summaryrefslogtreecommitdiff
path: root/ext/phar
diff options
context:
space:
mode:
Diffstat (limited to 'ext/phar')
-rw-r--r--ext/phar/config.m48
-rw-r--r--ext/phar/dirstream.c74
-rw-r--r--ext/phar/func_interceptors.c6
-rw-r--r--ext/phar/phar.c38
-rwxr-xr-xext/phar/phar/pharcommand.inc6
-rwxr-xr-xext/phar/phar_internal.h64
-rwxr-xr-xext/phar/phar_object.c252
-rw-r--r--ext/phar/pharzip.h33
-rw-r--r--ext/phar/stream.c51
-rw-r--r--ext/phar/tar.c22
-rw-r--r--ext/phar/tar.h9
-rw-r--r--ext/phar/tests/files/blog.pharbin496 -> 468 bytes
-rw-r--r--ext/phar/tests/files/blog.phar.inc4
-rw-r--r--ext/phar/tests/phar_get_supported_signatures_002a.phpt1
-rwxr-xr-xext/phar/tests/phar_oo_005.phpt3
-rw-r--r--ext/phar/tests/phar_setsignaturealgo2.phpt4
-rw-r--r--ext/phar/tests/stat.phpt14
-rw-r--r--ext/phar/tests/tar/phar_setsignaturealgo2.phpt6
-rw-r--r--ext/phar/tests/tar/rmdir.phpt3
-rw-r--r--ext/phar/tests/test_signaturealgos.phpt1
-rw-r--r--ext/phar/tests/zip/bzip2.phpt3
-rw-r--r--ext/phar/tests/zip/rmdir.phpt3
-rw-r--r--ext/phar/util.c63
-rw-r--r--ext/phar/zip.c88
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(&regexiter);
- }
- 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(&regexiter);
- }
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
index 9f0425db84..58c8a3bca7 100644
--- a/ext/phar/tests/files/blog.phar
+++ b/ext/phar/tests/files/blog.phar
Binary files differ
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(&central, 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;
}
}