@@ -525,41 +525,52 @@ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc)
525525 if (Z_TYPE (s -> wrapperdata ) == IS_ARRAY ) {
526526 zval * header ;
527527
528- ZEND_HASH_FOREACH_VAL_IND (Z_ARRVAL (s -> wrapperdata ), header ) {
528+ /* Scan backwards: The header array might contain the headers for multiple responses, if
529+ * a redirect was followed.
530+ */
531+ ZEND_HASH_REVERSE_FOREACH_VAL_IND (Z_ARRVAL (s -> wrapperdata ), header ) {
529532 const char buf [] = "Content-Type:" ;
530- if (Z_TYPE_P (header ) == IS_STRING &&
531- !zend_binary_strncasecmp (Z_STRVAL_P (header ), Z_STRLEN_P (header ), buf , sizeof (buf )- 1 , sizeof (buf )- 1 )) {
532- char needle [] = "charset=" ;
533- char * haystack = estrndup (Z_STRVAL_P (header ), Z_STRLEN_P (header ));
534- char * encoding = php_stristr (haystack , needle , Z_STRLEN_P (header ), strlen (needle ));
535-
536- if (encoding ) {
537- char * end ;
538-
539- encoding += sizeof ("charset=" )- 1 ;
540- if (* encoding == '"' ) {
541- encoding ++ ;
542- }
543- end = strchr (encoding , ';' );
544- if (end == NULL ) {
545- end = encoding + strlen (encoding );
546- }
547- end -- ; /* end == encoding-1 isn't a buffer underrun */
548- while (* end == ' ' || * end == '\t' ) {
549- end -- ;
550- }
551- if (* end == '"' ) {
552- end -- ;
553- }
554- if (encoding >= end ) continue ;
555- * (end + 1 ) = '\0' ;
556- enc = xmlParseCharEncoding (encoding );
557- if (enc <= XML_CHAR_ENCODING_NONE ) {
558- enc = XML_CHAR_ENCODING_NONE ;
533+ if (Z_TYPE_P (header ) == IS_STRING ) {
534+ /* If no colon is found in the header, we assume it's the HTTP status line and bail out. */
535+ char * colon = memchr (Z_STRVAL_P (header ), ':' , Z_STRLEN_P (header ));
536+ char * space = memchr (Z_STRVAL_P (header ), ' ' , Z_STRLEN_P (header ));
537+ if (colon == NULL || space < colon ) {
538+ break ;
539+ }
540+
541+ if (!zend_binary_strncasecmp (Z_STRVAL_P (header ), Z_STRLEN_P (header ), buf , sizeof (buf )- 1 , sizeof (buf )- 1 )) {
542+ char needle [] = "charset=" ;
543+ char * haystack = estrndup (Z_STRVAL_P (header ), Z_STRLEN_P (header ));
544+ char * encoding = php_stristr (haystack , needle , Z_STRLEN_P (header ), sizeof ("charset=" )- 1 );
545+
546+ if (encoding ) {
547+ char * end ;
548+
549+ encoding += sizeof ("charset=" )- 1 ;
550+ if (* encoding == '"' ) {
551+ encoding ++ ;
552+ }
553+ end = strchr (encoding , ';' );
554+ if (end == NULL ) {
555+ end = encoding + strlen (encoding );
556+ }
557+ end -- ; /* end == encoding-1 isn't a buffer underrun */
558+ while (* end == ' ' || * end == '\t' ) {
559+ end -- ;
560+ }
561+ if (* end == '"' ) {
562+ end -- ;
563+ }
564+ if (encoding >= end ) continue ;
565+ * (end + 1 ) = '\0' ;
566+ enc = xmlParseCharEncoding (encoding );
567+ if (enc <= XML_CHAR_ENCODING_NONE ) {
568+ enc = XML_CHAR_ENCODING_NONE ;
569+ }
559570 }
571+ efree (haystack );
572+ break ; /* found content-type */
560573 }
561- efree (haystack );
562- break ; /* found content-type */
563574 }
564575 } ZEND_HASH_FOREACH_END ();
565576 }
0 commit comments