diff options
Diffstat (limited to 'ext/phar')
-rw-r--r-- | ext/phar/config.m4 | 8 | ||||
-rw-r--r-- | ext/phar/dirstream.c | 74 | ||||
-rw-r--r-- | ext/phar/func_interceptors.c | 6 | ||||
-rw-r--r-- | ext/phar/phar.c | 38 | ||||
-rwxr-xr-x | ext/phar/phar/pharcommand.inc | 6 | ||||
-rwxr-xr-x | ext/phar/phar_internal.h | 64 | ||||
-rwxr-xr-x | ext/phar/phar_object.c | 252 | ||||
-rw-r--r-- | ext/phar/pharzip.h | 33 | ||||
-rw-r--r-- | ext/phar/stream.c | 51 | ||||
-rw-r--r-- | ext/phar/tar.c | 22 | ||||
-rw-r--r-- | ext/phar/tar.h | 9 | ||||
-rw-r--r-- | ext/phar/tests/files/blog.phar | bin | 496 -> 468 bytes | |||
-rw-r--r-- | ext/phar/tests/files/blog.phar.inc | 4 | ||||
-rw-r--r-- | ext/phar/tests/phar_get_supported_signatures_002a.phpt | 1 | ||||
-rwxr-xr-x | ext/phar/tests/phar_oo_005.phpt | 3 | ||||
-rw-r--r-- | ext/phar/tests/phar_setsignaturealgo2.phpt | 4 | ||||
-rw-r--r-- | ext/phar/tests/stat.phpt | 14 | ||||
-rw-r--r-- | ext/phar/tests/tar/phar_setsignaturealgo2.phpt | 6 | ||||
-rw-r--r-- | ext/phar/tests/tar/rmdir.phpt | 3 | ||||
-rw-r--r-- | ext/phar/tests/test_signaturealgos.phpt | 1 | ||||
-rw-r--r-- | ext/phar/tests/zip/bzip2.phpt | 3 | ||||
-rw-r--r-- | ext/phar/tests/zip/rmdir.phpt | 3 | ||||
-rw-r--r-- | ext/phar/util.c | 63 | ||||
-rw-r--r-- | ext/phar/zip.c | 88 |
24 files changed, 251 insertions, 505 deletions
diff --git a/ext/phar/config.m4 b/ext/phar/config.m4 index 2ac7f3dd81..8fba62ff9a 100644 --- a/ext/phar/config.m4 +++ b/ext/phar/config.m4 @@ -7,13 +7,6 @@ PHP_ARG_ENABLE(phar, for phar archive support, if test "$PHP_PHAR" != "no"; then PHP_NEW_EXTENSION(phar, util.c tar.c zip.c stream.c func_interceptors.c dirstream.c phar.c phar_object.c phar_path_check.c, $ext_shared) AC_MSG_CHECKING([for phar openssl support]) - if test "$PHP_HASH_SHARED" != "yes"; then - if test "$PHP_HASH" != "no"; then - AC_DEFINE(PHAR_HASH_OK,1,[ ]) - fi - else - AC_MSG_WARN([Phar: sha256/sha512 signature support disabled if ext/hash is built shared]) - fi if test "$PHP_OPENSSL_SHARED" = "yes"; then AC_MSG_RESULT([no (shared openssl)]) else @@ -24,7 +17,6 @@ if test "$PHP_PHAR" != "no"; then AC_MSG_RESULT([no]) fi fi - PHP_ADD_EXTENSION_DEP(phar, hash, true) PHP_ADD_EXTENSION_DEP(phar, spl, true) PHP_ADD_MAKEFILE_FRAGMENT fi diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index c0e4b18e09..2e1754d6c8 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -22,7 +22,8 @@ #include "dirstream.h" BEGIN_EXTERN_C() -void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_statbuf *ssb, zend_bool is_dir TSRMLS_DC); +void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_statbuf *ssb, + zend_bool is_dir, char *alias, int alias_len TSRMLS_DC); END_EXTERN_C() php_stream_ops phar_dir_ops = { @@ -507,6 +508,12 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, in return 0; } + if (phar->is_persistent && FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", unable to make cached phar writeable", resource->path+1, resource->host); + php_url_free(resource); + return 0; + } + memset((void *) &entry, 0, sizeof(phar_entry_info)); /* strip leading "/" */ @@ -625,43 +632,50 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_ return 0; } - if (!entry->is_deleted) { - for (zend_hash_internal_pointer_reset(&phar->manifest); + /* now for the easy part */ + if (phar->is_persistent && FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot remove directory \"%s\" in phar \"%s\", unable to make cached phar writeable", resource->path+1, resource->host); + php_url_free(resource); + return 0; + } + + for (zend_hash_internal_pointer_reset(&phar->manifest); HASH_KEY_NON_EXISTANT != zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL); zend_hash_move_forward(&phar->manifest)) { - PHAR_STR(key, str_key); + PHAR_STR(key, str_key); - if (key_len > path_len && - memcmp(str_key, resource->path+1, path_len) == 0 && - IS_SLASH(str_key[path_len])) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); - if (entry->is_temp_dir) { - efree(entry->filename); - efree(entry); - } - php_url_free(resource); - return 0; + if (!entry->is_deleted && + key_len > path_len && + memcmp(str_key, resource->path+1, path_len) == 0 && + IS_SLASH(str_key[path_len])) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); + if (entry->is_temp_dir) { + efree(entry->filename); + efree(entry); } + php_url_free(resource); + return 0; } + } - for (zend_hash_internal_pointer_reset(&phar->virtual_dirs); - HASH_KEY_NON_EXISTANT != zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL); - zend_hash_move_forward(&phar->virtual_dirs)) { - - PHAR_STR(key, str_key); - - if (key_len > path_len && - memcmp(str_key, resource->path+1, path_len) == 0 && - IS_SLASH(str_key[path_len])) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); - if (entry->is_temp_dir) { - efree(entry->filename); - efree(entry); - } - php_url_free(resource); - return 0; + for (zend_hash_internal_pointer_reset(&phar->virtual_dirs); + HASH_KEY_NON_EXISTANT != zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL); + zend_hash_move_forward(&phar->virtual_dirs)) { + + PHAR_STR(key, str_key); + + if (!entry->is_deleted && + key_len > path_len && + memcmp(str_key, resource->path+1, path_len) == 0 && + IS_SLASH(str_key[path_len])) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); + if (entry->is_temp_dir) { + efree(entry->filename); + efree(entry); } + php_url_free(resource); + return 0; } } diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index d2a6bb0743..cf08cfd47c 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -438,7 +438,7 @@ skip_phar: /* {{{ php_stat */ -static void phar_fancy_stat(struct stat *stat_sb, int type, zval *return_value TSRMLS_DC) +void phar_fancy_stat(struct stat *stat_sb, int type, zval *return_value TSRMLS_DC) { zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev, *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks; @@ -607,7 +607,7 @@ static void phar_fancy_stat(struct stat *stat_sb, int type, zval *return_value T } /* }}} */ -static void phar_file_stat(const char *filename, php_stat_len filename_length, int type, void (*orig_stat_func)(INTERNAL_FUNCTION_PARAMETERS), INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ +void phar_file_stat(const char *filename, php_stat_len filename_length, int type, void (*orig_stat_func)(INTERNAL_FUNCTION_PARAMETERS), INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { if (!filename_length) { RETURN_FALSE; @@ -646,7 +646,6 @@ static void phar_file_stat(const char *filename, php_stat_len filename_length, i entry_len = (int) filename_length; if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) { efree(arch); - efree(entry); goto skip_phar; } splitted: @@ -686,7 +685,6 @@ splitted: int save_len; notfound: - efree(entry); save = PHAR_G(cwd); save_len = PHAR_G(cwd_len); /* this file is not in the current directory, use the original path */ diff --git a/ext/phar/phar.c b/ext/phar/phar.c index ff8b8b5433..7102f23da1 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -440,11 +440,6 @@ int phar_entry_delref(phar_entry_data *idata TSRMLS_DC) /* {{{ */ if (idata->fp && idata->fp != idata->phar->fp && idata->fp != idata->phar->ufp && idata->fp != idata->internal_file->fp) { php_stream_close(idata->fp); } - /* if phar_get_or_create_entry_data returns a sub-directory, we have to free it */ - if (idata->internal_file->is_temp_dir) { - destroy_phar_manifest_entry((void *)idata->internal_file); - efree(idata->internal_file); - } } phar_archive_delref(idata->phar TSRMLS_CC); @@ -637,7 +632,9 @@ int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSR zval_ptr_dtor(metadata); *metadata = (zval *) pemalloc(buf_len, 1); memcpy(*metadata, *buffer, buf_len); - *buffer += buf_len; + if (!zip_metadata_len) { + *buffer += buf_len; + } return SUCCESS; } } else { @@ -836,7 +833,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char efree(sig); } break; -#if PHAR_HASH_OK +#if HAVE_HASH_EXT case PHAR_SIG_SHA512: { unsigned char digest[64]; @@ -1034,7 +1031,9 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char /* check whether we have meta data, zero check works regardless of byte order */ if (mydata->is_persistent) { + char *mysave = buffer; PHAR_GET_32(buffer, mydata->metadata_len); + buffer = mysave; if (phar_parse_metadata(&buffer, &mydata->metadata, mydata->metadata_len TSRMLS_CC) == FAILURE) { MAPPHAR_FAIL("unable to read phar metadata in .phar file \"%s\""); } @@ -1114,9 +1113,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char } if (entry.is_persistent) { - PHAR_GET_32(buffer, entry.metadata_len); - if (!entry.metadata_len) buffer -= 4; - if (phar_parse_metadata(&buffer, &entry.metadata, entry.metadata_len TSRMLS_CC) == FAILURE) { + if (phar_parse_metadata(&buffer, &entry.metadata, 0 TSRMLS_CC) == FAILURE) { pefree(entry.filename, entry.is_persistent); MAPPHAR_FAIL("unable to read file metadata in .phar file \"%s\""); } @@ -1704,7 +1701,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a if (got > 512) { if (phar_is_tar(pos, fname)) { php_stream_rewind(fp); - return phar_parse_tarfile(fp, fname, fname_len, alias, alias_len, pphar, compression, error TSRMLS_CC); + return phar_parse_tarfile(fp, fname, fname_len, alias, alias_len, options, pphar, compression, error TSRMLS_CC); } } } @@ -2560,8 +2557,6 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, return EOF; } - zend_hash_clean(&phar->virtual_dirs); - if (phar->is_zip) { return phar_zip_flush(phar, user_stub, len, convert, error TSRMLS_CC); } @@ -2739,7 +2734,6 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, } /* after excluding deleted files, calculate manifest size in bytes and number of entries */ ++new_manifest_count; - phar_add_virtual_dirs(phar, entry->filename, entry->filename_len TSRMLS_CC); if (entry->is_dir) { /* we use this to calculate API version, 1.1.1 is used for phars with directories */ @@ -2775,7 +2769,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, } if (!phar_get_efp(entry, 0 TSRMLS_CC)) { /* re-open internal file pointer just-in-time */ - newentry = phar_open_jit(phar, entry, error TSRMLS_CC); + newentry = phar_open_jit(phar, entry, oldfile, error, 0 TSRMLS_CC); if (!newentry) { /* major problem re-opening, so we ignore this file and the error */ efree(*error); @@ -3109,7 +3103,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, } switch(phar->sig_flags) { -#ifndef PHAR_HASH_OK +#if !HAVE_HASH_EXT case PHAR_SIG_SHA512: case PHAR_SIG_SHA256: if (closeoldfile) { @@ -3277,7 +3271,7 @@ static long phar_stream_fteller_for_zend(void *handle TSRMLS_DC) /* {{{ */ zend_op_array *(*phar_orig_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC); #if PHP_VERSION_ID >= 50300 #define phar_orig_zend_open zend_stream_open_function -static char *phar_resolve_path(const char *filename, int filename_len TSRMLS_DC) +char *phar_resolve_path(const char *filename, int filename_len TSRMLS_DC) { return phar_find_in_include_path((char *) filename, filename_len, NULL TSRMLS_CC); } @@ -3292,9 +3286,6 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type int failed; phar_archive_data *phar; - if (!file_handle || !file_handle->filename) { - return phar_orig_compile_file(file_handle, type TSRMLS_CC); - } if (strstr(file_handle->filename, ".phar") && !strstr(file_handle->filename, "://")) { if (SUCCESS == phar_open_from_filename(file_handle->filename, strlen(file_handle->filename), NULL, 0, 0, &phar, NULL TSRMLS_CC)) { if (phar->is_zip || phar->is_tar) { @@ -3546,7 +3537,6 @@ void phar_request_initialize(TSRMLS_D) /* {{{ */ PHAR_GLOBALS->request_ends = 0; PHAR_GLOBALS->request_done = 0; zend_hash_init(&(PHAR_GLOBALS->phar_fname_map), 5, zend_get_hash_value, destroy_phar_data, 0); - zend_hash_init(&(PHAR_GLOBALS->phar_persist_map), 5, zend_get_hash_value, NULL, 0); zend_hash_init(&(PHAR_GLOBALS->phar_alias_map), 5, zend_get_hash_value, NULL, 0); if (PHAR_G(manifest_cached)) { @@ -3566,6 +3556,7 @@ void phar_request_initialize(TSRMLS_D) /* {{{ */ PHAR_G(cwd) = NULL; PHAR_G(cwd_len) = 0; PHAR_G(cwd_init) = 0; + phar_intercept_functions(TSRMLS_C); } } /* }}} */ @@ -3583,8 +3574,6 @@ PHP_RSHUTDOWN_FUNCTION(phar) /* {{{ */ PHAR_GLOBALS->phar_alias_map.arBuckets = NULL; zend_hash_destroy(&(PHAR_GLOBALS->phar_fname_map)); PHAR_GLOBALS->phar_fname_map.arBuckets = NULL; - zend_hash_destroy(&(PHAR_GLOBALS->phar_persist_map)); - PHAR_GLOBALS->phar_persist_map.arBuckets = NULL; PHAR_GLOBALS->phar_SERVER_mung_list = 0; if (PHAR_GLOBALS->cached_fp) { @@ -3671,9 +3660,6 @@ static zend_module_dep phar_deps[] = { ZEND_MOD_OPTIONAL("openssl") ZEND_MOD_OPTIONAL("zlib") ZEND_MOD_OPTIONAL("standard") -#if defined(HAVE_HASH) && !defined(COMPILE_DL_HASH) - ZEND_MOD_REQUIRED("hash") -#endif #if HAVE_SPL ZEND_MOD_REQUIRED("spl") #endif diff --git a/ext/phar/phar/pharcommand.inc b/ext/phar/phar/pharcommand.inc index cbca587e35..80b6f18d07 100755 --- a/ext/phar/phar/pharcommand.inc +++ b/ext/phar/phar/pharcommand.inc @@ -213,7 +213,7 @@ class PharCommand extends CLICommand $apiver = trim(substr($apiver, strlen('API Version'))); if ($apiver) { self::notice("Pear package PHP_Archive: API Version: $apiver.\n"); - $files = explode("\n", `pear list-files PHP_Archive`); + $files = split("\n", `pear list-files PHP_Archive`); $phpdir = `pear config-get php_dir 2>/dev/null`; $phpdir = trim($phpdir); self::notice("Pear package PHP_Archive: $phpdir.\n"); @@ -488,9 +488,7 @@ class PharCommand extends CLICommand if (isset($loader)) { $s = "<?php if (!class_exists('PHP_Archive')) {\n?>"; - if (is_file($loader)) { - $s .= file_get_contents($loader); - } + $s .= file_get_contents($loader); $s .= "<?php\n"; $s .= "}\n"; $s .= "if (!in_array('phar', stream_get_wrappers())) {\n"; diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index efe28671fa..38b1e8816e 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -66,7 +66,7 @@ #ifdef HAVE_STDINT_H #include <stdint.h> #endif -#ifdef PHAR_HASH_OK +#if HAVE_HASH_EXT #include "ext/hash/php_hash.h" #include "ext/hash/php_hash_sha.h" #endif @@ -150,9 +150,6 @@ typedef struct _phar_entry_fp phar_entry_fp; typedef struct _phar_archive_data phar_archive_data; ZEND_BEGIN_MODULE_GLOBALS(phar) - /* a list of phar_archive_data objects that reference a cached phar, so - that if copy-on-write is performed, we can swap them out for the new value */ - HashTable phar_persist_map; HashTable phar_fname_map; /* for cached phars, this is a per-process store of fp/ufp */ phar_entry_fp *cached_fp; @@ -273,31 +270,30 @@ typedef struct _phar_entry_info { php_stream *fp; php_stream *cfp; int fp_refcount; + int is_crc_checked:1; + int is_modified:1; + int is_deleted:1; + int is_dir:1; + /* this flag is used for mounted entries (external files mapped to location + inside a phar */ + int is_mounted:1; char *tmp; + /* used when iterating */ + int is_temp_dir:1; phar_archive_data *phar; smart_str metadata_str; + /* tar-based phar file stuff */ + int is_tar:1; char *link; /* symbolic link to another file */ char tar_type; + /* zip-based phar file stuff */ + int is_zip:1; + /* for cached phar entries */ + int is_persistent:1; /* position in the manifest */ uint manifest_pos; /* for stat */ unsigned short inode; - - unsigned int is_crc_checked:1; - unsigned int is_modified:1; - unsigned int is_deleted:1; - unsigned int is_dir:1; - /* this flag is used for mounted entries (external files mapped to location - inside a phar */ - unsigned int is_mounted:1; - /* used when iterating */ - unsigned int is_temp_dir:1; - /* tar-based phar file stuff */ - unsigned int is_tar:1; - /* zip-based phar file stuff */ - unsigned int is_zip:1; - /* for cached phar entries */ - unsigned int is_persistent:1; } phar_entry_info; /* information about a phar file (the archive itself) */ @@ -329,22 +325,22 @@ struct _phar_archive_data { char *signature; zval *metadata; int metadata_len; /* only used for cached manifests */ - uint phar_pos; /* if 1, then this alias was manually specified by the user and is not a permanent alias */ - unsigned int is_temporary_alias:1; - unsigned int is_modified:1; - unsigned int is_writeable:1; - unsigned int is_brandnew:1; + int is_temporary_alias:1; + int is_modified:1; + int is_writeable:1; + int is_brandnew:1; /* defer phar creation */ - unsigned int donotflush:1; + int donotflush:1; /* zip-based phar variables */ - unsigned int is_zip:1; + int is_zip:1; /* tar-based phar variables */ - unsigned int is_tar:1; + int is_tar:1; /* PharData variables */ - unsigned int is_data:1; + int is_data:1; /* for cached phar manifests */ - unsigned int is_persistent:1; + int is_persistent:1; + uint phar_pos; }; typedef struct _phar_entry_fp_info { @@ -558,7 +554,7 @@ static inline void phar_unixify_path_separators(char *path, int path_len) static inline int phar_validate_alias(const char *alias, int alias_len) /* {{{ */ { return !(memchr(alias, '/', alias_len) || memchr(alias, '\\', alias_len) || memchr(alias, ':', alias_len) || - memchr(alias, ';', alias_len) || memchr(alias, '\n', alias_len) || memchr(alias, '\r', alias_len)); + memchr(alias, ';', alias_len)); } /* }}} */ @@ -596,12 +592,12 @@ char *phar_create_default_stub(const char *index_php, const char *web_index, siz char *phar_decompress_filter(phar_entry_info * entry, int return_unknown); char *phar_compress_filter(phar_entry_info * entry, int return_unknown); -void phar_remove_virtual_dirs(phar_archive_data *phar, char *filename, int filename_len TSRMLS_DC); void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, int filename_len TSRMLS_DC); int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, char *path, int path_len TSRMLS_DC); char *phar_find_in_include_path(char *file, int file_len, phar_archive_data **pphar TSRMLS_DC); char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC); -phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC); +phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, php_stream *fp, + char **error, int for_write TSRMLS_DC); int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSRMLS_DC); void destroy_phar_manifest_entry(void *pDest); int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t position, int follow_links TSRMLS_DC); @@ -616,7 +612,7 @@ int phar_copy_on_write(phar_archive_data **pphar TSRMLS_DC); /* tar functions in tar.c */ int phar_is_tar(char *buf, char *fname); -int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar, php_uint32 compression, char **error TSRMLS_DC); +int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, php_uint32 compression, char **error TSRMLS_DC); int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC); int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defaultstub, char **error TSRMLS_DC); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index d3bc4de872..db82767e4f 100755 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -50,7 +50,7 @@ static int phar_file_type(HashTable *mimes, char *file, char **mime_type TSRMLS_ } /* }}} */ -static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char *basename, int request_uri_len TSRMLS_DC) /* {{{ */ +static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char *basename, char *request_uri, int request_uri_len TSRMLS_DC) /* {{{ */ { HashTable *_SERVER; zval **stuff; @@ -166,7 +166,7 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char } /* }}} */ -static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char *mime_type, int code, char *entry, int entry_len, char *arch, char *basename, char *ru, int ru_len TSRMLS_DC) /* {{{ */ +static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char *mime_type, int code, char *entry, int entry_len, char *arch, int arch_len, char *basename, char *ru, int ru_len TSRMLS_DC) /* {{{ */ { char *name = NULL, buf[8192], *cwd; zend_syntax_highlighter_ini syntax_highlighter_ini; @@ -216,7 +216,7 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char if (!fp) { char *error; - if (!phar_open_jit(phar, info, &error TSRMLS_CC)) { + if (!phar_open_jit(phar, info, phar_get_pharfp(phar TSRMLS_CC), &error, 0 TSRMLS_CC)) { if (error) { zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error); efree(error); @@ -242,7 +242,7 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char zend_bailout(); case PHAR_MIME_PHP: if (basename) { - phar_mung_server_vars(arch, entry, entry_len, basename, ru_len TSRMLS_CC); + phar_mung_server_vars(arch, entry, entry_len, basename, ru, ru_len TSRMLS_CC); efree(basename); } @@ -349,7 +349,7 @@ static void phar_do_404(phar_archive_data *phar, char *fname, int fname_len, cha info = phar_get_entry_info(phar, f404, f404_len, NULL, 1 TSRMLS_CC); if (info) { - phar_file_action(phar, info, "text/html", PHAR_MIME_PHP, f404, f404_len, fname, NULL, NULL, 0 TSRMLS_CC); + phar_file_action(phar, info, "text/html", PHAR_MIME_PHP, f404, f404_len, fname, fname_len, NULL, NULL, 0 TSRMLS_CC); return; } } @@ -603,16 +603,16 @@ PHP_METHOD(Phar, webPhar) || (strlen(sapi_module.name) == sizeof("cgi")-1 && !strncmp(sapi_module.name, "cgi", sizeof("cgi")-1))) { if (PG(http_globals)[TRACK_VARS_SERVER]) { - HashTable *_server = Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]); + HashTable *ht = Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]); zval **z_script_name, **z_path_info; - if (SUCCESS != zend_hash_find(_server, "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void**)&z_script_name) || + if (SUCCESS != zend_hash_find(ht, "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void**)&z_script_name) || IS_STRING != Z_TYPE_PP(z_script_name) || !strstr(Z_STRVAL_PP(z_script_name), basename)) { return; } - if (SUCCESS == zend_hash_find(_server, "PATH_INFO", sizeof("PATH_INFO"), (void**)&z_path_info) && + if (SUCCESS == zend_hash_find(ht, "PATH_INFO", sizeof("PATH_INFO"), (void**)&z_path_info) && IS_STRING == Z_TYPE_PP(z_path_info)) { entry_len = Z_STRLEN_PP(z_path_info); entry = estrndup(Z_STRVAL_PP(z_path_info), entry_len); @@ -875,7 +875,7 @@ PHP_METHOD(Phar, webPhar) if (!mime_type) { code = phar_file_type(&PHAR_G(mime_types), entry, &mime_type TSRMLS_CC); } - ret = phar_file_action(phar, info, mime_type, code, entry, entry_len, fname, pt, ru, ru_len TSRMLS_CC); + ret = phar_file_action(phar, info, mime_type, code, entry, entry_len, fname, fname_len, pt, ru, ru_len TSRMLS_CC); } /* }}} */ @@ -1165,10 +1165,10 @@ PHP_METHOD(Phar, __construct) return; } - save_fname = fname; if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, !is_data, 2 TSRMLS_CC)) { /* use arch (the basename for the archive) for fname instead of fname */ /* this allows support for RecursiveDirectoryIterator of subdirectories */ + save_fname = fname; #ifdef PHP_WIN32 phar_unixify_path_separators(arch, arch_len); #endif @@ -1178,6 +1178,7 @@ PHP_METHOD(Phar, __construct) } else { arch = estrndup(fname, fname_len); arch_len = fname_len; + save_fname = fname; fname = arch; phar_unixify_path_separators(arch, arch_len); #endif @@ -1185,7 +1186,7 @@ PHP_METHOD(Phar, __construct) if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, is_data, REPORT_ERRORS, &phar_data, &error TSRMLS_CC) == FAILURE) { - if (fname == arch && fname != save_fname) { + if (fname == arch) { efree(arch); fname = save_fname; } @@ -1254,9 +1255,6 @@ PHP_METHOD(Phar, __construct) if (!phar_data->is_persistent) { phar_obj->arc.archive->is_data = is_data; - } else if (!EG(exception)) { - /* register this guy so we can modify if necessary */ - zend_hash_add(&PHAR_GLOBALS->phar_persist_map, (const char *) phar_obj->arc.archive, sizeof(phar_obj->arc.archive), (void *) &phar_obj, sizeof(phar_archive_object **), NULL); } phar_obj->spl.info_class = phar_ce_entry; @@ -1274,7 +1272,7 @@ PHP_METHOD(Phar, getSupportedSignatures) add_next_index_stringl(return_value, "MD5", 3, 1); add_next_index_stringl(return_value, "SHA-1", 5, 1); -#ifdef PHAR_HASH_OK +#if HAVE_HASH_EXT add_next_index_stringl(return_value, "SHA-256", 7, 1); add_next_index_stringl(return_value, "SHA-512", 7, 1); #endif @@ -1381,19 +1379,6 @@ PHP_METHOD(Phar, unlinkArchive) return; \ } -/* {{{ proto void Phar::__destruct() - * if persistent, remove from the cache - */ -PHP_METHOD(Phar, __destruct) -{ - phar_archive_object *phar_obj = (phar_archive_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - - if (phar_obj->arc.archive && phar_obj->arc.archive->is_persistent) { - zend_hash_del(&PHAR_GLOBALS->phar_persist_map, (const char *) phar_obj->arc.archive, sizeof(phar_obj->arc.archive)); - } -} -/* }}} */ - struct _phar_t { phar_archive_object *p; zend_class_entry *c; @@ -1841,16 +1826,6 @@ PHP_METHOD(Phar, buildFromDirectory) pass.ret = return_value; pass.fp = php_stream_fopen_tmpfile(); - if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zval_ptr_dtor(&iteriter); - if (apply_reg) { - zval_ptr_dtor(®exiter); - } - php_stream_close(pass.fp); - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } - if (SUCCESS == spl_iterator_apply((apply_reg ? regexiter : iteriter), (spl_iterator_apply_func_t) phar_build, (void *) &pass TSRMLS_CC)) { zval_ptr_dtor(&iteriter); @@ -1868,9 +1843,6 @@ PHP_METHOD(Phar, buildFromDirectory) } else { zval_ptr_dtor(&iteriter); - if (apply_reg) { - zval_ptr_dtor(®exiter); - } php_stream_close(pass.fp); } } @@ -1906,11 +1878,6 @@ PHP_METHOD(Phar, buildFromIterator) RETURN_FALSE; } - if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } - array_init(return_value); pass.c = Z_OBJCE_P(obj); @@ -2596,10 +2563,6 @@ PHP_METHOD(Phar, delete) RETURN_FALSE; } - if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } if (zend_hash_exists(&phar_obj->arc.archive->manifest, fname, (uint) fname_len)) { if (SUCCESS == zend_hash_find(&phar_obj->arc.archive->manifest, fname, (uint) fname_len, (void**)&entry)) { if (entry->is_deleted) { @@ -2703,10 +2666,6 @@ PHP_METHOD(Phar, setAlias) RETURN_FALSE; } valid_alias: - if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } if (phar_obj->arc.archive->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len, (void**)&fd_ptr)) { zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len); readd = 1; @@ -2846,10 +2805,6 @@ PHP_METHOD(Phar, setStub) } else { len = -1; } - if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } phar_flush(phar_obj->arc.archive, (char *) &zstub, len, 0, &error TSRMLS_CC); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error); @@ -2861,10 +2816,6 @@ PHP_METHOD(Phar, setStub) "Cannot change stub, unable to read from input stream"); } } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &stub, &stub_len) == SUCCESS) { - if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } phar_flush(phar_obj->arc.archive, stub, stub_len, 0, &error TSRMLS_CC); if (error) { @@ -2940,10 +2891,6 @@ PHP_METHOD(Phar, setDefaultStub) created_stub = 1; } - if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } phar_flush(phar_obj->arc.archive, stub, stub_len, 1, &error TSRMLS_CC); if (created_stub) { @@ -2993,18 +2940,14 @@ PHP_METHOD(Phar, setSignatureAlgorithm) switch (algo) { case PHAR_SIG_SHA256: case PHAR_SIG_SHA512: -#ifndef PHAR_HASH_OK +#if !HAVE_HASH_EXT zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, - "SHA-256 and SHA-512 signatures are only supported if the hash extension is enabled and built non-shared"); + "SHA-256 and SHA-512 signatures are only supported if the hash extension is enabled"); return; #endif case PHAR_SIG_MD5: case PHAR_SIG_SHA1: case PHAR_SIG_OPENSSL: - if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } phar_obj->arc.archive->sig_flags = algo; phar_obj->arc.archive->is_modified = 1; PHAR_G(openssl_privatekey) = key; @@ -3305,10 +3248,6 @@ PHP_METHOD(Phar, compressFiles) return; } - if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } pharobj_set_compression(&phar_obj->arc.archive->manifest, flags TSRMLS_CC); phar_obj->arc.archive->is_modified = 1; phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC); @@ -3343,10 +3282,6 @@ PHP_METHOD(Phar, decompressFiles) if (phar_obj->arc.archive->is_tar) { RETURN_TRUE; } else { - if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } pharobj_set_compression(&phar_obj->arc.archive->manifest, PHAR_ENT_COMPRESSED_NONE TSRMLS_CC); } @@ -3418,15 +3353,6 @@ PHP_METHOD(Phar, copy) RETURN_FALSE; } - if (phar_obj->arc.archive->is_persistent) { - if (FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } - /* re-populate with copied-on-write entry */ - zend_hash_find(&phar_obj->arc.archive->manifest, oldfile, (uint) oldfile_len, (void**)&oldentry); - } - memcpy((void *) &newentry, oldentry, sizeof(phar_entry_info)); if (newentry.metadata) { @@ -3557,7 +3483,7 @@ PHP_METHOD(Phar, offsetGet) /* {{{ add a file within the phar archive from a string or resource */ -static void phar_add_file(phar_archive_data **pphar, char *filename, int filename_len, char *cont_str, int cont_len, zval *zresource TSRMLS_DC) +static void phar_add_file(phar_archive_data *phar, char *filename, int filename_len, char *cont_str, int cont_len, zval *zresource TSRMLS_DC) { char *error; long contents_len; @@ -3565,11 +3491,11 @@ static void phar_add_file(phar_archive_data **pphar, char *filename, int filenam php_stream *contents_file; if (filename_len >= sizeof(".phar")-1 && !memcmp(filename, ".phar", sizeof(".phar")-1)) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot create any files in magic \".phar\" directory", (*pphar)->fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot create any files in magic \".phar\" directory", phar->fname); return; } - if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, filename, filename_len, "w+b", 0, &error, 1 TSRMLS_CC))) { + if (!(data = phar_get_or_create_entry_data(phar->fname, phar->fname_len, filename, filename_len, "w+b", 0, &error, 1 TSRMLS_CC))) { if (error) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s does not exist and cannot be created: %s", filename, error); efree(error); @@ -3600,12 +3526,8 @@ static void phar_add_file(phar_archive_data **pphar, char *filename, int filenam data->internal_file->compressed_filesize = data->internal_file->uncompressed_filesize = contents_len; } - /* check for copy-on-write */ - if (pphar[0] != data->phar) { - *pphar = data->phar; - } phar_entry_delref(data TSRMLS_CC); - phar_flush(*pphar, 0, 0, 0, &error TSRMLS_CC); + phar_flush(phar, 0, 0, 0, &error TSRMLS_CC); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error); @@ -3617,12 +3539,12 @@ static void phar_add_file(phar_archive_data **pphar, char *filename, int filenam /* {{{ create a directory within the phar archive */ -static void phar_mkdir(phar_archive_data **pphar, char *dirname, int dirname_len TSRMLS_DC) +static void phar_mkdir(phar_archive_data *phar, char *dirname, int dirname_len TSRMLS_DC) { char *error; phar_entry_data *data; - if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, dirname, dirname_len, "w+b", 2, &error, 1 TSRMLS_CC))) { + if (!(data = phar_get_or_create_entry_data(phar->fname, phar->fname_len, dirname, dirname_len, "w+b", 2, &error, 1 TSRMLS_CC))) { if (error) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Directory %s does not exist and cannot be created: %s", dirname, error); efree(error); @@ -3636,12 +3558,8 @@ static void phar_mkdir(phar_archive_data **pphar, char *dirname, int dirname_len efree(error); } - /* check for copy on write */ - if (data->phar != *pphar) { - *pphar = data->phar; - } phar_entry_delref(data TSRMLS_CC); - phar_flush(*pphar, 0, 0, 0, &error TSRMLS_CC); + phar_flush(phar, 0, 0, 0, &error TSRMLS_CC); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error); @@ -3686,7 +3604,7 @@ PHP_METHOD(Phar, offsetSet) return; } - phar_add_file(&(phar_obj->arc.archive), fname, fname_len, cont_str, cont_len, zresource TSRMLS_CC); + phar_add_file(phar_obj->arc.archive, fname, fname_len, cont_str, cont_len, zresource TSRMLS_CC); } /* }}} */ @@ -3716,14 +3634,6 @@ PHP_METHOD(Phar, offsetUnset) return; } - if (phar_obj->arc.archive->is_persistent) { - if (FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } - /* re-populate entry after copy on write */ - zend_hash_find(&phar_obj->arc.archive->manifest, fname, (uint) fname_len, (void **)&entry); - } entry->is_modified = 0; entry->is_deleted = 1; /* we need to "flush" the stream to save the newly deleted file on disk */ @@ -3761,7 +3671,7 @@ PHP_METHOD(Phar, addEmptyDir) return; } - phar_mkdir(&phar_obj->arc.archive, dirname, dirname_len TSRMLS_CC); + phar_mkdir(phar_obj->arc.archive, dirname, dirname_len TSRMLS_CC); } /* }}} */ @@ -3805,7 +3715,7 @@ PHP_METHOD(Phar, addFile) MAKE_STD_ZVAL(zresource); php_stream_to_zval(resource, zresource); - phar_add_file(&(phar_obj->arc.archive), fname, fname_len, NULL, 0, zresource TSRMLS_CC); + phar_add_file(phar_obj->arc.archive, fname, fname_len, NULL, 0, zresource TSRMLS_CC); efree(zresource); php_stream_close(resource); } @@ -3825,7 +3735,7 @@ PHP_METHOD(Phar, addFromString) return; } - phar_add_file(&(phar_obj->arc.archive), localname, localname_len, cont_str, cont_len, NULL TSRMLS_CC); + phar_add_file(phar_obj->arc.archive, localname, localname_len, cont_str, cont_len, NULL TSRMLS_CC); } /* }}} */ @@ -3853,7 +3763,7 @@ PHP_METHOD(Phar, getStub) char *filter_name; if ((filter_name = phar_decompress_filter(stub, 0)) != NULL) { - filter = php_stream_filter_create(filter_name, NULL, php_stream_is_persistent(fp) TSRMLS_CC); + filter = php_stream_filter_create(phar_decompress_filter(stub, 0), NULL, php_stream_is_persistent(fp) TSRMLS_CC); } else { filter = NULL; } @@ -3939,15 +3849,6 @@ PHP_METHOD(Phar, getMetadata) PHAR_ARCHIVE_OBJECT(); if (phar_obj->arc.archive->metadata) { - if (phar_obj->arc.archive->is_persistent) { - zval *ret; - char *buf = estrndup((char *) phar_obj->arc.archive->metadata, phar_obj->arc.archive->metadata_len); - /* assume success, we would have failed before */ - phar_parse_metadata(&buf, &ret, phar_obj->arc.archive->metadata_len TSRMLS_CC); - efree(buf); - RETURN_ZVAL(ret, 0, 1); - return; - } RETURN_ZVAL(phar_obj->arc.archive->metadata, 1, 0); } } @@ -3972,10 +3873,6 @@ PHP_METHOD(Phar, setMetadata) return; } - if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname); - return; - } if (phar_obj->arc.archive->metadata) { zval_ptr_dtor(&phar_obj->arc.archive->metadata); phar_obj->arc.archive->metadata = NULL; @@ -4299,9 +4196,8 @@ PHP_METHOD(Phar, extractTo) return; } } else { - phar_archive_data *phar; + phar_archive_data *phar = phar_obj->arc.archive; all_files: - phar = phar_obj->arc.archive; /* Extract all files */ if (!zend_hash_num_elements(&(phar->manifest))) { RETURN_TRUE; @@ -4310,6 +4206,7 @@ all_files: for (zend_hash_internal_pointer_reset(&phar->manifest); zend_hash_has_more_elements(&phar->manifest) == SUCCESS; zend_hash_move_forward(&phar->manifest)) { + phar_entry_info *entry; if (zend_hash_get_current_data(&phar->manifest, (void **)&entry) == FAILURE) { continue; @@ -4525,16 +4422,6 @@ PHP_METHOD(PharFileInfo, chmod) return; } - if (entry_obj->ent.entry->is_persistent) { - phar_archive_data *phar = entry_obj->ent.entry->phar; - - if (FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar->fname); - return; - } - /* re-populate after copy-on-write */ - zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry); - } /* clear permissions */ entry_obj->ent.entry->flags &= ~PHAR_ENT_PERM_MASK; perms &= 0777; @@ -4583,15 +4470,6 @@ PHP_METHOD(PharFileInfo, getMetadata) PHAR_ENTRY_OBJECT(); if (entry_obj->ent.entry->metadata) { - if (entry_obj->ent.entry->is_persistent) { - zval *ret; - char *buf = estrndup((char *) entry_obj->ent.entry->metadata, entry_obj->ent.entry->metadata_len); - /* assume success, we would have failed before */ - phar_parse_metadata(&buf, &ret, entry_obj->ent.entry->metadata_len TSRMLS_CC); - efree(buf); - RETURN_ZVAL(ret, 0, 1); - return; - } RETURN_ZVAL(entry_obj->ent.entry->metadata, 1, 0); } } @@ -4622,16 +4500,6 @@ PHP_METHOD(PharFileInfo, setMetadata) return; } - if (entry_obj->ent.entry->is_persistent) { - phar_archive_data *phar = entry_obj->ent.entry->phar; - - if (FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar->fname); - return; - } - /* re-populate after copy-on-write */ - zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry); - } if (entry_obj->ent.entry->metadata) { zval_ptr_dtor(&entry_obj->ent.entry->metadata); entry_obj->ent.entry->metadata = NULL; @@ -4672,16 +4540,6 @@ PHP_METHOD(PharFileInfo, delMetadata) } if (entry_obj->ent.entry->metadata) { - if (entry_obj->ent.entry->is_persistent) { - phar_archive_data *phar = entry_obj->ent.entry->phar; - - if (FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar->fname); - return; - } - /* re-populate after copy-on-write */ - zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry); - } zval_ptr_dtor(&entry_obj->ent.entry->metadata); entry_obj->ent.entry->metadata = NULL; entry_obj->ent.entry->is_modified = 1; @@ -4786,16 +4644,6 @@ PHP_METHOD(PharFileInfo, compress) return; } - if (entry_obj->ent.entry->is_persistent) { - phar_archive_data *phar = entry_obj->ent.entry->phar; - - if (FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar->fname); - return; - } - /* re-populate after copy-on-write */ - zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry); - } switch (method) { case PHAR_ENT_COMPRESSED_GZ: if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_GZ) { @@ -4918,16 +4766,6 @@ PHP_METHOD(PharFileInfo, decompress) return; } - if (entry_obj->ent.entry->is_persistent) { - phar_archive_data *phar = entry_obj->ent.entry->phar; - - if (FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) { - zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar->fname); - return; - } - /* re-populate after copy-on-write */ - zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry); - } if (!entry_obj->ent.entry->fp) { if (FAILURE == phar_open_archive_fp(entry_obj->ent.entry->phar TSRMLS_CC)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot decompress entry \"%s\", phar error: Cannot open phar archive \"%s\" for reading", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname); @@ -4954,6 +4792,7 @@ PHP_METHOD(PharFileInfo, decompress) /* {{{ phar methods */ +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar___construct, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_ARG_INFO(0, flags) @@ -4961,30 +4800,36 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_phar___construct, 0, 0, 1) ZEND_ARG_INFO(0, fileformat) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_createDS, 0, 0, 0) ZEND_ARG_INFO(0, index) ZEND_ARG_INFO(0, webindex) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_loadPhar, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_ARG_INFO(0, alias) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mapPhar, 0, 0, 0) ZEND_ARG_INFO(0, alias) ZEND_ARG_INFO(0, offset) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mount, 0, 0, 2) ZEND_ARG_INFO(0, inphar) ZEND_ARG_INFO(0, externalfile) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mungServer, 0, 0, 1) ZEND_ARG_INFO(0, munglist) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_webPhar, 0, 0, 0) ZEND_ARG_INFO(0, alias) ZEND_ARG_INFO(0, index) @@ -4993,105 +4838,127 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_webPhar, 0, 0, 0) ZEND_ARG_INFO(0, rewrites) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_running, 0, 0, 1) ZEND_ARG_INFO(0, retphar) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_ua, 0, 0, 1) ZEND_ARG_INFO(0, archive) ZEND_END_ARG_INFO() #if HAVE_SPL +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_build, 0, 0, 1) ZEND_ARG_INFO(0, iterator) ZEND_ARG_INFO(0, base_directory) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_conv, 0, 0, 0) ZEND_ARG_INFO(0, format) ZEND_ARG_INFO(0, compression_type) ZEND_ARG_INFO(0, file_ext) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_comps, 0, 0, 1) ZEND_ARG_INFO(0, compression_type) ZEND_ARG_INFO(0, file_ext) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_decomp, 0, 0, 0) ZEND_ARG_INFO(0, file_ext) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_comp, 0, 0, 1) ZEND_ARG_INFO(0, compression_type) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_compo, 0, 0, 0) ZEND_ARG_INFO(0, compression_type) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_copy, 0, 0, 2) ZEND_ARG_INFO(0, newfile) ZEND_ARG_INFO(0, oldfile) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_delete, 0, 0, 1) ZEND_ARG_INFO(0, entry) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_fromdir, 0, 0, 1) ZEND_ARG_INFO(0, base_dir) ZEND_ARG_INFO(0, regex) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_offsetExists, 0, 0, 1) ZEND_ARG_INFO(0, entry) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_offsetSet, 0, 0, 2) ZEND_ARG_INFO(0, entry) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setAlias, 0, 0, 1) ZEND_ARG_INFO(0, alias) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setMetadata, 0, 0, 1) ZEND_ARG_INFO(0, metadata) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setSigAlgo, 0, 0, 1) ZEND_ARG_INFO(0, algorithm) ZEND_ARG_INFO(0, privatekey) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setStub, 0, 0, 1) ZEND_ARG_INFO(0, newstub) ZEND_ARG_INFO(0, maxlen) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_emptydir, 0, 0, 0) ZEND_ARG_INFO(0, dirname) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_extract, 0, 0, 1) ZEND_ARG_INFO(0, pathto) ZEND_ARG_INFO(0, files) ZEND_ARG_INFO(0, overwrite) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_addfile, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_ARG_INFO(0, localname) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_fromstring, 0, 0, 1) ZEND_ARG_INFO(0, localname) ZEND_ARG_INFO(0, contents) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_isff, 0, 0, 1) ZEND_ARG_INFO(0, fileformat) ZEND_END_ARG_INFO() @@ -5103,7 +4970,6 @@ zend_function_entry php_archive_methods[] = { PHP_ME(Phar, __construct, arginfo_phar___construct, ZEND_ACC_PRIVATE) #else PHP_ME(Phar, __construct, arginfo_phar___construct, ZEND_ACC_PUBLIC) - PHP_ME(Phar, __destruct, NULL, ZEND_ACC_PUBLIC) PHP_ME(Phar, addEmptyDir, arginfo_phar_emptydir, ZEND_ACC_PUBLIC) PHP_ME(Phar, addFile, arginfo_phar_addfile, ZEND_ACC_PUBLIC) PHP_ME(Phar, addFromString, arginfo_phar_fromstring, ZEND_ACC_PUBLIC) @@ -5164,10 +5030,12 @@ zend_function_entry php_archive_methods[] = { }; #if HAVE_SPL +static ZEND_BEGIN_ARG_INFO_EX(arginfo_entry___construct, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_entry_chmod, 0, 0, 1) ZEND_ARG_INFO(0, perms) ZEND_END_ARG_INFO() diff --git a/ext/phar/pharzip.h b/ext/phar/pharzip.h index c753cbc9a4..e74b5ba47f 100644 --- a/ext/phar/pharzip.h +++ b/ext/phar/pharzip.h @@ -22,15 +22,9 @@ #ifdef PHP_WIN32 #pragma pack(1) # define PHAR_ZIP_PACK -#elif defined(__sgi) -# define PHAR_ZIP_PACK #else # define PHAR_ZIP_PACK __attribute__((__packed__)) #endif - -#if defined(__sgi) -# pragma pack 0 -#endif typedef struct _phar_zip_file_header { char signature[4]; /* local file header signature 4 bytes (0x04034b50) */ char zipversion[2]; /* version needed to extract 2 bytes */ @@ -47,9 +41,6 @@ typedef struct _phar_zip_file_header { /* extra field (variable size) */ } PHAR_ZIP_PACK phar_zip_file_header; -#if defined(__sgi) -# pragma pack 0 -#endif typedef struct _phar_zip_file_datadesc { php_uint32 crc32; /* crc-32 4 bytes */ php_uint32 compsize; /* compressed size 4 bytes */ @@ -64,9 +55,6 @@ typedef struct _phar_zip_file_datadesc_zip64 { php_uint32 uncompsize2; } PHAR_ZIP_PACK phar_zip_data_desc_zip64; -#if defined(__sgi) -# pragma pack 0 -#endif typedef struct _phar_zip_archive_extra_data_record { char signature[4]; /* archive extra data signature 4 bytes (0x08064b50) */ php_uint32 len; /* extra field length 4 bytes */ @@ -147,17 +135,11 @@ typedef struct _phar_zip_archive_extra_data_record { the CRC; i.e., it may be four bytes too small.] */ -#if defined(__sgi) -# pragma pack 0 -#endif typedef struct _phar_zip_extra_field_header { char tag[2]; php_uint16 size; } PHAR_ZIP_PACK phar_zip_extra_field_header; -#if defined(__sgi) -# pragma pack 0 -#endif typedef struct _phar_zip_unix3 { char tag[2]; /* 0x756e Short tag for this extra block type ("nu") */ php_uint16 size; /* TSize Short total data size for this block */ @@ -169,9 +151,6 @@ typedef struct _phar_zip_unix3 { /* (var.) variable symbolic link filename */ } PHAR_ZIP_PACK phar_zip_unix3; -#if defined(__sgi) -# pragma pack 0 -#endif typedef struct _phar_zip_central_dir_file { char signature[4]; /* central file header signature 4 bytes (0x02014b50) */ char madeby[2]; /* version made by 2 bytes */ @@ -196,17 +175,11 @@ typedef struct _phar_zip_central_dir_file { /* file comment (variable size) */ } PHAR_ZIP_PACK phar_zip_central_dir_file; -#if defined(__sgi) -# pragma pack 0 -#endif typedef struct _phar_zip_dir_signature { char signature[4]; /* header signature 4 bytes (0x05054b50) */ php_uint16 size; /* size of data 2 bytes */ } PHAR_ZIP_PACK phar_zip_dir_signature; -#if defined(__sgi) -# pragma pack 0 -#endif typedef struct _phar_zip64_dir_end { char signature[4]; /* zip64 end of central dir signature 4 bytes (0x06064b50) */ @@ -233,9 +206,6 @@ typedef struct _phar_zip64_dir_end { /* zip64 extensible data sector (variable size) */ } PHAR_ZIP_PACK phar_zip64_dir_end; -#if defined(__sgi) -# pragma pack 0 -#endif typedef struct _phar_zip64_dir_locator { char signature[4]; /* zip64 end of central dir locator signature 4 bytes (0x07064b50) */ @@ -248,9 +218,6 @@ typedef struct _phar_zip64_dir_locator { php_uint32 totaldisks; /* total number of disks 4 bytes */ } PHAR_ZIP_PACK phar_zip64_dir_locator; -#if defined(__sgi) -# pragma pack 0 -#endif typedef struct _phar_zip_dir_end { char signature[4]; /* end of central dir signature 4 bytes (0x06054b50) */ php_uint16 disknumber; /* number of this disk 2 bytes */ diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 6670f6d48c..5ec6e2a86d 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -258,7 +258,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat entry = (phar_entry_info *) ecalloc(1, sizeof(phar_entry_info)); entry->is_temp_dir = 1; - entry->filename = estrndup("", 0); + entry->filename = ""; entry->filename_len = 0; entry->phar = phar; entry->offset = entry->offset_abs = 0; @@ -346,8 +346,15 @@ phar_stub: */ static int phar_stream_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */ { + phar_entry_info *entry = ((phar_entry_data *)stream->abstract)->internal_file; + int is_temp_dir = entry->is_temp_dir; + phar_entry_delref((phar_entry_data *)stream->abstract TSRMLS_CC); + if (is_temp_dir) { + /* phar archive stub, free it */ + efree(entry); + } return 0; } /* }}} */ @@ -359,15 +366,8 @@ static size_t phar_stream_read(php_stream *stream, char *buf, size_t count TSRML { phar_entry_data *data = (phar_entry_data *)stream->abstract; size_t got; - phar_entry_info *entry; - if (data->internal_file->link) { - entry = phar_get_link_source(data->internal_file TSRMLS_CC); - } else { - entry = data->internal_file; - } - - if (entry->is_deleted) { + if (data->internal_file->is_deleted) { stream->eof = 1; return 0; } @@ -375,9 +375,9 @@ static size_t phar_stream_read(php_stream *stream, char *buf, size_t count TSRML /* use our proxy position */ php_stream_seek(data->fp, data->position + data->zero, SEEK_SET); - got = php_stream_read(data->fp, buf, MIN(count, entry->uncompressed_filesize - data->position)); + got = php_stream_read(data->fp, buf, MIN(count, data->internal_file->uncompressed_filesize - data->position)); data->position = php_stream_tell(data->fp) - data->zero; - stream->eof = (data->position == (off_t) entry->uncompressed_filesize); + stream->eof = (data->position == (off_t) data->internal_file->uncompressed_filesize); return got; } @@ -389,19 +389,12 @@ static size_t phar_stream_read(php_stream *stream, char *buf, size_t count TSRML static int phar_stream_seek(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC) /* {{{ */ { phar_entry_data *data = (phar_entry_data *)stream->abstract; - phar_entry_info *entry; + int res; off_t temp; - - if (data->internal_file->link) { - entry = phar_get_link_source(data->internal_file TSRMLS_CC); - } else { - entry = data->internal_file; - } - switch (whence) { case SEEK_END : - temp = data->zero + entry->uncompressed_filesize + offset; + temp = data->zero + data->internal_file->uncompressed_filesize + offset; break; case SEEK_CUR : temp = data->zero + data->position + offset; @@ -410,7 +403,7 @@ static int phar_stream_seek(php_stream *stream, off_t offset, int whence, off_t temp = data->zero + offset; break; } - if (temp > data->zero + (off_t) entry->uncompressed_filesize) { + if (temp > data->zero + (off_t) data->internal_file->uncompressed_filesize) { *newoffset = -1; return -1; } @@ -472,7 +465,8 @@ static int phar_stream_flush(php_stream *stream TSRMLS_DC) /* {{{ */ /** * stat an opened phar file handle stream, used by phar_stat() */ -void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_statbuf *ssb, zend_bool is_temp_dir TSRMLS_DC) +void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_statbuf *ssb, + zend_bool is_temp_dir, char *alias, int alias_len TSRMLS_DC) { memset(ssb, 0, sizeof(php_stream_statbuf)); @@ -549,7 +543,7 @@ static int phar_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_D return -1; } - phar_dostat(data->phar, data->internal_file, ssb, 0 TSRMLS_CC); + phar_dostat(data->phar, data->internal_file, ssb, 0, data->phar->alias, data->phar->alias_len TSRMLS_CC); return 0; } /* }}} */ @@ -587,7 +581,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, internal_file = resource->path + 1; /* strip leading "/" */ /* find the phar in our trusty global hash indexed by alias (host of phar://blah.phar/file.whatever) */ - if (FAILURE == phar_get_archive(&phar, resource->host, host_len, NULL, 0, &error TSRMLS_CC)) { + if (FAILURE == phar_get_archive(&phar, resource->host, strlen(resource->host), NULL, 0, &error TSRMLS_CC)) { php_url_free(resource); if (error) { efree(error); @@ -599,7 +593,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, } if (*internal_file == '\0') { /* root directory requested */ - phar_dostat(phar, NULL, ssb, 1 TSRMLS_CC); + phar_dostat(phar, NULL, ssb, 1, phar->alias, phar->alias_len TSRMLS_CC); php_url_free(resource); return SUCCESS; } @@ -610,12 +604,12 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, internal_file_len = strlen(internal_file); /* search through the manifest of files, and if we have an exact match, it's a file */ if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, internal_file_len, (void**)&entry)) { - phar_dostat(phar, entry, ssb, 0 TSRMLS_CC); + phar_dostat(phar, entry, ssb, 0, phar->alias, phar->alias_len TSRMLS_CC); php_url_free(resource); return SUCCESS; } if (zend_hash_exists(&(phar->virtual_dirs), internal_file, internal_file_len)) { - phar_dostat(phar, NULL, ssb, 1 TSRMLS_CC); + phar_dostat(phar, NULL, ssb, 1, phar->alias, phar->alias_len TSRMLS_CC); php_url_free(resource); return SUCCESS; } @@ -639,6 +633,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, } else { char *test; int test_len; + phar_entry_info *entry; php_stream_statbuf ssbi; if (SUCCESS != zend_hash_find(&phar->manifest, str_key, keylen, (void **) &entry)) { @@ -662,7 +657,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, if (SUCCESS != zend_hash_find(&phar->manifest, internal_file, internal_file_len, (void**)&entry)) { goto free_resource; } - phar_dostat(phar, entry, ssb, 0 TSRMLS_CC); + phar_dostat(phar, entry, ssb, 0, phar->alias, phar->alias_len TSRMLS_CC); php_url_free(resource); return SUCCESS; } diff --git a/ext/phar/tar.c b/ext/phar/tar.c index e1ec700a1a..8a0ac07a80 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -155,7 +155,7 @@ int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_l } /* }}} */ -static int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp TSRMLS_DC) /* {{{ */ +int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp TSRMLS_DC) /* {{{ */ { char *metadata; size_t save = php_stream_tell(fp), read; @@ -192,7 +192,7 @@ static int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp TSRM } /* }}} */ -int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar, php_uint32 compression, char **error TSRMLS_DC) /* {{{ */ +int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, php_uint32 compression, char **error TSRMLS_DC) /* {{{ */ { char buf[512], *actual_alias = NULL, *p; phar_entry_info entry = {0}; @@ -599,7 +599,7 @@ struct _phar_pass_tar_info { char **error; }; -static int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ */ +int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ */ { tar_header header; size_t pos; @@ -620,7 +620,6 @@ static int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ * } } - phar_add_virtual_dirs(entry->phar, entry->filename, entry->filename_len TSRMLS_CC); memset((char *) &header, 0, sizeof(header)); if (entry->filename_len > 100) { @@ -737,7 +736,7 @@ static int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ * } /* }}} */ -int phar_tar_setmetadata(zval *metadata, phar_entry_info *entry, char **error TSRMLS_DC) /* {{{ */ +int phar_tar_setmetadata(zval *metadata, phar_entry_info *entry, char **error, php_stream *fp TSRMLS_DC) /* {{{ */ { php_serialize_data_t metadata_hash; @@ -771,16 +770,17 @@ int phar_tar_setmetadata(zval *metadata, phar_entry_info *entry, char **error TS } /* }}} */ -static int phar_tar_setupmetadata(void *pDest, void *argument TSRMLS_DC) /* {{{ */ +int phar_tar_setupmetadata(void *pDest, void *argument TSRMLS_DC) /* {{{ */ { int lookfor_len; struct _phar_pass_tar_info *i = (struct _phar_pass_tar_info *)argument; char *lookfor, **error = i->error; + php_stream *fp = i->old; phar_entry_info *entry = (phar_entry_info *)pDest, *metadata, newentry = {0}; if (entry->filename_len >= sizeof(".phar/.metadata") && !memcmp(entry->filename, ".phar/.metadata", sizeof(".phar/.metadata")-1)) { if (entry->filename_len == sizeof(".phar/.metadata.bin")-1 && !memcmp(entry->filename, ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1)) { - return phar_tar_setmetadata(entry->phar->metadata, entry, error TSRMLS_CC); + return phar_tar_setmetadata(entry->phar->metadata, entry, error, fp TSRMLS_CC); } /* search for the file this metadata entry references */ if (entry->filename_len >= sizeof(".phar/.metadata/") + sizeof("/.metadata.bin") - 1 && !zend_hash_exists(&(entry->phar->manifest), entry->filename + sizeof(".phar/.metadata/") - 1, entry->filename_len - (sizeof("/.metadata.bin") - 1 + sizeof(".phar/.metadata/") - 1))) { @@ -806,7 +806,7 @@ static int phar_tar_setupmetadata(void *pDest, void *argument TSRMLS_DC) /* {{{ if (SUCCESS == zend_hash_find(&(entry->phar->manifest), lookfor, lookfor_len, (void **)&metadata)) { int ret; - ret = phar_tar_setmetadata(entry->metadata, metadata, error TSRMLS_CC); + ret = phar_tar_setmetadata(entry->metadata, metadata, error, fp TSRMLS_CC); efree(lookfor); return ret; } @@ -823,7 +823,7 @@ static int phar_tar_setupmetadata(void *pDest, void *argument TSRMLS_DC) /* {{{ return ZEND_HASH_APPLY_STOP; } - return phar_tar_setmetadata(entry->metadata, metadata, error TSRMLS_CC); + return phar_tar_setmetadata(entry->metadata, metadata, error, fp TSRMLS_CC); } /* }}} */ @@ -1014,7 +1014,7 @@ nostub: if (phar->metadata) { phar_entry_info *mentry; if (SUCCESS == zend_hash_find(&(phar->manifest), ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1, (void **)&mentry)) { - if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(phar->metadata, mentry, error TSRMLS_CC)) { + if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(phar->metadata, mentry, error, oldfile TSRMLS_CC)) { if (closeoldfile) { php_stream_close(oldfile); } @@ -1037,7 +1037,7 @@ nostub: return EOF; } - if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(phar->metadata, mentry, error TSRMLS_CC)) { + if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(phar->metadata, mentry, error, oldfile TSRMLS_CC)) { zend_hash_del(&(phar->manifest), ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1); if (closeoldfile) { php_stream_close(oldfile); diff --git a/ext/phar/tar.h b/ext/phar/tar.h index 45dc6e5c0b..6dc1fd3127 100644 --- a/ext/phar/tar.h +++ b/ext/phar/tar.h @@ -22,15 +22,9 @@ #ifdef PHP_WIN32 #pragma pack(1) # define PHAR_TAR_PACK -#elif defined(__sgi) -# define PHAR_TAR_PACK #else # define PHAR_TAR_PACK __attribute__((__packed__)) #endif - -#if defined(__sgi) -# pragma pack 0 -#endif /** * the format of the header block for a file, in the older UNIX-compatible * TAR format @@ -52,9 +46,6 @@ typedef struct _old_tar_header { /* {{{ */ } PHAR_TAR_PACK old_tar_header; /* }}} */ -#if defined(__sgi) -# pragma pack 0 -#endif /** * the new USTAR header format. * Note that tar can determine that the USTAR format is being used by the diff --git a/ext/phar/tests/files/blog.phar b/ext/phar/tests/files/blog.phar Binary files differindex 9f0425db84..58c8a3bca7 100644 --- a/ext/phar/tests/files/blog.phar +++ b/ext/phar/tests/files/blog.phar diff --git a/ext/phar/tests/files/blog.phar.inc b/ext/phar/tests/files/blog.phar.inc index 0f2afe475d..62d86c5c3f 100644 --- a/ext/phar/tests/files/blog.phar.inc +++ b/ext/phar/tests/files/blog.phar.inc @@ -4,9 +4,7 @@ $fname = dirname(__FILE__) . '/blog.phar'; @unlink($fname); $phar = new Phar($fname); -$phar->setStub('<?php -Phar::interceptFileFuncs(); -if(file_exists(dirname(__FILE__) . "/files/config.xml")) { +$phar->setStub('<?php if(file_exists(dirname(__FILE__) . "/files/config.xml")) { Phar::mount("config.xml", dirname(__FILE__) . "/files/config.xml"); } Phar::webPhar("blog", "index.php"); diff --git a/ext/phar/tests/phar_get_supported_signatures_002a.phpt b/ext/phar/tests/phar_get_supported_signatures_002a.phpt index 154d1806c6..ce907ff638 100644 --- a/ext/phar/tests/phar_get_supported_signatures_002a.phpt +++ b/ext/phar/tests/phar_get_supported_signatures_002a.phpt @@ -6,7 +6,6 @@ if (!extension_loaded("phar")) die("skip"); if (!extension_loaded("hash")) die("skip extension hash required"); $arr = Phar::getSupportedSignatures(); if (!in_array("OpenSSL", $arr)) die("skip openssl support required"); -if (!in_array('SHA-256', $arr)) die("skip hash extension loaded shared"); ?> --INI-- phar.require_hash=0 diff --git a/ext/phar/tests/phar_oo_005.phpt b/ext/phar/tests/phar_oo_005.phpt index 2d4cbd082c..119e013699 100755 --- a/ext/phar/tests/phar_oo_005.phpt +++ b/ext/phar/tests/phar_oo_005.phpt @@ -4,8 +4,7 @@ Phar and RecursiveDirectoryIterator <?php if (!extension_loaded("phar")) die("skip"); if (!extension_loaded("spl")) die("skip SPL not available"); -if (version_compare(PHP_VERSION, "5.3", "<") or version_compare(PHP_VERSION, "5.4", ">=")) - die("skip requires 5.3"); +if (!version_compare(PHP_VERSION, "5.3", "==")) die("skip requires 5.3"); ?> --INI-- phar.require_hash=0 diff --git a/ext/phar/tests/phar_setsignaturealgo2.phpt b/ext/phar/tests/phar_setsignaturealgo2.phpt index 66edb61222..e3f858d5d6 100644 --- a/ext/phar/tests/phar_setsignaturealgo2.phpt +++ b/ext/phar/tests/phar_setsignaturealgo2.phpt @@ -4,9 +4,7 @@ Phar::setSupportedSignatures() with hash <?php if (!extension_loaded("phar")) die("skip"); if (!extension_loaded("hash")) die("skip hash extension required"); -$arr = Phar::getSupportedSignatures(); -if (!in_array("OpenSSL", $arr)) die("skip openssl support required"); -if (!in_array('SHA-256', $arr)) die("skip hash extension loaded shared"); +if (!extension_loaded("openssl")) die("skip openssl extension required"); ?> --INI-- phar.require_hash=0 diff --git a/ext/phar/tests/stat.phpt b/ext/phar/tests/stat.phpt index 184aa6d2ec..020fc24f86 100644 --- a/ext/phar/tests/stat.phpt +++ b/ext/phar/tests/stat.phpt @@ -14,7 +14,7 @@ $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php'; $fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.tar'; $fname3 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar'; $a = new Phar($fname); -$a['my/index.php'] = '<?php +$a['index.php'] = '<?php echo "stat\n"; var_dump(stat("dir/file1.txt")); echo "lstat\n"; @@ -53,17 +53,13 @@ echo "is_file\n"; var_dump(is_file("dir/file1.txt")); echo "is_link\n"; var_dump(is_link("dir/file1.txt")); -echo "not found\n"; -var_dump(file_exists("not/found")); -echo "not found 2\n"; -var_dump(fileperms("not/found")); ?>'; $a['dir/file1.txt'] = 'hi'; $a['dir/file2.txt'] = 'hi2'; $a['dir/file3.txt'] = 'hi3'; $a->setStub('<?php set_include_path("phar://" . __FILE__ . "/dir" . PATH_SEPARATOR . "phar://" . __FILE__); -include "my/index.php"; +include "index.php"; __HALT_COMPILER();'); include $fname; ?> @@ -216,10 +212,4 @@ is_file bool(true) is_link bool(false) -not found -bool(false) -not found 2 - -Warning: fileperms(): stat failed for not/found in phar://%sstat.phar.php/my/index.php on line %d -bool(false) ===DONE===
\ No newline at end of file diff --git a/ext/phar/tests/tar/phar_setsignaturealgo2.phpt b/ext/phar/tests/tar/phar_setsignaturealgo2.phpt index 422ca90e8a..e9cbdb4a5d 100644 --- a/ext/phar/tests/tar/phar_setsignaturealgo2.phpt +++ b/ext/phar/tests/tar/phar_setsignaturealgo2.phpt @@ -2,10 +2,8 @@ Phar::setSupportedSignatures() with hash, tar-based --SKIPIF-- <?php if (!extension_loaded("phar")) die("skip"); ?> -<?php if (!extension_loaded("hash")) die("skip extension hash required"); -$arr = Phar::getSupportedSignatures(); -if (!in_array("OpenSSL", $arr)) die("skip openssl support required"); -if (!in_array('SHA-256', $arr)) die("skip hash extension loaded shared"); ?> +<?php if (!extension_loaded("hash")) die("skip extension hash required"); ?> +<?php if (!extension_loaded("openssl")) die("skip extension openssl required"); ?> --INI-- phar.require_hash=0 phar.readonly=0 diff --git a/ext/phar/tests/tar/rmdir.phpt b/ext/phar/tests/tar/rmdir.phpt index be037823d6..d08e521614 100644 --- a/ext/phar/tests/tar/rmdir.phpt +++ b/ext/phar/tests/tar/rmdir.phpt @@ -23,7 +23,6 @@ $files['a/x'] = 'a'; foreach ($files as $n => $file) { $tar->addFile($n, $file); } -$tar->mkdir('a'); $tar->close(); @@ -40,7 +39,7 @@ var_dump(rmdir($alias . '/a')); --EXPECTF-- a -Warning: rmdir(): phar error: Directory not empty in %srmdir.php on line %d +Warning: rmdir(): phar error: Directory not empty in %srmdir.php on line 24 bool(false) a bool(true) diff --git a/ext/phar/tests/test_signaturealgos.phpt b/ext/phar/tests/test_signaturealgos.phpt index 7cbf6c0513..2ef7ca109f 100644 --- a/ext/phar/tests/test_signaturealgos.phpt +++ b/ext/phar/tests/test_signaturealgos.phpt @@ -6,7 +6,6 @@ if (!extension_loaded("phar")) die("skip"); if (!extension_loaded("hash")) die("skip extension hash conflicts"); $arr = Phar::getSupportedSignatures(); if (!in_array("OpenSSL", $arr)) die("skip openssl support required"); -if (!in_array('SHA-256', $arr)) die("skip hash extension loaded shared"); ?> --INI-- phar.require_hash=0 diff --git a/ext/phar/tests/zip/bzip2.phpt b/ext/phar/tests/zip/bzip2.phpt index a703ce6033..f34f1859cd 100644 --- a/ext/phar/tests/zip/bzip2.phpt +++ b/ext/phar/tests/zip/bzip2.phpt @@ -11,8 +11,6 @@ try { foreach ($a as $entry => $file) { echo $file->getContent(); } - $a = new Phar(dirname(__FILE__) . '/files/bz2_alias.phar.zip'); - var_dump($a->getAlias()); } catch (Exception $e) { echo $e->getMessage() . "\n"; } @@ -79,5 +77,4 @@ $a = new corrupt_zipmaker; $a->addFile('hi', null, 'hii', null, null, 'compress', 'compress', 11); $a->writeZip(dirname(__FILE__) . '/compress_unsupunknown.zip'); ?> -string(175) "hitheresuperlongzipistoostupidtodowhatIsaysoIhavetousethisridiculouslylongaliasbecauseitisstupiddidImentionthatalreadythemadnessdoesnotstopIhateinfozipIhateinfozipIhateinfozip" ===DONE=== diff --git a/ext/phar/tests/zip/rmdir.phpt b/ext/phar/tests/zip/rmdir.phpt index c7ef9dacac..149f0e8d6b 100644 --- a/ext/phar/tests/zip/rmdir.phpt +++ b/ext/phar/tests/zip/rmdir.phpt @@ -15,7 +15,6 @@ $phar = new Phar($fname); $phar->setStub("<?php Phar::mapPhar('hio'); __HALT_COMPILER(); ?>"); -$phar->addEmptyDir('a'); $phar['a/x'] = 'a'; $phar->stopBuffering(); @@ -32,7 +31,7 @@ var_dump(rmdir($alias . '/a')); --EXPECTF-- a -Warning: rmdir(): phar error: Directory not empty in %srmdir.php on line %d +Warning: rmdir(): phar error: Directory not empty in %srmdir.php on line 16 bool(false) a bool(true) diff --git a/ext/phar/util.c b/ext/phar/util.c index cf4fa11e2b..0723cd2508 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -21,9 +21,6 @@ /* $Id$ */ #include "phar_internal.h" -#ifdef PHAR_HASH_OK -#include "ext/hash/php_hash_sha.h" -#endif #ifdef PHAR_HAVE_OPENSSL /* OpenSSL includes */ @@ -68,13 +65,12 @@ static char *phar_get_link_location(phar_entry_info *entry TSRMLS_DC) /* {{{ */ phar_entry_info *phar_get_link_source(phar_entry_info *entry TSRMLS_DC) /* {{{ */ { phar_entry_info *link_entry; - char *link; + char *link = phar_get_link_location(entry TSRMLS_CC); if (!entry->link) { return entry; } - link = phar_get_link_location(entry TSRMLS_CC); if (SUCCESS == zend_hash_find(&(entry->phar->manifest), entry->link, strlen(entry->link), (void **)&link_entry) || SUCCESS == zend_hash_find(&(entry->phar->manifest), link, strlen(link), (void **)&link_entry)) { if (link != entry->link) { @@ -684,13 +680,13 @@ really_get_entry: phar_seek_efp(entry, 0, SEEK_END, 0, 0 TSRMLS_CC); } } else { - if (for_write) { - if (entry->link) { - efree(entry->link); - entry->link = NULL; - entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); - } + if (entry->link) { + efree(entry->link); + entry->link = NULL; + entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); + } + if (for_write) { if (for_trunc) { if (FAILURE == phar_create_writeable_entry(phar, entry, error TSRMLS_CC)) { return FAILURE; @@ -715,11 +711,7 @@ really_get_entry: (*ret)->is_zip = entry->is_zip; (*ret)->is_tar = entry->is_tar; (*ret)->fp = phar_get_efp(entry, 1 TSRMLS_CC); - if (entry->link) { - (*ret)->zero = phar_get_fp_offset(phar_get_link_source(entry TSRMLS_CC) TSRMLS_CC); - } else { - (*ret)->zero = phar_get_fp_offset(entry TSRMLS_CC); - } + (*ret)->zero = phar_get_fp_offset(entry TSRMLS_CC); if (!phar->is_persistent) { ++(entry->fp_refcount); @@ -793,13 +785,13 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char if (allow_dir == 2) { etemp.is_dir = 1; etemp.flags = etemp.old_flags = PHAR_ENT_PERM_DEF_DIR; + if (is_dir) { + etemp.filename_len--; /* strip trailing / */ + path_len--; + } } else { etemp.flags = etemp.old_flags = PHAR_ENT_PERM_DEF_FILE; } - if (is_dir) { - etemp.filename_len--; /* strip trailing / */ - path_len--; - } phar_add_virtual_dirs(phar, path, path_len TSRMLS_CC); etemp.is_modified = 1; @@ -811,7 +803,7 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char if (phar->is_tar) { etemp.is_tar = phar->is_tar; - etemp.tar_type = etemp.is_dir ? TAR_DIR : TAR_FILE; + etemp.tar_type = TAR_FILE; } if (FAILURE == zend_hash_add(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info), (void **) &entry)) { @@ -1158,7 +1150,7 @@ int phar_separate_entry_fp(phar_entry_info *entry, char **error TSRMLS_DC) /* {{ /** * helper function to open an internal file's fp just-in-time */ -phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC) /* {{{ */ +phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, php_stream *fp, char **error, int for_write TSRMLS_DC) /* {{{ */ { if (error) { *error = NULL; @@ -1458,7 +1450,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in { const char *pcr_error; phar_entry_info *entry; - int is_dir; + char is_dir; #ifdef PHP_WIN32 phar_unixify_path_separators(path, path_len); @@ -1883,7 +1875,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ *signature_len = phar_hex_str((const char*)sig, sig_len, signature TSRMLS_CC); } break; -#ifdef PHAR_HASH_OK +#if HAVE_HASH_EXT case PHAR_SIG_SHA512: { unsigned char digest[64]; PHP_SHA512_CTX context; @@ -2047,7 +2039,7 @@ int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signat } switch(phar->sig_flags) { -#ifdef PHAR_HASH_OK +#if HAVE_HASH_EXT case PHAR_SIG_SHA512: { unsigned char digest[64]; PHP_SHA512_CTX context; @@ -2201,7 +2193,7 @@ void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, int filename } /* }}} */ -static int phar_update_cached_entry(void *data, void *argument) /* {{{ */ +static void phar_update_cached_entry(void *data, void *argument) /* {{{ */ { phar_entry_info *entry = (phar_entry_info *)data; TSRMLS_FETCH(); @@ -2222,10 +2214,8 @@ static int phar_update_cached_entry(void *data, void *argument) /* {{{ */ if (entry->metadata) { if (entry->metadata_len) { - char *buf = estrndup((char *) entry->metadata, entry->metadata_len); /* assume success, we would have failed before */ - phar_parse_metadata((char **) &buf, &entry->metadata, entry->metadata_len TSRMLS_CC); - efree(buf); + phar_parse_metadata((char **) &entry->metadata, &entry->metadata, entry->metadata_len TSRMLS_CC); } else { zval *t; @@ -2242,7 +2232,6 @@ static int phar_update_cached_entry(void *data, void *argument) /* {{{ */ entry->metadata_str.len = 0; } } - return ZEND_HASH_APPLY_KEEP; } /* }}} */ @@ -2251,7 +2240,6 @@ static void phar_copy_cached_phar(phar_archive_data **pphar TSRMLS_DC) /* {{{ */ phar_archive_data *phar; HashTable newmanifest; char *fname; - phar_archive_object **objphar; phar = (phar_archive_data *) emalloc(sizeof(phar_archive_data)); *phar = **pphar; @@ -2271,9 +2259,7 @@ static void phar_copy_cached_phar(phar_archive_data **pphar TSRMLS_DC) /* {{{ */ if (phar->metadata) { /* assume success, we would have failed before */ if (phar->metadata_len) { - char *buf = estrndup((char *) phar->metadata, phar->metadata_len); - phar_parse_metadata(&buf, &phar->metadata, phar->metadata_len TSRMLS_CC); - efree(buf); + phar_parse_metadata((char **) &phar->metadata, &phar->metadata, phar->metadata_len TSRMLS_CC); } else { zval *t; @@ -2300,15 +2286,6 @@ static void phar_copy_cached_phar(phar_archive_data **pphar TSRMLS_DC) /* {{{ */ zend_get_hash_value, NULL, 0); zend_hash_copy(&phar->virtual_dirs, &(*pphar)->virtual_dirs, NULL, NULL, sizeof(void *)); *pphar = phar; - - /* now, scan the list of persistent Phar objects referencing this phar and update the pointers */ - for (zend_hash_internal_pointer_reset(&PHAR_GLOBALS->phar_persist_map); - SUCCESS == zend_hash_get_current_data(&PHAR_GLOBALS->phar_persist_map, (void **) &objphar); - zend_hash_move_forward(&PHAR_GLOBALS->phar_persist_map)) { - if (objphar[0]->arc.archive->fname_len == phar->fname_len && !memcmp(objphar[0]->arc.archive->fname, phar->fname, phar->fname_len)) { - objphar[0]->arc.archive = phar; - } - } } /* }}} */ diff --git a/ext/phar/zip.c b/ext/phar/zip.c index b942bcee61..26d873239f 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -465,38 +465,10 @@ foundit: if (!actual_alias && entry.filename_len == sizeof(".phar/alias.txt")-1 && !strncmp(entry.filename, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) { php_stream_filter *filter; off_t saveloc; - /* verify local file header */ - phar_zip_file_header local; - /* archive alias found */ + /* archive alias found, seek to file contents, do not validate local header. Potentially risky, but not very. */ saveloc = php_stream_tell(fp); - php_stream_seek(fp, PHAR_GET_32(zipentry.offset), SEEK_SET); - - if (sizeof(local) != php_stream_read(fp, (char *) &local, sizeof(local))) { - PHAR_ZIP_FAIL("phar error: internal corruption of zip-based phar (cannot read local file header for alias)"); - } - - /* verify local header */ - if (entry.filename_len != PHAR_GET_16(local.filename_len) || entry.crc32 != PHAR_GET_32(local.crc32) || entry.uncompressed_filesize != PHAR_GET_32(local.uncompsize) || entry.compressed_filesize != PHAR_GET_32(local.compsize)) { - PHAR_ZIP_FAIL("phar error: internal corruption of zip-based phar (local head of alias does not match central directory)"); - } - - /* construct actual offset to file start - local extra_len can be different from central extra_len */ - entry.offset = entry.offset_abs = - sizeof(local) + entry.header_offset + PHAR_GET_16(local.filename_len) + PHAR_GET_16(local.extra_len); -#if PHP_VERSION_ID < 50207 - /* work around Bug #46147 */ - fp->writepos = fp->readpos = 0; -#endif - php_stream_seek(fp, entry.offset, SEEK_SET); - /* these next lines should be for php < 5.2.6 after 5.3 filters are fixed */ - fp->writepos = 0; - fp->readpos = 0; - php_stream_seek(fp, entry.offset, SEEK_SET); - fp->writepos = 0; - fp->readpos = 0; - /* the above lines should be for php < 5.2.6 after 5.3 filters are fixed */ - + php_stream_seek(fp, PHAR_GET_32(zipentry.offset) + sizeof(phar_zip_file_header) + entry.filename_len + PHAR_GET_16(zipentry.extra_len), SEEK_SET); mydata->alias_len = entry.uncompressed_filesize; if (entry.flags & PHAR_ENT_COMPRESSED_GZ) { @@ -511,9 +483,6 @@ foundit: if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) { pefree(entry.filename, entry.is_persistent); -#if PHP_VERSION_ID < 50207 - PHAR_ZIP_FAIL("unable to read in alias, truncated (PHP 5.2.7 and newer has a potential fix for this problem)"); -#endif PHAR_ZIP_FAIL("unable to read in alias, truncated"); } @@ -529,12 +498,10 @@ foundit: } php_stream_filter_append(&fp->readfilters, filter); + 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) { pefree(entry.filename, entry.is_persistent); -#if PHP_VERSION_ID < 50207 - PHAR_ZIP_FAIL("unable to read in alias, truncated (PHP 5.2.7 and newer has a potential fix for this problem)"); -#endif PHAR_ZIP_FAIL("unable to read in alias, truncated"); } @@ -704,7 +671,6 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */ } } - phar_add_virtual_dirs(entry->phar, entry->filename, entry->filename_len TSRMLS_CC); memset(&local, 0, sizeof(local)); memset(¢ral, 0, sizeof(central)); memset(&perms, 0, sizeof(perms)); @@ -1171,7 +1137,6 @@ nostub: pass.filefp = php_stream_fopen_tmpfile(); if (!pass.filefp) { -fperror: if (closeoldfile) { php_stream_close(oldfile); } @@ -1184,7 +1149,13 @@ fperror: pass.centralfp = php_stream_fopen_tmpfile(); if (!pass.centralfp) { - goto fperror; + if (closeoldfile) { + php_stream_close(oldfile); + } + if (error) { + spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to open temporary file", phar->fname); + } + return EOF; } pass.free_fp = pass.free_ufp = 1; @@ -1195,17 +1166,15 @@ fperror: zend_hash_apply_with_argument(&phar->manifest, phar_zip_changed_apply, (void *) &pass TSRMLS_CC); if (temperr) { - if (error) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: %s", phar->fname, temperr); - } - efree(temperr); -temperror: - php_stream_close(pass.centralfp); -nocentralerror: php_stream_close(pass.filefp); + php_stream_close(pass.centralfp); if (closeoldfile) { php_stream_close(oldfile); } + if (error) { + spprintf(error, 4096, "phar zip flush of \"%s\" failed: %s", phar->fname, temperr); + } + efree(temperr); return EOF; } @@ -1215,10 +1184,15 @@ nocentralerror: php_stream_seek(pass.centralfp, 0, SEEK_SET); if (eocd.cdir_size != php_stream_copy_to_stream(pass.centralfp, pass.filefp, PHP_STREAM_COPY_ALL)) { + php_stream_close(pass.filefp); + php_stream_close(pass.centralfp); if (error) { spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write central-directory", phar->fname); } - goto temperror; + if (closeoldfile) { + php_stream_close(oldfile); + } + return EOF; } php_stream_close(pass.centralfp); @@ -1231,27 +1205,41 @@ nocentralerror: eocd.comment_len = PHAR_SET_16(main_metadata_str.len); if (sizeof(eocd) != php_stream_write(pass.filefp, (char *)&eocd, sizeof(eocd))) { + php_stream_close(pass.filefp); if (error) { spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write end of central-directory", phar->fname); } - goto nocentralerror; + if (closeoldfile) { + php_stream_close(oldfile); + } + smart_str_free(&main_metadata_str); + return EOF; } if (main_metadata_str.len != php_stream_write(pass.filefp, main_metadata_str.c, main_metadata_str.len)) { + php_stream_close(pass.filefp); if (error) { spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write metadata to zip comment", phar->fname); } - goto nocentralerror; + if (closeoldfile) { + php_stream_close(oldfile); + } + smart_str_free(&main_metadata_str); + return EOF; } smart_str_free(&main_metadata_str); } else { if (sizeof(eocd) != php_stream_write(pass.filefp, (char *)&eocd, sizeof(eocd))) { + php_stream_close(pass.filefp); if (error) { spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write end of central-directory", phar->fname); } - goto nocentralerror; + if (closeoldfile) { + php_stream_close(oldfile); + } + return EOF; } } |