Skip to content

ext/zip: add ZipArchive::openString method#21205

Open
tstarling wants to merge 6 commits intophp:masterfrom
tstarling:add-ziparchive-openbuffer
Open

ext/zip: add ZipArchive::openString method#21205
tstarling wants to merge 6 commits intophp:masterfrom
tstarling:add-ziparchive-openbuffer

Conversation

@tstarling
Copy link
Contributor

  • Remove ifdef guards around ZIP_RDONLY, not needed since a979e9f
  • Add ZipArchive::openString().
  • For consistency with ::open(), return int|bool, don't throw an exception on error. Provide error information via existing properties and accessors.
  • Share buffer handling with ZipArchive::addFromString().
  • If there is an error from zip_close() during a call to ZipArchive::open(), emit a warning but proceed to open the archive, don't return early. Add test.
  • When buffers are saved by ZipArchive::addFromString(), release them in ZipArchive::close() and ::open(), don't accumulate buffers until the free_obj handler is called.
  • Factor out buffer handling and reuse it in ZipArchive::openString()

Co-authored-by: @shyim
Forked from #14078

tstarling and others added 5 commits February 11, 2026 13:31
ZIP_RDONLY was introduced in libzip 1.0.0 which is required since
a979e9f
Signed-off-by: Soner Sayakci <s.sayakci@shopware.com>
Fixes to php#14078:

* Rename ZipArchive::openBuffer() to ::openString().
* For consistency with ::open(), return int|bool, don't throw an
  exception on error. Provide error information via existing properties
  and accessors.
* Fix memory leak when ::openString() is called but ::close() is not
  called. Add test.
* Fix memory leak when a call to ::open() is followed by a call to
  ::openString(). Add test.
* Let libzip own the source, don't call zip_source_keep().
* Share buffer handling with ZipArchive::addFromString().

Elsewhere:

* If there is an error from zip_close() during a call to
  ZipArchive::open(), emit a warning but proceed to open the archive,
  don't return early. Add test.
* When buffers are saved by ZipArchive::addFromString(), release them
  in ZipArchive::close() and ::open(), don't accumulate buffers until
  the free_obj handler is called.
* Factor out buffer handling and reuse it in ZipArchive::openString()
/** @tentative-return-type */
public function open(string $filename, int $flags = 0): bool|int {}

public function openString(string $data): bool|int {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like the return is actually true|int and it is impossible to return false

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

php_zipobj_close(ze_obj);

/* open for write without option to empty the archive */
#ifdef ZIP_RDONLY
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the ZIP_RDONLY changes appear unrelated - if you restore #21195 I'm happy to review that, but ideally the addition here of openString() should not include other refactoring/changes that are unneeded

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, restored. It's not unrelated, it's needed because @shyim's patch was unconditionally using ZIP_RDONLY, which would have been an error if the guards were still needed. I would have submitted it separately anyway, except that it's a merge conflict, since both change the hash of php_zip.stub.php.

@iluuu1994
Copy link
Member

Just a heads-up: ext/zip doesn't currently have any active primary maintainers. I'm not sure who would be most qualified to review this. Maybe @devnexen or @ndossche? (Though note that @ndossche is a volunteer and busy with uni).

@tstarling
Copy link
Contributor Author

Just a heads-up: ext/zip doesn't currently have any active primary maintainers. I'm not sure who would be most qualified to review this. Maybe @devnexen or @ndossche? (Though note that @ndossche is a volunteer and busy with uni).

@ndossche is definitely the most qualified and it would be great to have his review. My work here carries on from his ZipArchive::addFromString() commit in November.

Regarding this commit and future directions: the read-only restriction is somewhat arbitrary -- we could provide an interface allowing a zip archive to be modified in memory, although I'm not sure exactly what that would look like. Maybe there would be a getter for the modified string. Then openString() could take a $flags argument, like open(). If we want to do that, $flags should be introduced here, since ZipArchive::open() defaults to read/write mode, and it would make sense for openString to do that too.

@tstarling
Copy link
Contributor Author

Since zip_close() does the writing, there's no point providing an accessor for the updated zip archive string before that is called. So maybe we could have ZipArchive::closeToString(), which closes the archive and returns it as a string.

We could then have a default for the first parameter of ZipArchive::openString to open an empty archive in read/write mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants