-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ext/phar: Refactor Phar to prevent unnecessary strlen() computations #11033
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -392,21 +392,24 @@ static void phar_postprocess_ru_web(char *fname, size_t fname_len, char **entry, | |
*/ | ||
PHP_METHOD(Phar, running) | ||
{ | ||
char *fname, *arch, *entry; | ||
size_t fname_len, arch_len, entry_len; | ||
zend_string *fname; | ||
char *arch, *entry; | ||
size_t arch_len, entry_len; | ||
bool retphar = 1; | ||
|
||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &retphar) == FAILURE) { | ||
RETURN_THROWS(); | ||
} | ||
|
||
fname = (char*)zend_get_executed_filename(); | ||
fname_len = strlen(fname); | ||
fname = zend_get_executed_filename_ex(); | ||
|
||
if (fname_len > 7 && !memcmp(fname, "phar://", 7) && SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) { | ||
if ( | ||
zend_string_starts_with_literal_ci(fname, "phar://") | ||
&& SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0) | ||
) { | ||
efree(entry); | ||
if (retphar) { | ||
RETVAL_STRINGL(fname, arch_len + 7); | ||
RETVAL_STRINGL(ZSTR_VAL(fname), arch_len + 7); | ||
efree(arch); | ||
return; | ||
} else { | ||
|
@@ -441,8 +444,9 @@ PHP_METHOD(Phar, mount) | |
RETURN_THROWS(); | ||
} | ||
|
||
fname = (char*)zend_get_executed_filename(); | ||
fname_len = strlen(fname); | ||
zend_string *zend_file_name = zend_get_executed_filename_ex(); | ||
fname = ZSTR_VAL(zend_file_name); | ||
fname_len = ZSTR_LEN(zend_file_name); | ||
|
||
#ifdef PHP_WIN32 | ||
save_fname = fname; | ||
|
@@ -482,15 +486,6 @@ PHP_METHOD(Phar, mount) | |
carry_on: | ||
if (SUCCESS != phar_mount_entry(pphar, actual, actual_len, path, path_len)) { | ||
zend_throw_exception_ex(phar_ce_PharException, 0, "Mounting of %s to %s within phar %s failed", path, actual, arch); | ||
if (path && path == entry) { | ||
efree(entry); | ||
} | ||
|
||
if (arch) { | ||
efree(arch); | ||
} | ||
|
||
goto finish; | ||
Comment on lines
-485
to
-493
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this is removed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code outside the if branch is equivalent to this and performs the necessary clean-up and then jumps to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, I see |
||
} | ||
|
||
if (entry && path && path == entry) { | ||
|
@@ -556,8 +551,6 @@ PHP_METHOD(Phar, webPhar) | |
} | ||
|
||
phar_request_initialize(); | ||
fname = (char*)zend_get_executed_filename(); | ||
fname_len = strlen(fname); | ||
|
||
if (phar_open_executed_filename(alias, alias_len, &error) != SUCCESS) { | ||
if (error) { | ||
|
@@ -583,6 +576,10 @@ PHP_METHOD(Phar, webPhar) | |
return; | ||
} | ||
|
||
zend_string *zend_file_name = zend_get_executed_filename_ex(); | ||
fname = ZSTR_VAL(zend_file_name); | ||
fname_len = ZSTR_LEN(zend_file_name); | ||
|
||
#ifdef PHP_WIN32 | ||
if (memchr(fname, '\\', fname_len)) { | ||
fname = estrndup(fname, fname_len); | ||
|
@@ -1274,9 +1271,9 @@ PHP_METHOD(Phar, getSupportedCompression) | |
/* {{{ Completely remove a phar archive from memory and disk */ | ||
PHP_METHOD(Phar, unlinkArchive) | ||
{ | ||
char *fname, *error, *zname, *arch, *entry; | ||
char *fname, *error, *arch, *entry; | ||
size_t fname_len; | ||
size_t zname_len, arch_len, entry_len; | ||
size_t arch_len, entry_len; | ||
phar_archive_data *phar; | ||
|
||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { | ||
|
@@ -1298,11 +1295,13 @@ PHP_METHOD(Phar, unlinkArchive) | |
RETURN_THROWS(); | ||
} | ||
|
||
zname = (char*)zend_get_executed_filename(); | ||
zname_len = strlen(zname); | ||
zend_string *zend_file_name = zend_get_executed_filename_ex(); | ||
|
||
if (zname_len > 7 && !memcmp(zname, "phar://", 7) && SUCCESS == phar_split_fname(zname, zname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) { | ||
if ((size_t)arch_len == fname_len && !memcmp(arch, fname, arch_len)) { | ||
if ( | ||
zend_string_starts_with_literal_ci(zend_file_name, "phar://") | ||
&& SUCCESS == phar_split_fname(ZSTR_VAL(zend_file_name), ZSTR_LEN(zend_file_name), &arch, &arch_len, &entry, &entry_len, 2, 0) | ||
) { | ||
if (arch_len == fname_len && !memcmp(arch, fname, arch_len)) { | ||
zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" cannot be unlinked from within itself", fname); | ||
efree(arch); | ||
efree(entry); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -242,8 +242,8 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_le | |
zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data **pphar) /* {{{ */ | ||
{ | ||
zend_string *ret; | ||
char *path, *fname, *arch, *entry, *test; | ||
size_t arch_len, entry_len, fname_len; | ||
char *path, *arch, *entry, *test; | ||
size_t arch_len, entry_len; | ||
phar_archive_data *phar; | ||
|
||
if (pphar) { | ||
|
@@ -256,17 +256,23 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data | |
return NULL; | ||
} | ||
|
||
fname = (char*)zend_get_executed_filename(); | ||
fname_len = strlen(fname); | ||
zend_string *fname = zend_get_executed_filename_ex(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Contrary to |
||
bool is_file_a_phar_wrapper = zend_string_starts_with_literal_ci(fname, "phar://"); | ||
size_t length_phar_protocol = strlen("phar://"); | ||
|
||
if (PHAR_G(last_phar) && !memcmp(fname, "phar://", 7) && fname_len - 7 >= PHAR_G(last_phar_name_len) && !memcmp(fname + 7, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))) { | ||
if ( | ||
PHAR_G(last_phar) | ||
&& is_file_a_phar_wrapper | ||
&& ZSTR_LEN(fname) - length_phar_protocol >= PHAR_G(last_phar_name_len) | ||
&& !memcmp(ZSTR_VAL(fname) + length_phar_protocol, 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); | ||
phar = PHAR_G(last_phar); | ||
goto splitted; | ||
} | ||
|
||
if (fname_len < 7 || memcmp(fname, "phar://", 7) || SUCCESS != phar_split_fname(fname, strlen(fname), &arch, &arch_len, &entry, &entry_len, 1, 0)) { | ||
if (!is_file_a_phar_wrapper || SUCCESS != phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 1, 0)) { | ||
return NULL; | ||
} | ||
|
||
|
@@ -310,7 +316,7 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data | |
ret = php_resolve_path(ZSTR_VAL(filename), ZSTR_LEN(filename), path); | ||
efree(path); | ||
|
||
if (ret && ZSTR_LEN(ret) > 8 && !strncmp(ZSTR_VAL(ret), "phar://", 7)) { | ||
if (ret && zend_string_starts_with_literal_ci(ret, "phar://")) { | ||
/* found phar:// */ | ||
if (SUCCESS != phar_split_fname(ZSTR_VAL(ret), ZSTR_LEN(ret), &arch, &arch_len, &entry, &entry_len, 1, 0)) { | ||
return ret; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This no longer makes sense, this string is only returned in
zend_get_executed_filename()
. This would now returnNULL
(and thus already segfault above).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah indeed, surprised we don't have a test for that... AFAIK this only happens with
eval()
?