Commit 895c2af4d48 for php.net

commit 895c2af4d4846819e84762297d810cb29bc9fe3a
Author: Gina Peter Banyard <girgias@php.net>
Date:   Sun Jun 28 20:36:14 2026 +0100

    ext/phar: refactor {de}compression filter name APIs (#22502)

    And clean-up usage sites as some of them shouldn't even be possible in the first place

diff --git a/ext/phar/phar.c b/ext/phar/phar.c
index ee12c5b91fe..c64c448c52a 100644
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -2724,7 +2724,9 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen
 			entry->compressed_filesize = entry->uncompressed_filesize;
 			continue;
 		}
-		filter = php_stream_filter_create(phar_compress_filter(entry, false), NULL, 0);
+		const char *compression_filter_name = phar_get_compress_filter_name(entry);
+		ZEND_ASSERT(compression_filter_name && "Must have as this has a compression flag set");
+		filter = php_stream_filter_create(compression_filter_name, NULL, false);
 		if (!filter) {
 			if (must_close_old_file) {
 				php_stream_close(oldfile);
diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h
index f175fb7b9d6..a7a5581e160 100644
--- a/ext/phar/phar_internal.h
+++ b/ext/phar/phar_internal.h
@@ -442,8 +442,8 @@ ZEND_ATTRIBUTE_NONNULL zend_string* phar_create_signature(phar_archive_data *pha

 /* utility functions */
 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);
+const char *phar_get_decompress_filter_name(const phar_entry_info *entry);
+const char *phar_get_compress_filter_name(const phar_entry_info *entry);

 /* void phar_remove_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len); */
 void phar_add_virtual_dirs(phar_archive_data *phar, const char *filename, size_t filename_len);
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 7eb8392e6c6..9859551b3cc 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -3865,15 +3865,11 @@ PHP_METHOD(Phar, getStub)
 					RETURN_THROWS();
 				}
 				if (stub->flags & PHAR_ENT_COMPRESSION_MASK) {
-					const char *filter_name = phar_decompress_filter(stub, false);
-
-					if (filter_name != NULL) {
-						filter = php_stream_filter_create(filter_name, NULL, php_stream_is_persistent(fp));
-					} else {
-						filter = NULL;
-					}
-					if (!filter) {
-						zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "phar error: unable to read stub of phar \"%s\" (cannot create %s filter)", ZSTR_VAL(phar_obj->archive->fname), phar_decompress_filter(stub, true));
+					const char *decompression_filter_name = phar_get_decompress_filter_name(stub);
+					ZEND_ASSERT(decompression_filter_name && "Must have as this has a decompression flag set");
+					filter = php_stream_filter_create(decompression_filter_name, NULL, php_stream_is_persistent(fp));
+					if (UNEXPECTED(filter == NULL)) {
+						zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "phar error: unable to read stub of phar \"%s\" (cannot create %s filter)", ZSTR_VAL(phar_obj->archive->fname), decompression_filter_name);
 						RETURN_THROWS();
 					}
 					php_stream_filter_append(&fp->readfilters, filter);
diff --git a/ext/phar/util.c b/ext/phar/util.c
index 2962f778b27..1f94be5a269 100644
--- a/ext/phar/util.c
+++ b/ext/phar/util.c
@@ -787,7 +787,6 @@ static void phar_set_fp_type(phar_entry_info *entry, enum phar_fp_type type, zen
  */
 ZEND_ATTRIBUTE_NONNULL zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, bool follow_links) /* {{{ */
 {
-	php_stream_filter *filter;
 	phar_archive_data *phar = entry->phar;
 	zend_off_t loc;
 	php_stream *ufp;
@@ -852,15 +851,16 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_open_entry_fp(phar_entry_info *entry, ch

 	ufp = phar_get_entrypufp(entry);

-	const char *filter_name = phar_decompress_filter(entry, false);
-	if (filter_name != NULL) {
-		filter = php_stream_filter_create(filter_name, NULL, 0);
-	} else {
-		filter = NULL;
+	const char *decompression_filter_name = phar_get_decompress_filter_name(entry);
+	if (UNEXPECTED(!decompression_filter_name)) {
+		spprintf(error, 4096, "phar error: unable to read phar \"%s\" (file \"%s\" is compressed with an unknown compression algorithm)", ZSTR_VAL(phar->fname), ZSTR_VAL(entry->filename));
+		return FAILURE;
 	}

+	php_stream_filter *filter = php_stream_filter_create(decompression_filter_name, NULL, 0);
+
 	if (!filter) {
-		spprintf(error, 4096, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", ZSTR_VAL(phar->fname), phar_decompress_filter(entry, true), ZSTR_VAL(entry->filename));
+		spprintf(error, 4096, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", ZSTR_VAL(phar->fname), decompression_filter_name, ZSTR_VAL(entry->filename));
 		return FAILURE;
 	}

@@ -1115,7 +1115,7 @@ phar_archive_data* phar_get_archive(const char *fname, size_t fname_len, const c
 /**
  * Determine which stream compression filter (if any) we need to read this file
  */
-const char * phar_compress_filter(const phar_entry_info *entry, bool return_unknown) /* {{{ */
+const char * phar_get_compress_filter_name(const phar_entry_info *entry)
 {
 	switch (entry->flags & PHAR_ENT_COMPRESSION_MASK) {
 	case PHAR_ENT_COMPRESSED_GZ:
@@ -1123,15 +1123,14 @@ const char * phar_compress_filter(const phar_entry_info *entry, bool return_unkn
 	case PHAR_ENT_COMPRESSED_BZ2:
 		return "bzip2.compress";
 	default:
-		return return_unknown ? "unknown" : NULL;
+		return NULL;
 	}
 }
-/* }}} */

 /**
  * Determine which stream decompression filter (if any) we need to read this file
  */
-const char * phar_decompress_filter(const phar_entry_info *entry, bool return_unknown) /* {{{ */
+const char * phar_get_decompress_filter_name(const phar_entry_info *entry)
 {
 	uint32_t flags;

@@ -1147,10 +1146,9 @@ const char * phar_decompress_filter(const phar_entry_info *entry, bool return_un
 		case PHAR_ENT_COMPRESSED_BZ2:
 			return "bzip2.decompress";
 		default:
-			return return_unknown ? "unknown" : NULL;
+			return NULL;
 	}
 }
-/* }}} */

 /**
  * retrieve information on a file contained within a phar, or null if it ain't there
diff --git a/ext/phar/zip.c b/ext/phar/zip.c
index 5aa3f552b2a..3085ee80c9a 100644
--- a/ext/phar/zip.c
+++ b/ext/phar/zip.c
@@ -935,7 +935,6 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{

 	/* do extra field for perms later */
 	if (entry->is_modified) {
-		php_stream_filter *filter;
 		php_stream *efp;

 		if (entry->is_dir) {
@@ -981,7 +980,9 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{
 			goto not_compressed;
 		}

-		filter = php_stream_filter_create(phar_compress_filter(entry, false), NULL, 0);
+		const char *compression_filter_name = phar_get_compress_filter_name(entry);
+		ZEND_ASSERT(compression_filter_name && "Must have as this has a compression flag set");
+		php_stream_filter *filter = php_stream_filter_create(compression_filter_name, NULL, false);

 		if (!filter) {
 			if (entry->flags & PHAR_ENT_COMPRESSED_GZ) {