Skip to content

Commit

Permalink
ext/zip: add ZipArchive::openBuffer method
Browse files Browse the repository at this point in the history
Signed-off-by: Soner Sayakci <s.sayakci@shopware.com>
  • Loading branch information
shyim committed Apr 29, 2024
1 parent 782af7a commit 023e619
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 6 deletions.
61 changes: 56 additions & 5 deletions ext/zip/php_zip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,47 @@ PHP_METHOD(ZipArchive, open)
}
/* }}} */

/* {{{ Create new read-only zip using given buffer */
PHP_METHOD(ZipArchive, openBuffer)
{
struct zip *intern;
zend_string *buffer;
zval *self = ZEND_THIS;
ze_zip_object *ze_obj;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &buffer) == FAILURE) {
RETURN_THROWS();
}

zip_error_t err;
zip_error_init(&err);

zip_source_t * zip_source = zip_source_buffer_create(ZSTR_VAL(buffer), ZSTR_LEN(buffer), 0, &err);

if (!zip_source) {
zend_throw_error(NULL, "Cannot open zip: %s", zip_error_strerror(&err));
zip_error_fini(&err);
RETURN_THROWS();
}

ze_obj = Z_ZIP_P(self);

intern = zip_open_from_source(zip_source, ZIP_RDONLY, &err);
if (!intern) {
zip_source_free(zip_source);
zend_throw_error(NULL, "Cannot open zip: %s", zip_error_strerror(&err));
zip_error_fini(&err);
RETURN_THROWS();
}

zip_source_keep(zip_source);
zip_error_fini(&err);

ze_obj->za = intern;
ze_obj->source = zip_source;
}
/* }}} */

/* {{{ Set the password for the active archive */
PHP_METHOD(ZipArchive, setPassword)
{
Expand Down Expand Up @@ -1582,12 +1623,22 @@ PHP_METHOD(ZipArchive, close)
ze_obj->err_sys = 0;
}

/* clear cache as empty zip are not created but deleted */
php_clear_stat_cache(1, ze_obj->filename, ze_obj->filename_len);
// if we have a filename, we need to free it
if (ze_obj->filename) {
/* clear cache as empty zip are not created but deleted */
php_clear_stat_cache(1, ze_obj->filename, ze_obj->filename_len);

efree(ze_obj->filename);
ze_obj->filename = NULL;
ze_obj->filename_len = 0;
}

if (ze_obj->source) {
zip_source_close(ze_obj->source);
zip_source_free(ze_obj->source);
ze_obj->source = NULL;
}

efree(ze_obj->filename);
ze_obj->filename = NULL;
ze_obj->filename_len = 0;
ze_obj->za = NULL;

if (!err) {
Expand Down
1 change: 1 addition & 0 deletions ext/zip/php_zip.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ typedef struct _ze_zip_read_rsrc {
/* Extends zend object */
typedef struct _ze_zip_object {
struct zip *za;
zip_source_t *source;
char **buffers;
HashTable *prop_handler;
char *filename;
Expand Down
3 changes: 3 additions & 0 deletions ext/zip/php_zip.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,9 @@ class ZipArchive implements Countable
/** @tentative-return-type */
public function open(string $filename, int $flags = 0): bool|int {}

/** @tentative-return-type */
public function openBuffer(string $data): void {}

/**
* @tentative-return-type
*/
Expand Down
8 changes: 7 additions & 1 deletion ext/zip/php_zip_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions ext/zip/tests/ziparchive_openbuffer.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--TEST--
ZipArchive::openBuffer() method
--EXTENSIONS--
zip
--FILE--
<?php
$zip = new ZipArchive();
$zip->openBuffer(file_get_contents(__DIR__."/test_procedural.zip"));

for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
echo $stat['name'] . "\n";
}

// Zip is read-only, not allowed
var_dump($zip->addFromString("foobar/baz", "baz"));
var_dump($zip->addEmptyDir("blub"));

var_dump($zip->close());
?>
--EXPECTF--
foo
bar
foobar/
foobar/baz
bool(false)
bool(false)
bool(true)

0 comments on commit 023e619

Please sign in to comment.