Skip to content

Commit 3d6f4c8

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GHSA-p3x9-6h7p-cgfc: libxml streams wrong `content-type` on redirect
2 parents 3ae4421 + a8d3a80 commit 3d6f4c8

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

ext/libxml/mime_sniff.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -308,11 +308,21 @@ PHP_LIBXML_API zend_string *php_libxml_sniff_charset_from_stream(const php_strea
308308
if (Z_TYPE(s->wrapperdata) == IS_ARRAY) {
309309
zval *header;
310310

311-
ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL(s->wrapperdata), header) {
312-
const char buf[] = "Content-Type:";
313-
if (Z_TYPE_P(header) == IS_STRING &&
314-
!zend_binary_strncasecmp(Z_STRVAL_P(header), Z_STRLEN_P(header), buf, sizeof(buf)-1, sizeof(buf)-1)) {
315-
return php_libxml_sniff_charset_from_string(Z_STRVAL_P(header) + sizeof(buf) - 1, Z_STRVAL_P(header) + Z_STRLEN_P(header));
311+
/* Scan backwards: The header array might contain the headers for multiple responses, if
312+
* a redirect was followed.
313+
*/
314+
ZEND_HASH_REVERSE_FOREACH_VAL_IND(Z_ARRVAL(s->wrapperdata), header) {
315+
if (Z_TYPE_P(header) == IS_STRING) {
316+
/* If no colon is found in the header, we assume it's the HTTP status line and bail out. */
317+
char *colon = memchr(Z_STRVAL_P(header), ':', Z_STRLEN_P(header));
318+
char *space = memchr(Z_STRVAL_P(header), ' ', Z_STRLEN_P(header));
319+
if (colon == NULL || space < colon) {
320+
return NULL;
321+
}
322+
323+
if (zend_string_starts_with_literal_ci(Z_STR_P(header), "content-type:")) {
324+
return php_libxml_sniff_charset_from_string(Z_STRVAL_P(header) + strlen("content-type:"), Z_STRVAL_P(header) + Z_STRLEN_P(header));
325+
}
316326
}
317327
} ZEND_HASH_FOREACH_END();
318328
}

0 commit comments

Comments
 (0)