Skip to content

Commit 3b54fa4

Browse files
authored
Make entry argument nullable for phar_split_fname() to avoid extra allocations (#20146)
1 parent 7fbf9b8 commit 3b54fa4

File tree

5 files changed

+38
-53
lines changed

5 files changed

+38
-53
lines changed

ext/phar/dirstream.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,12 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo
349349
{
350350
phar_entry_info entry, *e;
351351
phar_archive_data *phar = NULL;
352-
char *error, *arch, *entry2;
353-
size_t arch_len, entry_len;
352+
char *error, *arch;
353+
size_t arch_len;
354354
php_url *resource = NULL;
355355

356356
/* pre-readonly check, we need to know if this is a data phar */
357-
if (FAILURE == phar_split_fname(url_from, strlen(url_from), &arch, &arch_len, &entry2, &entry_len, 2, 2)) {
357+
if (FAILURE == phar_split_fname(url_from, strlen(url_from), &arch, &arch_len, NULL, NULL, 2, 2)) {
358358
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\", no phar archive specified", url_from);
359359
return 0;
360360
}
@@ -364,7 +364,6 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo
364364
}
365365

366366
efree(arch);
367-
efree(entry2);
368367

369368
if (PHAR_G(readonly) && (!phar || !phar->is_data)) {
370369
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\", write operations disabled", url_from);
@@ -477,12 +476,12 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
477476
{
478477
phar_entry_info *entry;
479478
phar_archive_data *phar = NULL;
480-
char *error, *arch, *entry2;
481-
size_t arch_len, entry_len;
479+
char *error, *arch;
480+
size_t arch_len;
482481
php_url *resource = NULL;
483482

484483
/* pre-readonly check, we need to know if this is a data phar */
485-
if (FAILURE == phar_split_fname(url, strlen(url), &arch, &arch_len, &entry2, &entry_len, 2, 2)) {
484+
if (FAILURE == phar_split_fname(url, strlen(url), &arch, &arch_len, NULL, NULL, 2, 2)) {
486485
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\", no phar archive specified, or phar archive does not exist", url);
487486
return 0;
488487
}
@@ -492,7 +491,6 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
492491
}
493492

494493
efree(arch);
495-
efree(entry2);
496494

497495
if (PHAR_G(readonly) && (!phar || !phar->is_data)) {
498496
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot rmdir directory \"%s\", write operations disabled", url);

ext/phar/func_interceptors.c

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,11 @@ PHP_FUNCTION(phar_opendir) /* {{{ */
5050
goto skip_phar;
5151
}
5252

53-
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) {
53+
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0)) {
5454
php_stream_context *context = NULL;
5555
php_stream *stream;
5656
char *name;
5757

58-
efree(entry);
5958
entry = estrndup(filename, filename_len);
6059
/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
6160
entry_len = filename_len;
@@ -89,8 +88,8 @@ PHP_FUNCTION(phar_opendir) /* {{{ */
8988

9089
static zend_string* phar_get_name_for_relative_paths(zend_string *filename, bool using_include_path)
9190
{
92-
char *arch, *entry;
93-
size_t arch_len, entry_len;
91+
char *arch;
92+
size_t arch_len;
9493
zend_string *fname = zend_get_executed_filename_ex();
9594

9695
/* we are checking for existence of a file within the relative path. Chances are good that this is
@@ -99,13 +98,10 @@ static zend_string* phar_get_name_for_relative_paths(zend_string *filename, bool
9998
return NULL;
10099
}
101100

102-
if (FAILURE == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) {
101+
if (FAILURE == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0)) {
103102
return NULL;
104103
}
105104

106-
efree(entry);
107-
entry = NULL;
108-
entry_len = 0;
109105
/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
110106
/* retrieving a file defaults to within the current directory, so use this if possible */
111107
phar_archive_data *phar;
@@ -122,8 +118,8 @@ static zend_string* phar_get_name_for_relative_paths(zend_string *filename, bool
122118
return NULL;
123119
}
124120
} else {
125-
entry_len = ZSTR_LEN(filename);
126-
entry = phar_fix_filepath(estrndup(ZSTR_VAL(filename), ZSTR_LEN(filename)), &entry_len, 1);
121+
size_t entry_len = ZSTR_LEN(filename);
122+
char *entry = phar_fix_filepath(estrndup(ZSTR_VAL(filename), ZSTR_LEN(filename)), &entry_len, 1);
127123
if (entry[0] == '/') {
128124
if (!zend_hash_str_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
129125
/* this file is not in the phar, use the original path */
@@ -509,9 +505,7 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ
509505
phar = PHAR_G(last_phar);
510506
goto splitted;
511507
}
512-
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) {
513-
514-
efree(entry);
508+
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0)) {
515509
entry = estrndup(filename, filename_length);
516510
/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
517511
entry_len = filename_length;
@@ -751,10 +745,9 @@ PHP_FUNCTION(phar_is_file) /* {{{ */
751745
goto skip_phar;
752746
}
753747

754-
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) {
748+
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0)) {
755749
phar_archive_data *phar;
756750

757-
efree(entry);
758751
entry = filename;
759752
/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
760753
entry_len = filename_len;
@@ -817,10 +810,9 @@ PHP_FUNCTION(phar_is_link) /* {{{ */
817810
goto skip_phar;
818811
}
819812

