diff options
author | Dmitry Stogov <dmitry@zend.com> | 2014-05-08 18:30:07 +0400 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2014-05-08 18:30:07 +0400 |
commit | df5ad846c6c789a319bed176d5ead14a0a2ff264 (patch) | |
tree | 9c705a5fba168e74e5732b4c435e05afbca467f1 /ext/phar/zip.c | |
parent | ebaee948d9b565b6af5b76aec2edf21ddce1de51 (diff) | |
download | php-git-df5ad846c6c789a319bed176d5ead14a0a2ff264.tar.gz |
Support for ext/phar (incomplete)
Diffstat (limited to 'ext/phar/zip.c')
-rw-r--r-- | ext/phar/zip.c | 169 |
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); } |