From 6babab5070777842dd07cb101a28d83dd620dc27 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 16 Oct 2025 00:40:42 +0100 Subject: [PATCH 1/8] ext/phar: remove unused parameters for phar_do_403() --- ext/phar/phar_object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 0b7e55c5e9af..c8035ac7f414 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -311,7 +311,7 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char } /* }}} */ -static void phar_do_403(char *entry, size_t entry_len) /* {{{ */ +static void phar_do_403(void) /* {{{ */ { sapi_header_line ctr = {0}; @@ -723,7 +723,7 @@ PHP_METHOD(Phar, webPhar) break; case IS_TRUE: case IS_FALSE: - phar_do_403(entry, entry_len); + phar_do_403(); if (free_pathinfo) { efree(path_info); From abe03613bfe66a0b0e516447b8600e3faeb8f1f7 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 15 Oct 2025 23:31:27 +0100 Subject: [PATCH 2/8] ext/phar: remove unused parameters for phar_do_404() --- ext/phar/phar_object.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index c8035ac7f414..5839a490fecc 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -325,7 +325,7 @@ static void phar_do_403(void) /* {{{ */ } /* }}} */ -static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, char *f404, size_t f404_len, char *entry, size_t entry_len) /* {{{ */ +static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, char *f404, size_t f404_len) /* {{{ */ { sapi_header_line ctr = {0}; phar_entry_info *info; @@ -769,7 +769,7 @@ PHP_METHOD(Phar, webPhar) if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { - phar_do_404(phar, fname, fname_len, f404, f404_len, entry, entry_len); + phar_do_404(phar, fname, fname_len, f404, f404_len); if (free_pathinfo) { efree(path_info); @@ -815,7 +815,7 @@ PHP_METHOD(Phar, webPhar) if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { - phar_do_404(phar, fname, fname_len, f404, f404_len, entry, entry_len); + phar_do_404(phar, fname, fname_len, f404, f404_len); zend_bailout(); } From 5380c6817193491df84095a236dbeb5dd7b4bd71 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 16 Oct 2025 00:42:35 +0100 Subject: [PATCH 3/8] ext/phar: use zend_string for f404 param of phar_do_404() --- ext/phar/phar_object.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 5839a490fecc..3b81a6ebef43 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -325,16 +325,16 @@ static void phar_do_403(void) /* {{{ */ } /* }}} */ -static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, char *f404, size_t f404_len) /* {{{ */ +static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, zend_string *f404) /* {{{ */ { sapi_header_line ctr = {0}; phar_entry_info *info; - if (phar && f404_len) { - info = phar_get_entry_info(phar, f404, f404_len, NULL, true); + if (phar && f404 && ZSTR_LEN(f404)) { + info = phar_get_entry_info(phar, ZSTR_VAL(f404), ZSTR_LEN(f404), NULL, true); if (info) { - phar_file_action(phar, info, "text/html", PHAR_MIME_PHP, f404, f404_len, fname, NULL, NULL, 0); + phar_file_action(phar, info, "text/html", PHAR_MIME_PHP, ZSTR_VAL(f404), ZSTR_LEN(f404), fname, NULL, NULL, 0); return; } } @@ -559,8 +559,9 @@ PHP_METHOD(Phar, webPhar) zval *mimeoverride = NULL; zend_fcall_info rewrite_fci = {0}; zend_fcall_info_cache rewrite_fcc; - char *alias = NULL, *error, *index_php = NULL, *f404 = NULL, *ru = NULL; - size_t alias_len = 0, f404_len = 0, free_pathinfo = 0; + char *alias = NULL, *error, *index_php = NULL, *ru = NULL; + size_t alias_len = 0, free_pathinfo = 0; + zend_string *f404 = NULL; size_t ru_len = 0; char *fname, *path_info, *mime_type = NULL, *entry, *pt; const char *basename; @@ -571,7 +572,7 @@ PHP_METHOD(Phar, webPhar) phar_entry_info *info = NULL; size_t sapi_mod_name_len = strlen(sapi_module.name); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!s!s!af!", &alias, &alias_len, &index_php, &index_php_len, &f404, &f404_len, &mimeoverride, &rewrite_fci, &rewrite_fcc) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!s!S!af!", &alias, &alias_len, &index_php, &index_php_len, &f404, &mimeoverride, &rewrite_fci, &rewrite_fcc) == FAILURE) { RETURN_THROWS(); } @@ -769,7 +770,7 @@ PHP_METHOD(Phar, webPhar) if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { - phar_do_404(phar, fname, fname_len, f404, f404_len); + phar_do_404(phar, fname, fname_len, f404); if (free_pathinfo) { efree(path_info); @@ -815,7 +816,7 @@ PHP_METHOD(Phar, webPhar) if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { - phar_do_404(phar, fname, fname_len, f404, f404_len); + phar_do_404(phar, fname, fname_len, f404); zend_bailout(); } From 02250efc353cb6c400ef6fa148b4cee6a791a297 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 15 Oct 2025 23:37:41 +0100 Subject: [PATCH 4/8] ext/phar: Use RETURN_BOOL() when possible --- ext/phar/phar_object.c | 44 ++++++++++++------------------------------ 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 3b81a6ebef43..f5c6ef6f12b7 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -1030,23 +1030,11 @@ PHP_METHOD(Phar, canCompress) phar_request_initialize(); switch (method) { case PHAR_ENT_COMPRESSED_GZ: - if (PHAR_G(has_zlib)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(PHAR_G(has_zlib)); case PHAR_ENT_COMPRESSED_BZ2: - if (PHAR_G(has_bz2)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(PHAR_G(has_bz2)); default: - if (PHAR_G(has_zlib) || PHAR_G(has_bz2)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(PHAR_G(has_zlib) || PHAR_G(has_bz2)); } } /* }}} */ @@ -2577,11 +2565,8 @@ PHP_METHOD(Phar, isWritable) } if (SUCCESS != php_stream_stat_path(phar_obj->archive->fname, &ssb)) { - if (phar_obj->archive->is_brandnew) { - /* assume it works if the file doesn't exist yet */ - RETURN_TRUE; - } - RETURN_FALSE; + /* assume it works if the file doesn't exist yet */ + RETURN_BOOL(phar_obj->archive->is_brandnew); } RETURN_BOOL((ssb.sb.st_mode & (S_IWOTH | S_IWGRP | S_IWUSR)) != 0); @@ -3503,7 +3488,6 @@ PHP_METHOD(Phar, copy) PHP_METHOD(Phar, offsetExists) { zend_string *file_name; - phar_entry_info *entry; if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); @@ -3511,19 +3495,15 @@ PHP_METHOD(Phar, offsetExists) PHAR_ARCHIVE_OBJECT(); - if (zend_hash_exists(&phar_obj->archive->manifest, file_name)) { - if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { - if (entry->is_deleted) { - /* entry is deleted, but has not been flushed to disk yet */ - RETURN_FALSE; - } - } - - if (zend_string_starts_with_literal(file_name, ".phar")) { - /* none of these are real files, so they don't exist */ + const phar_entry_info *entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name); + if (entry != NULL) { + if (entry->is_deleted) { + /* entry is deleted, but has not been flushed to disk yet */ RETURN_FALSE; } - RETURN_TRUE; + + /* none of these are real files, so they don't exist */ + RETURN_BOOL(!zend_string_starts_with_literal(file_name, ".phar")); } else { /* If the info class is not based on PharFileInfo, directories are not directly instantiable */ if (UNEXPECTED(!instanceof_function(phar_obj->spl.info_class, phar_ce_entry))) { From 7bc7810a949301c95fd53dd0d542601163c84b9b Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 16 Oct 2025 00:03:28 +0100 Subject: [PATCH 5/8] ext/phar: Do not aquire lifetime of basename parameter in phar_file_action() This is incredibly confusing. --- ext/phar/phar_object.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index f5c6ef6f12b7..70821ff561bf 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -168,7 +168,6 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char switch (code) { case PHAR_MIME_PHPS: - efree(basename); /* highlight source */ if (entry[0] == '/') { spprintf(&name, 4096, "phar://%s%s", arch, entry); @@ -186,7 +185,6 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char zend_bailout(); case PHAR_MIME_OTHER: /* send headers, output file contents */ - efree(basename); ctr.line_len = spprintf((char **) &(ctr.line), 0, "Content-type: %s", mime_type); sapi_header_op(SAPI_HEADER_REPLACE, &ctr); efree((void *) ctr.line); @@ -230,7 +228,6 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char case PHAR_MIME_PHP: if (basename) { phar_mung_server_vars(arch, entry, entry_len, basename, ru_len); - efree(basename); } if (entry[0] == '/') { @@ -870,6 +867,7 @@ PHP_METHOD(Phar, webPhar) code = phar_file_type(&PHAR_G(mime_types), entry, &mime_type); } phar_file_action(phar, info, mime_type, code, entry, entry_len, fname, pt, ru, ru_len); + efree(pt); finish: ; #ifdef PHP_WIN32 From 24dba79c8d26ae6ac8472946e6885de13ae71c0c Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 16 Oct 2025 00:10:57 +0100 Subject: [PATCH 6/8] ext/phar/phar_object.c: add some const qualifiers --- ext/phar/phar_object.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 70821ff561bf..a66de882d304 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -45,7 +45,7 @@ static zend_class_entry *phar_ce_entry; RETURN_THROWS(); \ } -static int phar_file_type(HashTable *mimes, char *file, char **mime_type) /* {{{ */ +static int phar_file_type(const HashTable *mimes, const char *file, char **mime_type) /* {{{ */ { char *ext; phar_mime_type *mime; @@ -65,7 +65,7 @@ static int phar_file_type(HashTable *mimes, char *file, char **mime_type) /* {{{ } /* }}} */ -static void phar_mung_server_vars(char *fname, char *entry, size_t entry_len, char *basename, size_t request_uri_len) /* {{{ */ +static void phar_mung_server_vars(char *fname, char *entry, size_t entry_len, const char *basename, size_t request_uri_len) /* {{{ */ { HashTable *_SERVER; zval *stuff; @@ -151,7 +151,7 @@ static void phar_mung_server_vars(char *fname, char *entry, size_t entry_len, ch } /* }}} */ -static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char *mime_type, int code, char *entry, size_t entry_len, char *arch, char *basename, char *ru, size_t ru_len) /* {{{ */ +static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char *mime_type, int code, char *entry, size_t entry_len, char *arch, const char *basename, char *ru, size_t ru_len) /* {{{ */ { char *name = NULL, buf[8192]; const char *cwd; @@ -349,7 +349,7 @@ static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, /* post-process REQUEST_URI and retrieve the actual request URI. This is for cases like http://localhost/blah.phar/path/to/file.php/extra/stuff which calls "blah.phar" file "path/to/file.php" with PATH_INFO "/extra/stuff" */ -static void phar_postprocess_ru_web(char *fname, size_t fname_len, char **entry, size_t *entry_len, char **ru, size_t *ru_len) /* {{{ */ +static void phar_postprocess_ru_web(const char *fname, size_t fname_len, char **entry, size_t *entry_len, char **ru, size_t *ru_len) /* {{{ */ { char *e = *entry + 1, *u = NULL, *u1 = NULL, *saveu = NULL; size_t e_len = *entry_len - 1, u_len = 0; @@ -627,7 +627,7 @@ PHP_METHOD(Phar, webPhar) || (sapi_mod_name_len == sizeof("litespeed") - 1 && !strncmp(sapi_module.name, "litespeed", sizeof("litespeed") - 1))) { if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF) { - HashTable *_server = Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]); + const HashTable *_server = Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]); zval *z_script_name, *z_path_info; if (NULL == (z_script_name = zend_hash_str_find(_server, "SCRIPT_NAME", sizeof("SCRIPT_NAME")-1)) || @@ -3114,7 +3114,7 @@ static int phar_set_compression(zval *zv, void *argument) /* {{{ */ static int phar_test_compression(zval *zv, void *argument) /* {{{ */ { - phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv); + const phar_entry_info *entry = Z_PTR_P(zv); if (entry->is_deleted) { return ZEND_HASH_APPLY_KEEP; From 4e41fe2bcb6e228e73e0e3a5f652fe5491524295 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 16 Oct 2025 00:56:10 +0100 Subject: [PATCH 7/8] ext/phar: Refactor phar_create_default_stub() --- ext/phar/phar.c | 50 ++++++++++++++++++++++------------------ ext/phar/phar_internal.h | 2 +- ext/phar/phar_object.c | 12 +++++----- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index b1f6d39171e4..e9998930ab54 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2488,42 +2488,48 @@ static int phar_flush_clean_deleted_apply(zval *zv) /* {{{ */ #include "stub.h" /* Generated phar_get_stub() function from makestub.php script */ -zend_string *phar_create_default_stub(const char *index_php, const char *web_index, char **error) /* {{{ */ +zend_string *phar_create_default_stub(const zend_string *php_index_str, const zend_string *web_index_str, char **error) /* {{{ */ { - size_t index_len, web_len; + const char *php_index; + const char *web_index; + size_t php_len, web_len; if (error) { *error = NULL; } - if (!index_php) { - index_php = "index.php"; - } - - if (!web_index) { - web_index = "index.php"; - } - - index_len = strlen(index_php); - web_len = strlen(web_index); - - if (index_len > 400) { - /* ridiculous size not allowed for index.php startup filename */ - if (error) { - spprintf(error, 0, "Illegal filename passed in for stub creation, was %zd characters long, and only 400 or less is allowed", index_len); + if (!php_index_str) { + php_index = "index.php"; + php_len = strlen("index.php"); + } else { + php_index = ZSTR_VAL(php_index_str); + php_len = ZSTR_LEN(php_index_str); + if (php_len > 400) { + /* ridiculous size not allowed for index.php startup filename */ + if (error) { + spprintf(error, 0, "Illegal filename passed in for stub creation, was %zd characters long, and only 400 or less is allowed", php_len); + } return NULL; } } - if (web_len > 400) { - /* ridiculous size not allowed for index.php startup filename */ - if (error) { - spprintf(error, 0, "Illegal web filename passed in for stub creation, was %zd characters long, and only 400 or less is allowed", web_len); + if (!web_index_str) { + web_index = "index.php"; + web_len = strlen("index.php"); + } else { + web_index = ZSTR_VAL(web_index_str); + web_len = ZSTR_LEN(web_index_str); + + if (web_len > 400) { + /* ridiculous size not allowed for index.php startup filename */ + if (error) { + spprintf(error, 0, "Illegal web filename passed in for stub creation, was %zd characters long, and only 400 or less is allowed", web_len); + } return NULL; } } - return phar_get_stub(index_php, web_index, index_len+1, web_len+1); + return phar_get_stub(php_index, web_index, php_len+1, web_len+1); } /* }}} */ diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index fe63e075c1b5..d588d67f4ed6 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -415,7 +415,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error); /* utility functions */ -zend_string *phar_create_default_stub(const char *index_php, const char *web_index, char **error); +zend_string *phar_create_default_stub(const zend_string *php_index_str, const zend_string *web_index_str, char **error); const char *phar_decompress_filter(const phar_entry_info *entry, bool return_unknown); const char *phar_compress_filter(const phar_entry_info *entry, bool return_unknown); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index a66de882d304..0183f4fc5079 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -946,11 +946,11 @@ PHP_METHOD(Phar, interceptFileFuncs) */ PHP_METHOD(Phar, createDefaultStub) { - char *index = NULL, *webindex = NULL, *error; + zend_string *index = NULL, *webindex = NULL; + char *error; zend_string *stub; - size_t index_len = 0, webindex_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|p!p!", &index, &index_len, &webindex, &webindex_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|P!P!", &index, &webindex) == FAILURE) { RETURN_THROWS(); } @@ -2914,12 +2914,11 @@ PHP_METHOD(Phar, setStub) */ PHP_METHOD(Phar, setDefaultStub) { - char *index = NULL, *webindex = NULL, *error = NULL; + zend_string *index = NULL, *webindex = NULL; zend_string *stub = NULL; - size_t index_len = 0, webindex_len = 0; bool created_stub = false; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!s!", &index, &index_len, &webindex, &webindex_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|P!P!", &index, &webindex) == FAILURE) { RETURN_THROWS(); } @@ -2947,6 +2946,7 @@ PHP_METHOD(Phar, setDefaultStub) RETURN_THROWS(); } + char *error = NULL; if (!phar_obj->archive->is_tar && !phar_obj->archive->is_zip) { stub = phar_create_default_stub(index, webindex, &error); From 37f456f4f704e8f1be0f58a4fc50422429aafcc0 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 16 Oct 2025 01:33:09 +0100 Subject: [PATCH 8/8] ext/phar: start refactoring phar_postprocess_ru_web() --- ext/phar/phar_object.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 0183f4fc5079..c7afd1ff0a35 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -349,9 +349,10 @@ static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, /* post-process REQUEST_URI and retrieve the actual request URI. This is for cases like http://localhost/blah.phar/path/to/file.php/extra/stuff which calls "blah.phar" file "path/to/file.php" with PATH_INFO "/extra/stuff" */ -static void phar_postprocess_ru_web(const char *fname, size_t fname_len, char **entry, size_t *entry_len, char **ru, size_t *ru_len) /* {{{ */ +static void phar_postprocess_ru_web(const char *fname, size_t fname_len, const char *entry, size_t *entry_len, char **ru, size_t *ru_len) /* {{{ */ { - char *e = *entry + 1, *u = NULL, *u1 = NULL, *saveu = NULL; + const char *e = entry + 1; + char *u = NULL, *u1 = NULL, *saveu = NULL; size_t e_len = *entry_len - 1, u_len = 0; phar_archive_data *pphar; @@ -746,7 +747,7 @@ PHP_METHOD(Phar, webPhar) } if (entry_len) { - phar_postprocess_ru_web(fname, fname_len, &entry, &entry_len, &ru, &ru_len); + phar_postprocess_ru_web(fname, fname_len, entry, &entry_len, &ru, &ru_len); } if (!entry_len || (entry_len == 1 && entry[0] == '/')) {