making progress - up to 42/phar vs. 48/disk with these optimizations

This commit is contained in:
Greg Beaver 2008-06-20 05:42:58 +00:00
parent 5233505043
commit 7cc6b9f3f5
6 changed files with 207 additions and 72 deletions

View File

@ -119,7 +119,7 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */
fname_len = strlen(fname);
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
char *name;
phar_archive_data **pphar;
phar_archive_data *phar;
efree(entry);
entry = filename;
@ -133,8 +133,7 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */
}
/* retrieving a file defaults to within the current directory, so use this if possible */
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && FAILURE == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar)))
&& (PHAR_G(manifest_cached) && FAILURE == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) {
if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
efree(arch);
goto skip_phar;
}
@ -150,7 +149,7 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */
} else {
entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
if (entry[0] == '/') {
if (!zend_hash_exists(&((*pphar)->manifest), entry + 1, entry_len - 1)) {
if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
/* this file is not in the phar, use the original path */
notfound:
efree(arch);
@ -158,7 +157,7 @@ notfound:
goto skip_phar;
}
} else {
if (!zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) {
if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
goto notfound;
}
}
@ -237,7 +236,7 @@ PHAR_FUNC(phar_readfile) /* {{{ */
int arch_len, entry_len, fname_len;
php_stream_context *context = NULL;
char *name;
phar_archive_data **pphar;
phar_archive_data *phar;
fname = zend_get_executed_filename(TSRMLS_C);
if (strncasecmp(fname, "phar://", 7)) {
@ -253,8 +252,7 @@ PHAR_FUNC(phar_readfile) /* {{{ */
/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
entry_len = filename_len;
/* retrieving a file defaults to within the current directory, so use this if possible */
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && FAILURE == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar)))
&& (PHAR_G(manifest_cached) && FAILURE == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) {
if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
efree(arch);
goto skip_phar;
}
@ -269,7 +267,7 @@ PHAR_FUNC(phar_readfile) /* {{{ */
} else {
entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
if (entry[0] == '/') {
if (!zend_hash_exists(&((*pphar)->manifest), entry + 1, entry_len - 1)) {
if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
/* this file is not in the phar, use the original path */
notfound:
efree(entry);
@ -277,7 +275,7 @@ notfound:
goto skip_phar;
}
} else {
if (!zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) {
if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
goto notfound;
}
}
@ -330,7 +328,7 @@ PHAR_FUNC(phar_fopen) /* {{{ */
int arch_len, entry_len, fname_len;
php_stream_context *context = NULL;
char *name;
phar_archive_data **pphar;
phar_archive_data *phar;
fname = zend_get_executed_filename(TSRMLS_C);
if (strncasecmp(fname, "phar://", 7)) {
@ -346,8 +344,7 @@ PHAR_FUNC(phar_fopen) /* {{{ */
/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
entry_len = filename_len;
/* retrieving a file defaults to within the current directory, so use this if possible */
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && FAILURE == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar)))
&& (PHAR_G(manifest_cached) && FAILURE == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) {
if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
efree(arch);
goto skip_phar;
}
@ -362,7 +359,7 @@ PHAR_FUNC(phar_fopen) /* {{{ */
} else {
entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
if (entry[0] == '/') {
if (!zend_hash_exists(&((*pphar)->manifest), entry + 1, entry_len - 1)) {
if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
/* this file is not in the phar, use the original path */
notfound:
efree(entry);
@ -370,7 +367,7 @@ notfound:
goto skip_phar;
}
} else {
if (!zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) {
if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
/* this file is not in the phar, use the original path */
goto notfound;
}
@ -602,8 +599,7 @@ void phar_file_stat(const char *filename, php_stat_len filename_length, int type
int arch_len, entry_len, fname_len;
struct stat sb = {0};
phar_entry_info *data = NULL;
char *tmp;
int tmp_len;
phar_archive_data *phar;
fname = zend_get_executed_filename(TSRMLS_C);
@ -614,31 +610,39 @@ void phar_file_stat(const char *filename, php_stat_len filename_length, int type
goto skip_phar;
}
fname_len = strlen(fname);
if (PHAR_G(last_phar) && fname_len - 7 >= PHAR_G(last_phar_name_len) && !memcmp(fname + 7, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))) {
arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len));
arch_len = PHAR_G(last_phar_name_len);
entry = estrndup(filename, filename_length);
/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
entry_len = (int) filename_length;
phar = PHAR_G(last_phar);
goto splitted;
}
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
phar_archive_data **pphar;
efree(entry);
entry = estrndup(filename, filename_length);
/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
entry_len = (int) filename_length;
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && FAILURE == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar)))
&& (PHAR_G(manifest_cached) && FAILURE == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) {
if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
efree(arch);
goto skip_phar;
}
splitted:
entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
if (entry[0] == '/') {
if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry + 1, entry_len - 1, (void **) &data)) {
if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &data)) {
efree(entry);
goto stat_entry;
}
goto notfound;
}
if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) &data)) {
if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &data)) {
efree(entry);
goto stat_entry;
}
if (SUCCESS == zend_hash_find(&((*pphar)->virtual_dirs), entry, entry_len, (void **) &data)) {
if (SUCCESS == zend_hash_find(&(phar->virtual_dirs), entry, entry_len, (void **) &data)) {
efree(entry);
efree(arch);
if (IS_EXISTS_CHECK(type)) {
@ -648,13 +652,13 @@ void phar_file_stat(const char *filename, php_stat_len filename_length, int type
sb.st_mode = 0777;
sb.st_mode |= S_IFDIR; /* regular directory */
#ifdef NETWARE
sb.st_mtime.tv_sec = (*pphar)->max_timestamp;
sb.st_atime.tv_sec = (*pphar)->max_timestamp;
sb.st_ctime.tv_sec = (*pphar)->max_timestamp;
sb.st_mtime.tv_sec = phar->max_timestamp;
sb.st_atime.tv_sec = phar->max_timestamp;
sb.st_ctime.tv_sec = phar->max_timestamp;
#else
sb.st_mtime = (*pphar)->max_timestamp;
sb.st_atime = (*pphar)->max_timestamp;
sb.st_ctime = (*pphar)->max_timestamp;
sb.st_mtime = phar->max_timestamp;
sb.st_atime = phar->max_timestamp;
sb.st_ctime = phar->max_timestamp;
#endif
goto statme_baby;
} else {
@ -675,7 +679,7 @@ notfound:
PHAR_G(cwd_len) = 0;
/* clean path without cwd */
entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry + 1, entry_len - 1, (void **) &data)) {
if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &data)) {
PHAR_G(cwd) = save;
PHAR_G(cwd_len) = save_len;
efree(entry);
@ -685,7 +689,7 @@ notfound:
}
goto stat_entry;
}
if (SUCCESS == zend_hash_find(&((*pphar)->virtual_dirs), entry + 1, entry_len - 1, (void **) &data)) {
if (SUCCESS == zend_hash_find(&(phar->virtual_dirs), entry + 1, entry_len - 1, (void **) &data)) {
PHAR_G(cwd) = save;
PHAR_G(cwd_len) = save_len;
efree(entry);
@ -698,13 +702,13 @@ notfound:
sb.st_mode = 0777;
sb.st_mode |= S_IFDIR; /* regular directory */
#ifdef NETWARE
sb.st_mtime.tv_sec = (*pphar)->max_timestamp;
sb.st_atime.tv_sec = (*pphar)->max_timestamp;
sb.st_ctime.tv_sec = (*pphar)->max_timestamp;
sb.st_mtime.tv_sec = phar->max_timestamp;
sb.st_atime.tv_sec = phar->max_timestamp;
sb.st_ctime.tv_sec = phar->max_timestamp;
#else
sb.st_mtime = (*pphar)->max_timestamp;
sb.st_atime = (*pphar)->max_timestamp;
sb.st_ctime = (*pphar)->max_timestamp;
sb.st_mtime = phar->max_timestamp;
sb.st_atime = phar->max_timestamp;
sb.st_ctime = phar->max_timestamp;
#endif
goto statme_baby;
}
@ -759,29 +763,18 @@ stat_entry:
statme_baby:
efree(arch);
if (!(*pphar)->is_writeable) {
if (!phar->is_writeable) {
sb.st_mode = (sb.st_mode & 0555) | (sb.st_mode & ~0777);
}
sb.st_nlink = 1;
sb.st_rdev = -1;
if (data) {
tmp_len = data->filename_len + (*pphar)->alias_len;
} else {
tmp_len = (*pphar)->alias_len + 1;
}
tmp = (char *) emalloc(tmp_len);
memcpy(tmp, (*pphar)->alias, (*pphar)->alias_len);
if (data) {
memcpy(tmp + (*pphar)->alias_len, data->filename, data->filename_len);
} else {
*(tmp + (*pphar)->alias_len) = '/';
}
/* this is only for APC, so use /dev/null device - no chance of conflict there! */
sb.st_dev = 0xc;
/* generate unique inode number for alias/filename, so no phars will conflict */
sb.st_ino = (unsigned short)zend_get_hash_value(tmp, tmp_len);
efree(tmp);
if (data) {
sb.st_ino = data->inode;
}
#ifndef PHP_WIN32
sb.st_blksize = -1;
sb.st_blocks = -1;
@ -904,20 +897,19 @@ PHAR_FUNC(phar_is_file) /* {{{ */
}
fname_len = strlen(fname);
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
phar_archive_data **pphar;
phar_archive_data *phar;
efree(entry);
entry = filename;
/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
entry_len = filename_len;
/* retrieving a file within the current directory, so use this if possible */
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar)))
|| (PHAR_G(manifest_cached) && SUCCESS == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) {
if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
phar_entry_info *etemp;
entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
if (entry[0] == '/') {
if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry + 1, entry_len - 1, (void **) &etemp)) {
if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &etemp)) {
/* this file is not in the current directory, use the original path */
found_it:
efree(entry);
@ -925,7 +917,7 @@ found_it:
RETURN_BOOL(!etemp->is_dir);
}
} else {
if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) &etemp)) {
if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &etemp)) {
goto found_it;
}
}
@ -966,20 +958,19 @@ PHAR_FUNC(phar_is_link) /* {{{ */
}
fname_len = strlen(fname);
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
phar_archive_data **pphar;
phar_archive_data *phar;
efree(entry);
entry = filename;
/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
entry_len = filename_len;
/* retrieving a file within the current directory, so use this if possible */
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar)))
|| (PHAR_G(manifest_cached) && SUCCESS == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) {
if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
phar_entry_info *etemp;
entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
if (entry[0] == '/') {
if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry + 1, entry_len - 1, (void **) &etemp)) {
if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &etemp)) {
/* this file is not in the current directory, use the original path */
found_it:
efree(entry);
@ -987,7 +978,7 @@ found_it:
RETURN_BOOL(etemp->link);
}
} else {
if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) &etemp)) {
if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &etemp)) {
goto found_it;
}
}

