Skip to content

Commit a72778b

Browse files
committed
ext/phar: Prevent unnecessary known string length computation
Closes GH-11033
1 parent b9af980 commit a72778b

File tree

4 files changed

+81
-74
lines changed

4 files changed

+81
-74
lines changed

ext/phar/func_interceptors.c

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,17 @@ PHAR_FUNC(phar_opendir) /* {{{ */
4141
}
4242

4343
if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
44-
char *arch, *entry, *fname;
45-
size_t arch_len, entry_len, fname_len;
46-
fname = (char*)zend_get_executed_filename();
44+
char *arch, *entry;
45+
size_t arch_len, entry_len;
46+
zend_string *fname = zend_get_executed_filename_ex();
4747

4848
/* we are checking for existence of a file within the relative path. Chances are good that this is
4949
retrieving something from within the phar archive */
50-
51-
if (strncasecmp(fname, "phar://", 7)) {
50+
if (!zend_string_starts_with_literal_ci(fname, "phar://")) {
5251
goto skip_phar;
5352
}
54-
fname_len = strlen(fname);
55-
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) {
53+
54+
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) {
5655
php_stream_context *context = NULL;
5756
php_stream *stream;
5857
char *name;
@@ -91,15 +90,17 @@ PHAR_FUNC(phar_opendir) /* {{{ */
9190

9291
static zend_string* phar_get_name_for_relative_paths(zend_string *filename, bool using_include_path)
9392
{
94-
char *arch, *entry, *fname;
95-
size_t arch_len, entry_len, fname_len;
93+
char *arch, *entry;
94+
size_t arch_len, entry_len;
95+
zend_string *fname = zend_get_executed_filename_ex();
9696

97-
fname = (char*)zend_get_executed_filename();
98-
if (strncasecmp(fname, "phar://", 7)) {
97+
/* we are checking for existence of a file within the relative path. Chances are good that this is
98+
retrieving something from within the phar archive */
99+
if (!zend_string_starts_with_literal_ci(fname, "phar://")) {
99100
return NULL;
100101
}
101-
fname_len = strlen(fname);
102-
if (FAILURE == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) {
102+
103+
if (FAILURE == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) {
103104
return NULL;
104105
}
105106

@@ -485,22 +486,22 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ
485486
}
486487

487488
if (!IS_ABSOLUTE_PATH(filename, filename_length) && !strstr(filename, "://")) {
488-
char *arch, *entry, *fname;
489-
size_t arch_len, entry_len, fname_len;
489+
char *arch, *entry;
490+
size_t arch_len, entry_len;
491+
zend_string *fname;
490492
zend_stat_t sb = {0};
491493
phar_entry_info *data = NULL;
492494
phar_archive_data *phar;
493495

494-
fname = (char*)zend_get_executed_filename();
496+
fname = zend_get_executed_filename_ex();
495497

496498
/* we are checking for existence of a file within the relative path. Chances are good that this is
497499
retrieving something from within the phar archive */
498-
499-
if (strncasecmp(fname, "phar://", 7)) {
500+
if (!zend_string_starts_with_literal_ci(fname, "phar://")) {
500501
goto skip_phar;
501502
}
502-
fname_len = strlen(fname);
503-
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))) {
503+
504+
if (PHAR_G(last_phar) && ZSTR_LEN(fname) - 7 >= PHAR_G(last_phar_name_len) && !memcmp(ZSTR_VAL(fname) + 7, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))) {
504505
arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len));
505506
arch_len = PHAR_G(last_phar_name_len);
506507
entry = estrndup(filename, filename_length);
@@ -509,7 +510,7 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ
509510
phar = PHAR_G(last_phar);
510511
goto splitted;
511512
}
512-
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) {
513+
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) {
513514

514515
efree(entry);
515516
entry = estrndup(filename, filename_length);
@@ -741,18 +742,17 @@ PHAR_FUNC(phar_is_file) /* {{{ */
741742
goto skip_phar;
742743
}
743744
if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
744-
char *arch, *entry, *fname;
745-
size_t arch_len, entry_len, fname_len;
746-
fname = (char*)zend_get_executed_filename();
745+
char *arch, *entry;
746+
size_t arch_len, entry_len;
747+
zend_string *fname = zend_get_executed_filename_ex();
747748

748749
/* we are checking for existence of a file within the relative path. Chances are good that this is
749750
retrieving something from within the phar archive */
750-
751-
if (strncasecmp(fname, "phar://", 7)) {
751+
if (!zend_string_starts_with_literal_ci(fname, "phar://")) {
752752
goto skip_phar;
753753
}
754-
fname_len = strlen(fname);
755-
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) {
754+
755+
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) {
756756
phar_archive_data *phar;
757757

758758
efree(entry);
@@ -808,18 +808,17 @@ PHAR_FUNC(phar_is_link) /* {{{ */
808808
goto skip_phar;
809809
}
810810
if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
811-
char *arch, *entry, *fname;
812-
size_t arch_len, entry_len, fname_len;
813-
fname = (char*)zend_get_executed_filename();
811+
char *arch, *entry;
812+
size_t arch_len, entry_len;
813+
zend_string *fname = zend_get_executed_filename_ex();
814814

