From 3a9d59971b68906fcf54dfc4d96f0acaa04f1db9 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 25 Oct 2025 21:01:28 +0200 Subject: [PATCH 1/2] phar: Use a loop instead of goto when looking for extensions (#20289) This gets rid of a TODO and makes the code clearer. --- ext/phar/phar.c | 57 ++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 15cdddb21af4..b7bd61b86019 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2034,45 +2034,40 @@ zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len } } - // TODO Use some sort of loop here instead of a goto pos = memchr(filename + 1, '.', filename_len); -next_extension: - if (!pos) { - return FAILURE; - } - - while (pos != filename && (*(pos - 1) == '/' || *(pos - 1) == '\0')) { - pos = memchr(pos + 1, '.', filename_len - (pos - filename) - 1); - if (!pos) { - return FAILURE; + while (pos) { + while (pos != filename && (*(pos - 1) == '/' || *(pos - 1) == '\0')) { + pos = memchr(pos + 1, '.', filename_len - (pos - filename) - 1); + if (!pos) { + return FAILURE; + } } - } - slash = memchr(pos, '/', filename_len - (pos - filename)); + slash = memchr(pos, '/', filename_len - (pos - filename)); - if (!slash) { - /* this is a url like "phar://blah.phar" with no directory */ - *ext_str = pos; - *ext_len = strlen(pos); + if (!slash) { + /* this is a url like "phar://blah.phar" with no directory */ + *ext_str = pos; + *ext_len = strlen(pos); - /* file extension must contain "phar" */ - return phar_check_str(filename, *ext_str, *ext_len, executable, for_create); - } + /* file extension must contain "phar" */ + return phar_check_str(filename, *ext_str, *ext_len, executable, for_create); + } - /* we've found an extension that ends at a directory separator */ - *ext_str = pos; - *ext_len = slash - pos; + /* we've found an extension that ends at a directory separator */ + *ext_str = pos; + *ext_len = slash - pos; - if (phar_check_str(filename, *ext_str, *ext_len, executable, for_create) == SUCCESS) { - return SUCCESS; - } + if (phar_check_str(filename, *ext_str, *ext_len, executable, for_create) == SUCCESS) { + return SUCCESS; + } - /* look for more extensions */ - pos = strchr(pos + 1, '.'); - if (pos) { - *ext_str = NULL; - *ext_len = 0; - goto next_extension; + /* look for more extensions */ + pos = strchr(pos + 1, '.'); + if (pos) { + *ext_str = NULL; + *ext_len = 0; + } } return FAILURE; From 86a15f9a1bf7d9d5f2774f78157ae5fc48cd4e77 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 25 Oct 2025 21:01:41 +0200 Subject: [PATCH 2/2] phar: Remove redundant *error check (#20288) The failure of the iterator is already checked above at line 1157. --- ext/phar/tar.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 8a5df4f443dc..4847597cce2e 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -1242,12 +1242,6 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) void phar_tar_flush(phar_archive_data *phar, z php_stream_close(oldfile); } - /* on error in the hash iterator above, error is set */ - if (*error) { - php_stream_close(newfile); - return; - } - if (phar->fp && pass.free_fp) { php_stream_close(phar->fp); }