mirror of
https://github.com/php/php-src.git
synced 2024-09-22 10:27:25 +00:00
making progress - up to 42/phar vs. 48/disk with these optimizations
This commit is contained in:
parent
5233505043
commit
7cc6b9f3f5
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user