View File

@ -267,6 +267,9 @@ int phar_archive_delref(phar_archive_data *phar TSRMLS_DC) /* {{{ */
}
return 1;
} else if (!phar->refcount) {
/* invalidate phar cache */
PHAR_G(last_phar) = NULL;
PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
if (phar->fp && !(phar->flags & PHAR_FILE_COMPRESSION_MASK)) {
/* close open file handle - allows removal or rename of
the file on windows, which has greedy locking
@ -1613,6 +1616,11 @@ static int phar_analyze_path(const char *fname, const char *ext, int ext_len, in
efree(realpath);
return SUCCESS;
}
if (PHAR_G(manifest_cached) && zend_hash_exists(&cached_phars, realpath, strlen(realpath))) {
*a = old;
efree(realpath);
return SUCCESS;
}
efree(realpath);
}
if (SUCCESS == php_stream_stat_path((char *) fname, &ssb)) {
@ -1746,9 +1754,14 @@ int phar_detect_phar_fname_ext(const char *filename, int filename_len, const cha
*ext_len = -1;
return FAILURE;
}
if (PHAR_G(manifest_cached) && zend_hash_exists(&cached_alias, (char *) filename, pos - filename)) {
*ext_str = pos;
*ext_len = -1;
return FAILURE;
}
}
if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) {
if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)) || PHAR_G(manifest_cached)) {
phar_archive_data **pphar;
if (is_complete) {
@ -1767,6 +1780,10 @@ woohoo:
}
return FAILURE;
}
if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, (char *) filename, filename_len, (void **)&pphar)) {
*ext_str = filename + (filename_len - (*pphar)->ext_len);
goto woohoo;
}
} else {
phar_zstr key;
char *str_key;
@ -1795,6 +1812,30 @@ woohoo:
}
zend_hash_move_forward(&(PHAR_GLOBALS->phar_fname_map));
}
if (PHAR_G(manifest_cached)) {
zend_hash_internal_pointer_reset(&cached_phars);
while (FAILURE != zend_hash_has_more_elements(&cached_phars)) {
if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(&cached_phars, &key, &keylen, &unused, 0, NULL)) {
break;
}
PHAR_STR(key, str_key);
if (keylen > (uint) filename_len) {
zend_hash_move_forward(&cached_phars);
continue;
}
if (!memcmp(filename, str_key, keylen) && ((uint)filename_len == keylen
|| filename[keylen] == '/' || filename[keylen] == '\0')) {
if (FAILURE == zend_hash_get_current_data(&cached_phars, (void **) &pphar)) {
break;
}
*ext_str = filename + (keylen - (*pphar)->ext_len);
goto woohoo;
}
zend_hash_move_forward(&cached_phars);
}
}
}
}
@ -3205,6 +3246,9 @@ int phar_zend_open(const char *filename, zend_file_handle *handle TSRMLS_DC) /*
if (fname_len > 7 && !strncasecmp(fname, "phar://", 7)) {
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 1, 0 TSRMLS_CC)) {
zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar);
if (!pphar && PHAR_G(manifest_cached)) {
zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar);
}
efree(arch);
efree(entry);
}
@ -3281,6 +3325,8 @@ void phar_request_initialize(TSRMLS_D) /* {{{ */
{
if (!PHAR_GLOBALS->request_init)
{
PHAR_G(last_phar) = NULL;
PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
PHAR_G(has_bz2) = zend_hash_exists(&module_registry, "bz2", sizeof("bz2"));
PHAR_G(has_zlib) = zend_hash_exists(&module_registry, "zlib", sizeof("zlib"));
PHAR_GLOBALS->request_init = 1;

Binary file not shown.

View File

@ -137,6 +137,7 @@
#define TAR_NEW '8'
typedef struct _phar_entry_fp phar_entry_fp;
typedef struct _phar_archive_data phar_archive_data;
ZEND_BEGIN_MODULE_GLOBALS(phar)
HashTable phar_fname_map;
@ -184,6 +185,12 @@ ZEND_BEGIN_MODULE_GLOBALS(phar)
int cwd_init;
char *openssl_privatekey;
int openssl_privatekey_len;
/* phar_get_archive cache */
char* last_phar_name;
int last_phar_name_len;
char* last_alias;
int last_alias_len;
phar_archive_data* last_phar;
ZEND_END_MODULE_GLOBALS(phar)
ZEND_EXTERN_MODULE_GLOBALS(phar)
@ -226,8 +233,6 @@ enum phar_fp_type {
PHAR_TMP
};
typedef struct _phar_archive_data phar_archive_data;
/* entry for one file in a phar file */
typedef struct _phar_entry_info {
/* first bytes are exactly as in file */

View File

@ -473,6 +473,11 @@ PHP_METHOD(Phar, mount)
}
carry_on2:
if (SUCCESS != zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **)&pphar)) {
if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, arch, arch_len, (void **)&pphar)) {
if (SUCCESS == phar_copy_on_write(pphar)) {
goto carry_on;
}
}
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s is not a phar archive, cannot mount", arch);
if (arch) {
efree(arch);
@ -499,6 +504,11 @@ carry_on:
return;
} else if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void **)&pphar)) {
goto carry_on;
} else if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, fname, fname_len, (void **)&pphar)) {
if (SUCCESS == phar_copy_on_write(pphar)) {
goto carry_on;
}
goto carry_on;
} else if (SUCCESS == phar_split_fname(path, path_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
path = entry;
path_len = entry_len;
@ -1334,6 +1344,10 @@ PHP_METHOD(Phar, unlinkArchive)
return;
}
fname = estrndup(phar->fname, phar->fname_len);
/* invalidate phar cache */
PHAR_G(last_phar) = NULL;
PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
phar_archive_delref(phar TSRMLS_CC);
unlink(fname);
efree(fname);
@ -2042,6 +2056,10 @@ static zval *phar_convert_to_other(phar_archive_data *source, int convert, char
phar_entry_info *entry, newentry;
zval *ret;
/* invalidate phar cache */
PHAR_G(last_phar) = NULL;
PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
phar = (phar_archive_data *) ecalloc(1, sizeof(phar_archive_data));
/* set whole-archive compression and type from parameter */
phar->flags = flags;
@ -2468,6 +2486,9 @@ PHP_METHOD(Phar, setAlias)
"Cannot write out phar archive, phar is read-only");
RETURN_FALSE;
}
/* invalidate phar cache */
PHAR_G(last_phar) = NULL;
PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
if (phar_obj->arc.archive->is_data) {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,

View File

@ -237,9 +237,12 @@ char *phar_find_in_include_path(char *filename, int filename_len, phar_archive_d
#if PHP_VERSION_ID >= 50300
char *path, *fname, *arch, *entry, *ret, *test;
int arch_len, entry_len, fname_len;
phar_archive_data *phar;
if (pphar) {
*pphar = NULL;
} else {
pphar = &phar;
}
if (!zend_is_executing(TSRMLS_C) || !PHAR_G(cwd)) {
@ -255,22 +258,24 @@ char *phar_find_in_include_path(char *filename, int filename_len, phar_archive_d
if (*filename == '.') {
int try_len;
if (SUCCESS != zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar) &&
PHAR_G(manifest_cached) && SUCCESS != zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)) {
if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
efree(arch);
return phar_save_resolve_path(filename, filename_len TSRMLS_CC);
}
if (pphar) {
*pphar = phar;
}
try_len = filename_len;
test = phar_fix_filepath(estrndup(filename, filename_len), &try_len, 1 TSRMLS_CC);
if (*test == '/') {
if (zend_hash_exists(&((*pphar)->manifest), test + 1, try_len - 1)) {
if (zend_hash_exists(&(phar->manifest), test + 1, try_len - 1)) {
spprintf(&ret, 0, "phar://%s%s", arch, test);
efree(arch);
efree(test);
return ret;
}
} else {
if (zend_hash_exists(&((*pphar)->manifest), test, try_len)) {
if (zend_hash_exists(&(phar->manifest), test, try_len)) {
spprintf(&ret, 0, "phar://%s/%s", arch, test);
efree(arch);
efree(test);
@ -293,6 +298,9 @@ char *phar_find_in_include_path(char *filename, int filename_len, phar_archive_d
return ret;
}
zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar);
if (!pphar && PHAR_G(manifest_cached)) {
zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar);
}
efree(arch);
efree(entry);
}
@ -324,7 +332,7 @@ char *phar_find_in_include_path(char *filename, int filename_len, phar_archive_d
phar_archive_data **pphar;
int try_len;
if (SUCCESS != (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) {
if (FAILURE == phar_get_archive(pphar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
efree(arch);
goto doit;
}
@ -441,6 +449,9 @@ not_stream:
return estrndup(trypath, ret_len);
}
zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar);
if (!pphar && PHAR_G(manifest_cached)) {
zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar);
}
efree(arch);
efree(entry);
return estrndup(trypath, ret_len);
@ -1042,6 +1053,9 @@ int phar_free_alias(phar_archive_data *phar, char *alias, int alias_len TSRMLS_D
if (zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), phar->fname, phar->fname_len) != SUCCESS) {
return FAILURE;
}
/* invalidate phar cache */
PHAR_G(last_phar) = NULL;
PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
return SUCCESS;
}
/* }}} */
@ -1063,6 +1077,30 @@ int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, ch
*error = NULL;
}
*archive = NULL;
if (PHAR_G(last_phar) && fname_len == PHAR_G(last_phar_name_len) && !memcmp(fname, PHAR_G(last_phar_name), fname_len)) {
*archive = PHAR_G(last_phar);
if (alias && alias_len) {
if (!PHAR_G(last_phar)->is_temporary_alias && (alias_len != PHAR_G(last_phar)->alias_len || memcmp(PHAR_G(last_phar)->alias, alias, alias_len))) {
if (error) {
spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, PHAR_G(last_phar)->fname, fname);
}
*archive = NULL;
return FAILURE;
}
if (PHAR_G(last_phar)->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len, (void**)&fd_ptr)) {
zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len);
}
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&(*archive), sizeof(phar_archive_data*), NULL);
PHAR_G(last_alias) = alias;
PHAR_G(last_alias_len) = alias_len;
}
return SUCCESS;
}
if (alias && alias_len && PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) {
fd = PHAR_G(last_phar);
fd_ptr = &fd;
goto alias_success;
}
if (alias && alias_len) {
ahash = zend_inline_hash_func(alias, alias_len);
if (SUCCESS == zend_hash_quick_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, ahash, (void**)&fd_ptr)) {
@ -1078,6 +1116,12 @@ alias_success:
return FAILURE;
}
*archive = *fd_ptr;
fd = *fd_ptr;
PHAR_G(last_phar) = fd;
PHAR_G(last_phar_name) = fd->fname;
PHAR_G(last_phar_name_len) = fd->fname_len;
PHAR_G(last_alias) = alias;
PHAR_G(last_alias_len) = alias_len;
return SUCCESS;
}
if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_alias, alias, alias_len, ahash, (void **)&fd_ptr)) {
@ -1104,6 +1148,11 @@ alias_success:
}
zend_hash_quick_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, ahash, (void*)&fd, sizeof(phar_archive_data*), NULL);
}
PHAR_G(last_phar) = fd;
PHAR_G(last_phar_name) = fd->fname;
PHAR_G(last_phar_name_len) = fd->fname_len;
PHAR_G(last_alias) = fd->alias;
PHAR_G(last_alias_len) = fd->alias_len;
return SUCCESS;
}
if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_phars, fname, fname_len, fhash, (void**)&fd_ptr)) {
@ -1119,14 +1168,29 @@ alias_success:
return FAILURE;
}
}
PHAR_G(last_phar) = fd;
PHAR_G(last_phar_name) = fd->fname;
PHAR_G(last_phar_name_len) = fd->fname_len;
PHAR_G(last_alias) = fd->alias;
PHAR_G(last_alias_len) = fd->alias_len;
return SUCCESS;
}
if (SUCCESS == zend_hash_quick_find(&(PHAR_GLOBALS->phar_alias_map), save, save_len, fhash, (void**)&fd_ptr)) {
*archive = *fd_ptr;
fd = *archive = *fd_ptr;
PHAR_G(last_phar) = fd;
PHAR_G(last_phar_name) = fd->fname;
PHAR_G(last_phar_name_len) = fd->fname_len;
PHAR_G(last_alias) = fd->alias;
PHAR_G(last_alias_len) = fd->alias_len;
return SUCCESS;
}
if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_alias, save, save_len, fhash, (void**)&fd_ptr)) {
*archive = *fd_ptr;
fd = *archive = *fd_ptr;
PHAR_G(last_phar) = fd;
PHAR_G(last_phar_name) = fd->fname;
PHAR_G(last_phar_name_len) = fd->fname_len;
PHAR_G(last_alias) = fd->alias;
PHAR_G(last_alias_len) = fd->alias_len;
return SUCCESS;
}
@ -1150,6 +1214,11 @@ realpath_success:
zend_hash_quick_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, ahash, (void*)&fd, sizeof(phar_archive_data*), NULL);
}
efree(my_realpath);
PHAR_G(last_phar) = fd;
PHAR_G(last_phar_name) = fd->fname;
PHAR_G(last_phar_name_len) = fd->fname_len;
PHAR_G(last_alias) = fd->alias;
PHAR_G(last_alias_len) = fd->alias_len;
return SUCCESS;
}
if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_phars, fname, fname_len, fhash, (void**)&fd_ptr)) {
@ -2025,6 +2094,9 @@ int phar_copy_on_write(phar_archive_data **pphar TSRMLS_DC) /* {{{ */
*newpphar = *pphar;
phar_copy_cached_phar(newpphar TSRMLS_CC);
/* invalidate phar cache */
PHAR_G(last_phar) = NULL;
PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
if (newpphar[0]->alias_len && FAILURE == zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), newpphar[0]->alias, newpphar[0]->alias_len, (void*)newpphar, sizeof(phar_archive_data*), NULL)) {
zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), (*pphar)->fname, (*pphar)->fname_len);
return FAILURE;