820-
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) {
813+
if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0)) {
821814
phar_archive_data *phar;
822815

823-
efree(entry);
824816
entry = filename;
825817
/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
826818
entry_len = filename_len;

ext/phar/phar.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,16 +2298,18 @@ zend_result phar_split_fname(const char *filename, size_t filename_len, char **a
22982298
*arch_len = ext_str - filename + ext_len;
22992299
*arch = estrndup(filename, *arch_len);
23002300

2301-
if (ext_str[ext_len]) {
2302-
*entry_len = filename_len - *arch_len;
2303-
*entry = estrndup(ext_str+ext_len, *entry_len);
2304-
#ifdef PHP_WIN32
2305-
phar_unixify_path_separators(*entry, *entry_len);
2306-
#endif
2307-
*entry = phar_fix_filepath(*entry, entry_len, 0);
2308-
} else {
2309-
*entry_len = 1;
2310-
*entry = estrndup("/", 1);
2301+
if (entry) {
2302+
if (ext_str[ext_len]) {
2303+
*entry_len = filename_len - *arch_len;
2304+
*entry = estrndup(ext_str+ext_len, *entry_len);
2305+
#ifdef PHP_WIN32
2306+
phar_unixify_path_separators(*entry, *entry_len);
2307+
#endif
2308+
*entry = phar_fix_filepath(*entry, entry_len, 0);
2309+
} else {
2310+
*entry_len = 1;
2311+
*entry = estrndup("/", 1);
2312+
}
23112313
}
23122314

23132315
#ifdef PHP_WIN32

ext/phar/phar_object.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,8 @@ static void phar_postprocess_ru_web(char *fname, size_t fname_len, char **entry,
412412
PHP_METHOD(Phar, running)
413413
{
414414
zend_string *fname;
415-
char *arch, *entry;
416-
size_t arch_len, entry_len;
415+
char *arch;
416+
size_t arch_len;
417417
bool retphar = true;
418418

419419
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &retphar) == FAILURE) {
@@ -427,9 +427,8 @@ PHP_METHOD(Phar, running)
427427

428428
if (
429429
zend_string_starts_with_literal_ci(fname, "phar://")
430-
&& SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)
430+
&& SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0)
431431
) {
432-
efree(entry);
433432
if (retphar) {
434433
RETVAL_STRINGL(ZSTR_VAL(fname), arch_len + 7);
435434
efree(arch);
@@ -485,8 +484,7 @@ PHP_METHOD(Phar, mount)
485484
}
486485
#endif
487486

488-
if (fname_len > 7 && !memcmp(fname, "phar://", 7) && SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) {
489-
efree(entry);
487+
if (fname_len > 7 && !memcmp(fname, "phar://", 7) && SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, NULL, NULL, 2, 0)) {
490488
entry = NULL;
491489

492490
if (path_len > 7 && !memcmp(path, "phar://", 7)) {
@@ -1300,9 +1298,9 @@ PHP_METHOD(Phar, getSupportedCompression)
13001298
/* {{{ Completely remove a phar archive from memory and disk */
13011299
PHP_METHOD(Phar, unlinkArchive)
13021300
{
1303-
char *fname, *error, *arch, *entry;
1301+
char *fname, *error, *arch;
13041302
size_t fname_len;
1305-
size_t arch_len, entry_len;
1303+
size_t arch_len;
13061304
phar_archive_data *phar;
13071305

13081306
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) {
@@ -1329,16 +1327,14 @@ PHP_METHOD(Phar, unlinkArchive)
13291327
if (
13301328
zend_file_name
13311329
&& zend_string_starts_with_literal_ci(zend_file_name, "phar://")
1332-
&& SUCCESS == phar_split_fname(ZSTR_VAL(zend_file_name), ZSTR_LEN(zend_file_name), &arch, &arch_len, &entry, &entry_len, 2, 0)
1330+
&& SUCCESS == phar_split_fname(ZSTR_VAL(zend_file_name), ZSTR_LEN(zend_file_name), &arch, &arch_len, NULL, NULL, 2, 0)
13331331
) {
13341332
if (arch_len == fname_len && !memcmp(arch, fname, arch_len)) {
13351333
zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" cannot be unlinked from within itself", fname);
13361334
efree(arch);
1337-
efree(entry);
13381335
RETURN_THROWS();
13391336
}
13401337
efree(arch);
1341-
efree(entry);
13421338
}
13431339

13441340
if (phar->is_persistent) {

ext/phar/util.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t fil
267267
zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data **pphar) /* {{{ */
268268
{
269269
zend_string *ret;
270-
char *path, *arch, *entry, *test;
271-
size_t arch_len, entry_len;
270+
char *path, *arch, *test;
271+
size_t arch_len;
272272
phar_archive_data *phar;
273273

274274
if (pphar) {
@@ -301,12 +301,10 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data
301301
goto splitted;
302302
}
303303

304-
if (!is_file_a_phar_wrapper || SUCCESS != phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
304+
if (!is_file_a_phar_wrapper || SUCCESS != phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 1, 0)) {
305305
return NULL;
306306
}
307307

308-
efree(entry);
309-
310308
if (*ZSTR_VAL(filename) == '.') {
311309
size_t try_len;
312310

@@ -347,7 +345,7 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data
347345

348346
if (ret && zend_string_starts_with_literal_ci(ret, "phar://")) {
349347
/* found phar:// */
350-
if (SUCCESS != phar_split_fname(ZSTR_VAL(ret), ZSTR_LEN(ret), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
348+
if (SUCCESS != phar_split_fname(ZSTR_VAL(ret), ZSTR_LEN(ret), &arch, &arch_len, NULL, NULL, 1, 0)) {
351349
return ret;
352350
}
353351

@@ -358,7 +356,6 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data
358356
}
359357

360358
efree(arch);
361-
efree(entry);
362359
}
363360

364361
return ret;

0 commit comments

Comments
 (0)