@@ -364,41 +364,52 @@ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc)
364364 if (Z_TYPE (s -> wrapperdata ) == IS_ARRAY ) {
365365 zval * header ;
366366
367- ZEND_HASH_FOREACH_VAL_IND (Z_ARRVAL (s -> wrapperdata ), header ) {
367+ /* Scan backwards: The header array might contain the headers for multiple responses, if
368+ * a redirect was followed.
369+ */
370+ ZEND_HASH_REVERSE_FOREACH_VAL_IND (Z_ARRVAL (s -> wrapperdata ), header ) {
368371 const char buf [] = "Content-Type:" ;
369- if (Z_TYPE_P (header ) == IS_STRING &&
370- !zend_binary_strncasecmp (Z_STRVAL_P (header ), Z_STRLEN_P (header ), buf , sizeof (buf )- 1 , sizeof (buf )- 1 )) {
371- char needle [] = "charset=" ;
372- char * haystack = estrndup (Z_STRVAL_P (header ), Z_STRLEN_P (header ));
373- char * encoding = php_stristr (haystack , needle , Z_STRLEN_P (header ), strlen (needle ));
374-
375- if (encoding ) {
376- char * end ;
377-
378- encoding += sizeof ("charset=" )- 1 ;
379- if (* encoding == '"' ) {
380- encoding ++ ;
381- }
382- end = strchr (encoding , ';' );
383- if (end == NULL ) {
384- end = encoding + strlen (encoding );
385- }
386- end -- ; /* end == encoding-1 isn't a buffer underrun */
387- while (* end == ' ' || * end == '\t' ) {
388- end -- ;
389- }
390- if (* end == '"' ) {
391- end -- ;
392- }
393- if (encoding >= end ) continue ;
394- * (end + 1 ) = '\0' ;
395- enc = xmlParseCharEncoding (encoding );
396- if (enc <= XML_CHAR_ENCODING_NONE ) {
397- enc = XML_CHAR_ENCODING_NONE ;
372+ if (Z_TYPE_P (header ) == IS_STRING ) {
373+ /* If no colon is found in the header, we assume it's the HTTP status line and bail out. */
374+ char * colon = memchr (Z_STRVAL_P (header ), ':' , Z_STRLEN_P (header ));
375+ char * space = memchr (Z_STRVAL_P (header ), ' ' , Z_STRLEN_P (header ));
376+ if (colon == NULL || space < colon ) {
377+ break ;
378+ }
379+
380+ if (!zend_binary_strncasecmp (Z_STRVAL_P (header ), Z_STRLEN_P (header ), buf , sizeof (buf )- 1 , sizeof (buf )- 1 )) {
381+ char needle [] = "charset=" ;
382+ char * haystack = estrndup (Z_STRVAL_P (header ), Z_STRLEN_P (header ));
383+ char * encoding = php_stristr (haystack , needle , Z_STRLEN_P (header ), sizeof ("charset=" )- 1 );
384+
385+ if (encoding ) {
386+ char * end ;
387+
388+ encoding += sizeof ("charset=" )- 1 ;
389+ if (* encoding == '"' ) {
390+ encoding ++ ;
391+ }
392+ end = strchr (encoding , ';' );
393+ if (end == NULL ) {
394+ end = encoding + strlen (encoding );
395+ }
396+ end -- ; /* end == encoding-1 isn't a buffer underrun */
397+ while (* end == ' ' || * end == '\t' ) {
398+ end -- ;
399+ }
400+ if (* end == '"' ) {
401+ end -- ;
402+ }
403+ if (encoding >= end ) continue ;
404+ * (end + 1 ) = '\0' ;
405+ enc = xmlParseCharEncoding (encoding );
406+ if (enc <= XML_CHAR_ENCODING_NONE ) {
407+ enc = XML_CHAR_ENCODING_NONE ;
408+ }
398409 }
410+ efree (haystack );
411+ break ; /* found content-type */
399412 }
400- efree (haystack );
401- break ; /* found content-type */
402413 }
403414 } ZEND_HASH_FOREACH_END ();
404415 }
0 commit comments