From f2ab0354fe506aa353395cd1fcd22adefc8c1826 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Fri, 23 Jan 2026 16:09:32 -0400 Subject: [PATCH 1/2] Fix regression with header removing removing whole prefixes The header removal code looked for the colon for key-value at the wrong place, so it would overzealously remove headers. Tweak that condition, and make the alternative condition only active if it's set (with the remove prefix op case). Fixes GH-21018. --- .../tests/general_functions/gh21018.phpt | 21 +++++++++++++++++++ main/SAPI.c | 6 +++++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 ext/standard/tests/general_functions/gh21018.phpt diff --git a/ext/standard/tests/general_functions/gh21018.phpt b/ext/standard/tests/general_functions/gh21018.phpt new file mode 100644 index 0000000000000..249cfb515aeb6 --- /dev/null +++ b/ext/standard/tests/general_functions/gh21018.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-21018 (header() removes headers with the same prefix) +--INI-- +expose_php=On +--CGI-- +--FILE-- + +--EXPECTF-- +array(3) { + [0]=> + string(%d) "X-Powered-By: PHP/%s" + [1]=> + string(9) "a-test: 1" + [2]=> + string(4) "a: 1" +} diff --git a/main/SAPI.c b/main/SAPI.c index 6709d467e34fe..047c2af6f1081 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -610,8 +610,12 @@ static void sapi_remove_header(zend_llist *l, char *name, size_t len, size_t hea while (current) { header = (sapi_header_struct *)(current->data); next = current->next; + /* + * header_len is set for DELETE_PREFIX (used in cookies) + * look for the : otherwise + */ if (header->header_len > header_len - && (header->header[header_len] == ':' || len > header_len) + && (header->header[len] == ':' || (header_len && len > header_len)) && !strncasecmp(header->header, name, len)) { if (current->prev) { current->prev->next = next; From b31a03f3dcd44c59343297492dc0766017acc3a6 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Fri, 23 Jan 2026 17:35:27 -0400 Subject: [PATCH 2/2] avoid reading past the actual length --- main/SAPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/SAPI.c b/main/SAPI.c index 047c2af6f1081..c369be10ab71c 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -614,7 +614,7 @@ static void sapi_remove_header(zend_llist *l, char *name, size_t len, size_t hea * header_len is set for DELETE_PREFIX (used in cookies) * look for the : otherwise */ - if (header->header_len > header_len + if (header->header_len > len && (header->header[len] == ':' || (header_len && len > header_len)) && !strncasecmp(header->header, name, len)) { if (current->prev) {