summaryrefslogtreecommitdiff
path: root/ext/phar/zip.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-05-08 18:30:07 +0400
committerDmitry Stogov <dmitry@zend.com>2014-05-08 18:30:07 +0400
commitdf5ad846c6c789a319bed176d5ead14a0a2ff264 (patch)
tree9c705a5fba168e74e5732b4c435e05afbca467f1 /ext/phar/zip.c
parentebaee948d9b565b6af5b76aec2edf21ddce1de51 (diff)
downloadphp-git-df5ad846c6c789a319bed176d5ead14a0a2ff264.tar.gz
Support for ext/phar (incomplete)
Diffstat (limited to 'ext/phar/zip.c')
-rw-r--r--ext/phar/zip.c169
1 files changed, 102 insertions, 67 deletions
diff --git a/ext/phar/zip.c b/ext/phar/zip.c
index 2fc692c33e..bbd7126d8a 100644
--- a/ext/phar/zip.c
+++ b/ext/phar/zip.c
@@ -241,18 +241,10 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
mydata->metadata_len = 0;
/* if not valid serialized data, it is a regular string */
- if (entry.is_persistent) {
- ALLOC_PERMANENT_ZVAL(mydata->metadata);
- } else {
- ALLOC_ZVAL(mydata->metadata);
- }
-
- INIT_ZVAL(*mydata->metadata);
- metadata = pestrndup(metadata, PHAR_GET_16(locator.comment_len), mydata->is_persistent);
- ZVAL_STRINGL(mydata->metadata, metadata, PHAR_GET_16(locator.comment_len), 0);
+ ZVAL_STR(&mydata->metadata, STR_INIT(metadata, PHAR_GET_16(locator.comment_len), mydata->is_persistent));
}
} else {
- mydata->metadata = NULL;
+ ZVAL_UNDEF(&mydata->metadata);
}
goto foundit;
@@ -307,9 +299,7 @@ foundit:
zend_hash_destroy(&mydata->virtual_dirs); \
mydata->virtual_dirs.arHash = 0; \
php_stream_close(fp); \
- if (mydata->metadata) { \
- zval_dtor(mydata->metadata); \
- } \
+ zval_dtor(&mydata->metadata); \
if (mydata->signature) { \
efree(mydata->signature); \
} \
@@ -331,9 +321,7 @@ foundit:
zend_hash_destroy(&mydata->virtual_dirs); \
mydata->virtual_dirs.arHash = 0; \
php_stream_close(fp); \
- if (mydata->metadata) { \
- zval_dtor(mydata->metadata); \
- } \
+ zval_dtor(&mydata->metadata); \
if (mydata->signature) { \
efree(mydata->signature); \
} \
@@ -541,17 +529,10 @@ foundit:
entry.metadata_len = 0;
/* if not valid serialized data, it is a regular string */
- if (entry.is_persistent) {
- ALLOC_PERMANENT_ZVAL(entry.metadata);
- } else {
- ALLOC_ZVAL(entry.metadata);
- }
-
- INIT_ZVAL(*entry.metadata);
- ZVAL_STRINGL(entry.metadata, pestrndup(buf, PHAR_GET_16(zipentry.comment_len), entry.is_persistent), PHAR_GET_16(zipentry.comment_len), 0);
+ ZVAL_STR(&entry.metadata, STR_INIT(buf, PHAR_GET_16(zipentry.comment_len), entry.is_persistent));
}
} else {
- entry.metadata = NULL;
+ ZVAL_UNDEF(&entry.metadata);
}
if (!actual_alias && entry.filename_len == sizeof(".phar/alias.txt")-1 && !strncmp(entry.filename, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) {
@@ -588,7 +569,6 @@ foundit:
/* the above lines should be for php < 5.2.6 after 5.3 filters are fixed */
mydata->alias_len = entry.uncompressed_filesize;
-
if (entry.flags & PHAR_ENT_COMPRESSED_GZ) {
filter = php_stream_filter_create("zlib.inflate", NULL, php_stream_is_persistent(fp) TSRMLS_CC);
@@ -599,7 +579,21 @@ foundit:
php_stream_filter_append(&fp->readfilters, filter);
- if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
+ // TODO: refactor to avoid reallocation ???
+//??? entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)
+ {
+ zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
+ if (str) {
+ entry.uncompressed_filesize = str->len;
+ actual_alias = estrndup(str->val, str->len);
+ STR_RELEASE(str);
+ } else {
+ actual_alias = NULL;
+ entry.uncompressed_filesize = 0;
+ }
+ }
+
+ if (!entry.uncompressed_filesize || !actual_alias) {
pefree(entry.filename, entry.is_persistent);
PHAR_ZIP_FAIL("unable to read in alias, truncated");
}
@@ -617,7 +611,21 @@ foundit:
php_stream_filter_append(&fp->readfilters, filter);
- if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
+ // TODO: refactor to avoid reallocation ???
+//??? entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)
+ {
+ zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
+ if (str) {
+ entry.uncompressed_filesize = str->len;
+ actual_alias = estrndup(str->val, str->len);
+ STR_RELEASE(str);
+ } else {
+ actual_alias = NULL;
+ entry.uncompressed_filesize = 0;
+ }
+ }
+
+ if (!entry.uncompressed_filesize || !actual_alias) {
pefree(entry.filename, entry.is_persistent);
PHAR_ZIP_FAIL("unable to read in alias, truncated");
}
@@ -625,7 +633,21 @@ foundit:
php_stream_filter_flush(filter, 1);
php_stream_filter_remove(filter, 1 TSRMLS_CC);
} else {
- if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
+ // TODO: refactor to avoid reallocation ???
+//??? entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)
+ {
+ zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
+ if (str) {
+ entry.uncompressed_filesize = str->len;
+ actual_alias = estrndup(str->val, str->len);
+ STR_RELEASE(str);
+ } else {
+ actual_alias = NULL;
+ entry.uncompressed_filesize = 0;
+ }
+ }
+
+ if (!entry.uncompressed_filesize || !actual_alias) {
pefree(entry.filename, entry.is_persistent);
PHAR_ZIP_FAIL("unable to read in alias, truncated");
}
@@ -636,40 +658,40 @@ foundit:
}
phar_set_inode(&entry TSRMLS_CC);
- zend_hash_add(&mydata->manifest, entry.filename, entry.filename_len, (void *)&entry,sizeof(phar_entry_info), NULL);
+ zend_hash_str_add_mem(&mydata->manifest, entry.filename, entry.filename_len, (void *)&entry, sizeof(phar_entry_info));
}
mydata->fp = fp;
- if (zend_hash_exists(&(mydata->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
+ if (zend_hash_str_exists(&(mydata->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
mydata->is_data = 0;
} else {
mydata->is_data = 1;
}
- zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+ zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, mydata);
if (actual_alias) {
- phar_archive_data **fd_ptr;
+ phar_archive_data *fd_ptr;
if (!phar_validate_alias(actual_alias, mydata->alias_len)) {
if (error) {
spprintf(error, 4096, "phar error: invalid alias \"%s\" in zip-based phar \"%s\"", actual_alias, fname);
}
efree(actual_alias);
- zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+ zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
return FAILURE;
}
mydata->is_temporary_alias = 0;
- if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void **)&fd_ptr)) {
- if (SUCCESS != phar_free_alias(*fd_ptr, actual_alias, mydata->alias_len TSRMLS_CC)) {
+ if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len))) {
+ if (SUCCESS != phar_free_alias(fd_ptr, actual_alias, mydata->alias_len TSRMLS_CC)) {
if (error) {
spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with implicit alias, alias is already in use", fname);
}
efree(actual_alias);
- zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+ zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
return FAILURE;
}
}
@@ -680,22 +702,22 @@ foundit:
efree(actual_alias);
}
- zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+ zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, mydata);
} else {
- phar_archive_data **fd_ptr;
+ phar_archive_data *fd_ptr;
if (alias_len) {
- if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void **)&fd_ptr)) {
- if (SUCCESS != phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
+ if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len))) {
+ if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len TSRMLS_CC)) {
if (error) {
spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with explicit alias, alias is already in use", fname);
}
- zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+ zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
return FAILURE;
}
}
- zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+ zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, mydata);
mydata->alias = pestrndup(alias, alias_len, mydata->is_persistent);
mydata->alias_len = alias_len;
} else {
@@ -761,7 +783,7 @@ struct _phar_zip_pass {
char **error;
};
/* perform final modification of zip contents for each file in the manifest before saving */
-static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */
+static int phar_zip_changed_apply(zval *zv, void *arg TSRMLS_DC) /* {{{ */
{
phar_entry_info *entry;
phar_zip_file_header local;
@@ -771,7 +793,7 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */
php_uint32 newcrc32;
off_t offset;
int not_really_modified = 0;
- entry = (phar_entry_info *)data;
+ entry = (phar_entry_info *)Z_PTR_P(zv);
p = (struct _phar_zip_pass*) arg;
if (entry->is_mounted) {
@@ -939,18 +961,17 @@ not_compressed:
PHAR_SET_32(local.crc32, entry->crc32);
continue_dir:
/* set file metadata */
- if (entry->metadata) {
+ if (Z_TYPE(entry->metadata) != IS_UNDEF) {
php_serialize_data_t metadata_hash;
- if (entry->metadata_str.c) {
+ if (entry->metadata_str.s) {
smart_str_free(&entry->metadata_str);
}
- entry->metadata_str.c = 0;
- entry->metadata_str.len = 0;
+ entry->metadata_str.s = NULL;
PHP_VAR_SERIALIZE_INIT(metadata_hash);
php_var_serialize(&entry->metadata_str, &entry->metadata, &metadata_hash TSRMLS_CC);
PHP_VAR_SERIALIZE_DESTROY(metadata_hash);
- PHAR_SET_16(central.comment_len, entry->metadata_str.len);
+ PHAR_SET_16(central.comment_len, entry->metadata_str.s->len);
}
entry->header_offset = php_stream_tell(p->filefp);
@@ -1060,8 +1081,8 @@ continue_dir:
entry->offset = entry->offset_abs = offset;
entry->fp_type = PHAR_FP;
- if (entry->metadata_str.c) {
- if (entry->metadata_str.len != php_stream_write(p->centralfp, entry->metadata_str.c, entry->metadata_str.len)) {
+ if (entry->metadata_str.s) {
+ if (entry->metadata_str.s->len != php_stream_write(p->centralfp, entry->metadata_str.s->val, entry->metadata_str.s->len)) {
spprintf(p->error, 0, "unable to write metadata as file comment for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
smart_str_free(&entry->metadata_str);
return ZEND_HASH_APPLY_STOP;
@@ -1097,8 +1118,8 @@ static int phar_zip_applysignature(phar_archive_data *phar, struct _phar_zip_pas
tell = php_stream_tell(pass->centralfp);
php_stream_seek(pass->centralfp, 0, SEEK_SET);
php_stream_copy_to_stream_ex(pass->centralfp, newfile, tell, NULL);
- if (metadata->c) {
- php_stream_write(newfile, metadata->c, metadata->len);
+ if (metadata->s) {
+ php_stream_write(newfile, metadata->s->val, metadata->s->len);
}
if (FAILURE == phar_create_signature(phar, newfile, &signature, &signature_length, pass->error TSRMLS_CC)) {
@@ -1206,14 +1227,14 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
entry.filename = estrndup(".phar/alias.txt", sizeof(".phar/alias.txt")-1);
entry.filename_len = sizeof(".phar/alias.txt")-1;
- if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+ if (NULL == zend_hash_str_update_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
if (error) {
spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname);
}
return EOF;
}
} else {
- zend_hash_del(&phar->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
+ zend_hash_str_del(&phar->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
}
/* register alias */
@@ -1227,7 +1248,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
if (user_stub && !defaultstub) {
if (len < 0) {
/* resource passed in */
- if (!(php_stream_from_zval_no_verify(stubfile, (zval **)user_stub))) {
+ if (!(php_stream_from_zval_no_verify(stubfile, (zval *)user_stub))) {
if (error) {
spprintf(error, 0, "unable to access resource to copy stub to new zip-based phar \"%s\"", phar->fname);
}
@@ -1242,7 +1263,21 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
user_stub = 0;
- if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) {
+ // TODO: refactor to avoid reallocation ???
+//??? len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)
+ {
+ zend_string *str = php_stream_copy_to_mem(stubfile, len, 0);
+ if (str) {
+ len = str->len;
+ user_stub = estrndup(str->val, str->len);
+ STR_RELEASE(str);
+ } else {
+ user_stub = NULL;
+ len = 0;
+ }
+ }
+
+ if (!len || !user_stub) {
if (error) {
spprintf(error, 0, "unable to read resource to copy stub to new zip-based phar \"%s\"", phar->fname);
}
@@ -1290,7 +1325,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
entry.filename = estrndup(".phar/stub.php", sizeof(".phar/stub.php")-1);
entry.filename_len = sizeof(".phar/stub.php")-1;
- if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+ if (NULL == zend_hash_str_update_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
if (free_user_stub) {
efree(user_stub);
}
@@ -1323,8 +1358,8 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
entry.filename_len = sizeof(".phar/stub.php")-1;
if (!defaultstub) {
- if (!zend_hash_exists(&phar->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
- if (SUCCESS != zend_hash_add(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+ if (!zend_hash_str_exists(&phar->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
+ if (NULL == zend_hash_str_add_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
php_stream_close(entry.fp);
efree(entry.filename);
if (error) {
@@ -1337,7 +1372,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
efree(entry.filename);
}
} else {
- if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+ if (NULL == zend_hash_str_update_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
php_stream_close(entry.fp);
efree(entry.filename);
if (error) {
@@ -1394,7 +1429,7 @@ fperror:
}
zend_hash_apply_with_argument(&phar->manifest, phar_zip_changed_apply, (void *) &pass TSRMLS_CC);
- if (phar->metadata) {
+ if (Z_TYPE(phar->metadata) != IS_UNDEF) {
/* set phar metadata */
PHP_VAR_SERIALIZE_INIT(metadata_hash);
php_var_serialize(&main_metadata_str, &phar->metadata, &metadata_hash TSRMLS_CC);
@@ -1408,7 +1443,7 @@ fperror:
temperror:
php_stream_close(pass.centralfp);
nocentralerror:
- if (phar->metadata) {
+ if (Z_TYPE(phar->metadata) != IS_UNDEF) {
smart_str_free(&main_metadata_str);
}
php_stream_close(pass.filefp);
@@ -1442,9 +1477,9 @@ nocentralerror:
php_stream_close(pass.centralfp);
- if (phar->metadata) {
+ if (Z_TYPE(phar->metadata) != IS_UNDEF) {
/* set phar metadata */
- PHAR_SET_16(eocd.comment_len, main_metadata_str.len);
+ PHAR_SET_16(eocd.comment_len, main_metadata_str.s->len);
if (sizeof(eocd) != php_stream_write(pass.filefp, (char *)&eocd, sizeof(eocd))) {
if (error) {
@@ -1453,7 +1488,7 @@ nocentralerror:
goto nocentralerror;
}
- if (main_metadata_str.len != php_stream_write(pass.filefp, main_metadata_str.c, main_metadata_str.len)) {
+ if (main_metadata_str.s->len != php_stream_write(pass.filefp, main_metadata_str.s->val, main_metadata_str.s->len)) {
if (error) {
spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write metadata to zip comment", phar->fname);
}