Skip to content

Commit f265e6d

Browse files
committed
ext/phar: avoid redundant allocation by using zend_string for alias
1 parent 5c54810 commit f265e6d

File tree

1 file changed

+54
-23
lines changed

1 file changed

+54
-23
lines changed

ext/phar/zip.c

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,9 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch
234234
uint16_t i;
235235
phar_archive_data *mydata = NULL;
236236
phar_entry_info entry = {0};
237-
char *ext = NULL;
237+
char *ext, *actual_alias = NULL;
238238
char *metadata = NULL;
239-
zend_string *actual_alias = NULL;
239+
240240
size = php_stream_tell(fp);
241241

242242
if (size > sizeof(locator) + 65536) {
@@ -343,10 +343,7 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch
343343
entry.fp_type = PHAR_FP;
344344
entry.is_persistent = mydata->is_persistent;
345345
#define PHAR_ZIP_FAIL(errmsg) \
346-
if (actual_alias) { \
347-
zend_string_release_ex(actual_alias, 0); \
348-
actual_alias = NULL; \
349-
} \
346+
efree(actual_alias); \
350347
zend_hash_destroy(&mydata->manifest); \
351348
HT_INVALIDATE(&mydata->manifest); \
352349
zend_hash_destroy(&mydata->mounted_dirs); \
@@ -605,7 +602,7 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch
605602
ZVAL_UNDEF(&entry.metadata_tracker.val);
606603
}
607604

608-
if (actual_alias == NULL && zend_string_equals_literal(entry.filename, ".phar/alias.txt")) {
605+
if (!actual_alias && zend_string_equals_literal(entry.filename, ".phar/alias.txt")) {
609606
php_stream_filter *filter;
610607

611608
/* archive alias found */
@@ -631,7 +628,19 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch
631628

632629
php_stream_filter_append(&fp->readfilters, filter);
633630

634-
actual_alias = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
631+
// TODO: refactor to avoid reallocation ???
632+
//??? entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)
633+
{
634+
zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
635+
if (str) {
636+
entry.uncompressed_filesize = ZSTR_LEN(str);
637+
actual_alias = estrndup(ZSTR_VAL(str), ZSTR_LEN(str));
638+
zend_string_release_ex(str, 0);
639+
} else {
640+
actual_alias = NULL;
641+
entry.uncompressed_filesize = 0;
642+
}
643+
}
635644

636645
if (!entry.uncompressed_filesize) {
637646
php_stream_filter_remove(filter, 1);
@@ -651,7 +660,20 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch
651660
}
652661

653662
php_stream_filter_append(&fp->readfilters, filter);
654-
actual_alias = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
663+
664+
// TODO: refactor to avoid reallocation ???
665+
//??? entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)
666+
{
667+
zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
668+
if (str) {
669+
entry.uncompressed_filesize = ZSTR_LEN(str);
670+
actual_alias = estrndup(ZSTR_VAL(str), ZSTR_LEN(str));
671+
zend_string_release_ex(str, 0);
672+
} else {
673+
actual_alias = NULL;
674+
entry.uncompressed_filesize = 0;
675+
}
676+
}
655677

656678
if (!entry.uncompressed_filesize) {
657679
php_stream_filter_remove(filter, 1);
@@ -662,7 +684,19 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch
662684
php_stream_filter_flush(filter, 1);
663685
php_stream_filter_remove(filter, 1);
664686
} else {
665-
actual_alias = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
687+
// TODO: refactor to avoid reallocation ???
688+
//??? entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)
689+
{
690+
zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
691+
if (str) {
692+
entry.uncompressed_filesize = ZSTR_LEN(str);
693+
actual_alias = estrndup(ZSTR_VAL(str), ZSTR_LEN(str));
694+
zend_string_release_ex(str, 0);
695+
} else {
696+
actual_alias = NULL;
697+
entry.uncompressed_filesize = 0;
698+
}
699+
}
666700

667701
if (!entry.uncompressed_filesize) {
668702
zend_string_release_ex(entry.filename, entry.is_persistent);
@@ -693,38 +727,35 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch
693727

694728
zend_hash_str_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len, mydata);
695729

696-
if (actual_alias != NULL) {
730+
if (actual_alias) {
697731
phar_archive_data *fd_ptr;
698732

699-
if (!phar_validate_alias(ZSTR_VAL(actual_alias), ZSTR_LEN(actual_alias))) {
733+
if (!phar_validate_alias(actual_alias, mydata->alias_len)) {
700734
if (error) {
701-
spprintf(error, 4096, "phar error: invalid alias \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(actual_alias), fname);
735+
spprintf(error, 4096, "phar error: invalid alias \"%s\" in zip-based phar \"%s\"", actual_alias, fname);
702736
}
703-
zend_string_release_ex(actual_alias, 0);
737+
efree(actual_alias);
704738
zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len);
705739
return FAILURE;
706740
}
707741

708742
mydata->is_temporary_alias = 0;
709743

710-
if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), ZSTR_VAL(actual_alias), ZSTR_LEN(actual_alias)))) {
711-
if (SUCCESS != phar_free_alias(fd_ptr, ZSTR_VAL(actual_alias), ZSTR_LEN(actual_alias))) {
744+
if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias, mydata->alias_len))) {
745+
if (SUCCESS != phar_free_alias(fd_ptr, actual_alias, mydata->alias_len)) {
712746
if (error) {
713747
spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with implicit alias, alias is already in use", fname);
714748
}
715-
zend_string_release_ex(actual_alias, 0);
749+
efree(actual_alias);
716750
zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len);
717751
return FAILURE;
718752
}
719753
}
720754

721-
755+
mydata->alias = entry.is_persistent ? pestrndup(actual_alias, mydata->alias_len, 1) : actual_alias;
756+
722757
if (entry.is_persistent) {
723-
mydata->alias = pestrndup(ZSTR_VAL(actual_alias), ZSTR_LEN(actual_alias), 1);
724-
zend_string_release_ex(actual_alias, 0);
725-
} else {
726-
mydata->alias = estrndup(ZSTR_VAL(actual_alias), ZSTR_LEN(actual_alias));
727-
zend_string_release_ex(actual_alias, 0);
758+
efree(actual_alias);
728759
}
729760

730761
zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), mydata->alias, mydata->alias_len, mydata);

0 commit comments

Comments
 (0)