815815
/* we are checking for existence of a file within the relative path. Chances are good that this is
816816
retrieving something from within the phar archive */
817-
818-
if (strncasecmp(fname, "phar://", 7)) {
817+
if (!zend_string_starts_with_literal_ci(fname, "phar://")) {
819818
goto skip_phar;
820819
}
821-
fname_len = strlen(fname);
822-
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) {
820+
821+
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) {
823822
phar_archive_data *phar;
824823

825824
efree(entry);

ext/phar/phar.c

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,24 +2318,17 @@ int phar_split_fname(const char *filename, size_t filename_len, char **arch, siz
23182318
*/
23192319
int phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* {{{ */
23202320
{
2321-
char *fname;
2322-
php_stream *fp;
2323-
size_t fname_len;
2324-
zend_string *actual = NULL;
2325-
int ret;
2326-
23272321
if (error) {
23282322
*error = NULL;
23292323
}
23302324

2331-
fname = (char*)zend_get_executed_filename();
2332-
fname_len = strlen(fname);
2325+
zend_string *fname = zend_get_executed_filename_ex();
23332326

2334-
if (phar_open_parsed_phar(fname, fname_len, alias, alias_len, 0, REPORT_ERRORS, NULL, 0) == SUCCESS) {
2327+
if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, 0, REPORT_ERRORS, NULL, 0) == SUCCESS) {
23352328
return SUCCESS;
23362329
}
23372330

2338-
if (!strcmp(fname, "[no active file]")) {
2331+
if (zend_string_equals_literal(fname, "[no active file]")) {
23392332
if (error) {
23402333
spprintf(error, 0, "cannot initialize a phar outside of PHP execution");
23412334
}
@@ -2349,15 +2342,17 @@ int phar_open_executed_filename(char *alias, size_t alias_len, char **error) /*
23492342
return FAILURE;
23502343
}
23512344

2352-
if (php_check_open_basedir(fname)) {
2345+
if (php_check_open_basedir(ZSTR_VAL(fname))) {
23532346
return FAILURE;
23542347
}
23552348

2356-
fp = php_stream_open_wrapper(fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, &actual);
2349+
zend_string *actual = NULL;
2350+
php_stream *fp;
2351+
fp = php_stream_open_wrapper(ZSTR_VAL(fname), "rb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, &actual);
23572352

23582353
if (!fp) {
23592354
if (error) {
2360-
spprintf(error, 0, "unable to open phar for reading \"%s\"", fname);
2355+
spprintf(error, 0, "unable to open phar for reading \"%s\"", ZSTR_VAL(fname));
23612356
}
23622357
if (actual) {
23632358
zend_string_release_ex(actual, 0);
@@ -2366,11 +2361,10 @@ int phar_open_executed_filename(char *alias, size_t alias_len, char **error) /*
23662361
}
23672362

23682363
if (actual) {
2369-
fname = ZSTR_VAL(actual);
2370-
fname_len = ZSTR_LEN(actual);
2364+
fname = actual;
23712365
}
23722366

2373-
ret = phar_open_from_fp(fp, fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, 0, error);
2367+
int ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, REPORT_ERRORS, NULL, 0, error);
23742368

23752369
if (actual) {
23762370
zend_string_release_ex(actual, 0);

ext/phar/phar_object.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -392,21 +392,24 @@ static void phar_postprocess_ru_web(char *fname, size_t fname_len, char **entry,
392392
*/
393393
PHP_METHOD(Phar, running)
394394
{
395-
char *fname, *arch, *entry;
396-
size_t fname_len, arch_len, entry_len;
395+
zend_string *fname;
396+
char *arch, *entry;
397+
size_t arch_len, entry_len;
397398
bool retphar = 1;
398399

399400
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &retphar) == FAILURE) {
400401
RETURN_THROWS();
401402
}
402403

403-
fname = (char*)zend_get_executed_filename();
404-
fname_len = strlen(fname);
404+
fname = zend_get_executed_filename_ex();
405405

406-
if (fname_len > 7 && !memcmp(fname, "phar://", 7) && SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) {
406+
if (
407+
zend_string_starts_with_literal_ci(fname, "phar://")
408+
&& SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)
409+
) {
407410
efree(entry);
408411
if (retphar) {
409-
RETVAL_STRINGL(fname, arch_len + 7);
412+
RETVAL_STRINGL(ZSTR_VAL(fname), arch_len + 7);
410413
efree(arch);
411414
return;
412415
} else {
@@ -441,8 +444,9 @@ PHP_METHOD(Phar, mount)
441444
RETURN_THROWS();
442445
}
443446

444-
fname = (char*)zend_get_executed_filename();
445-
fname_len = strlen(fname);
447+
zend_string *zend_file_name = zend_get_executed_filename_ex();
448+
fname = ZSTR_VAL(zend_file_name);
449+
fname_len = ZSTR_LEN(zend_file_name);
446450

447451
#ifdef PHP_WIN32
448452
save_fname = fname;
@@ -556,8 +560,6 @@ PHP_METHOD(Phar, webPhar)
556560
}
557561

558562
phar_request_initialize();
559-
fname = (char*)zend_get_executed_filename();
560-
fname_len = strlen(fname);
561563

562564
if (phar_open_executed_filename(alias, alias_len, &error) != SUCCESS) {
563565
if (error) {
@@ -583,6 +585,10 @@ PHP_METHOD(Phar, webPhar)
583585
return;
584586
}
585587

588+
zend_string *zend_file_name = zend_get_executed_filename_ex();
589+
fname = ZSTR_VAL(zend_file_name);
590+
fname_len = ZSTR_LEN(zend_file_name);
591+
586592
#ifdef PHP_WIN32
587593
if (memchr(fname, '\\', fname_len)) {
588594
fname = estrndup(fname, fname_len);
@@ -1274,9 +1280,9 @@ PHP_METHOD(Phar, getSupportedCompression)
12741280
/* {{{ Completely remove a phar archive from memory and disk */
12751281
PHP_METHOD(Phar, unlinkArchive)
12761282
{
1277-
char *fname, *error, *zname, *arch, *entry;
1283+
char *fname, *error, *arch, *entry;
12781284
size_t fname_len;
1279-
size_t zname_len, arch_len, entry_len;
1285+
size_t arch_len, entry_len;
12801286
phar_archive_data *phar;
12811287

12821288
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) {
@@ -1298,11 +1304,13 @@ PHP_METHOD(Phar, unlinkArchive)
12981304
RETURN_THROWS();
12991305
}
13001306

1301-
zname = (char*)zend_get_executed_filename();
1302-
zname_len = strlen(zname);
1307+
zend_string *zend_file_name = zend_get_executed_filename_ex();
13031308

1304-
if (zname_len > 7 && !memcmp(zname, "phar://", 7) && SUCCESS == phar_split_fname(zname, zname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) {
1305-
if ((size_t)arch_len == fname_len && !memcmp(arch, fname, arch_len)) {
1309+
if (
1310+
zend_string_starts_with_literal_ci(zend_file_name, "phar://")
1311+
&& SUCCESS == phar_split_fname(ZSTR_VAL(zend_file_name), ZSTR_LEN(zend_file_name), &arch, &arch_len, &entry, &entry_len, 2, 0)
1312+
) {
1313+
if (arch_len == fname_len && !memcmp(arch, fname, arch_len)) {
13061314
zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" cannot be unlinked from within itself", fname);
13071315
efree(arch);
13081316
efree(entry);

ext/phar/util.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_le
242242
zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data **pphar) /* {{{ */
243243
{
244244
zend_string *ret;
245-
char *path, *fname, *arch, *entry, *test;
246-
size_t arch_len, entry_len, fname_len;
245+
char *path, *arch, *entry, *test;
246+
size_t arch_len, entry_len;
247247
phar_archive_data *phar;
248248

249249
if (pphar) {
@@ -256,17 +256,23 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data
256256
return NULL;
257257
}
258258

259-
fname = (char*)zend_get_executed_filename();
260-
fname_len = strlen(fname);
259+
zend_string *fname = zend_get_executed_filename_ex();
260+
bool is_file_a_phar_wrapper = zend_string_starts_with_literal_ci(fname, "phar://");
261+
size_t length_phar_protocol = strlen("phar://");
261262

262-
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))) {
263+
if (
264+
PHAR_G(last_phar)
265+
&& is_file_a_phar_wrapper
266+
&& ZSTR_LEN(fname) - length_phar_protocol >= PHAR_G(last_phar_name_len)
267+
&& !memcmp(ZSTR_VAL(fname) + length_phar_protocol, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))
268+
) {
263269
arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len));
264270
arch_len = PHAR_G(last_phar_name_len);
265271
phar = PHAR_G(last_phar);
266272
goto splitted;
267273
}
268274

269-
if (fname_len < 7 || memcmp(fname, "phar://", 7) || SUCCESS != phar_split_fname(fname, strlen(fname), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
275+
if (!is_file_a_phar_wrapper || SUCCESS != phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
270276
return NULL;
271277
}
272278

@@ -310,7 +316,7 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data
310316
ret = php_resolve_path(ZSTR_VAL(filename), ZSTR_LEN(filename), path);
311317
efree(path);
312318

313-
if (ret && ZSTR_LEN(ret) > 8 && !strncmp(ZSTR_VAL(ret), "phar://", 7)) {
319+
if (ret && zend_string_starts_with_literal_ci(ret, "phar://")) {
314320
/* found phar:// */
315321
if (SUCCESS != phar_split_fname(ZSTR_VAL(ret), ZSTR_LEN(ret), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
316322
return ret;

0 commit comments

Comments
 (0)