d2399a
From 7d163e8a0880ae8af2dd869071393e5dc07ef271 Mon Sep 17 00:00:00 2001
d2399a
From: Rob Richards <rrichards@php.net>
d2399a
Date: Sat, 6 Jul 2013 07:53:07 -0400
d2399a
Subject: [PATCH] truncate results at depth of 255 to prevent corruption
d2399a
d2399a
---
d2399a
 ext/xml/xml.c | 90 +++++++++++++++++++++++++++++++++--------------------------
d2399a
 1 file changed, 50 insertions(+), 40 deletions(-)
d2399a
d2399a
diff --git a/ext/xml/xml.c b/ext/xml/xml.c
d2399a
index 1f0480b..9f0bc30 100644
d2399a
--- a/ext/xml/xml.c
d2399a
+++ b/ext/xml/xml.c
d2399a
@@ -428,7 +428,7 @@ static void xml_parser_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
d2399a
 	}
d2399a
 	if (parser->ltags) {
d2399a
 		int inx;
d2399a
-		for (inx = 0; inx < parser->level; inx++)
d2399a
+		for (inx = 0; ((inx < parser->level) && (inx < XML_MAXLEVEL)); inx++)
d2399a
 			efree(parser->ltags[ inx ]);
d2399a
 		efree(parser->ltags);
d2399a
 	}
d2399a
@@ -805,45 +805,50 @@ void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Ch
d2399a
 		} 
d2399a
 
d2399a
 		if (parser->data) {
d2399a
-			zval *tag, *atr;
d2399a
-			int atcnt = 0;
d2399a
+			if (parser->level <= XML_MAXLEVEL)  {
d2399a
+				zval *tag, *atr;
d2399a
+				int atcnt = 0;
d2399a
 
d2399a
-			MAKE_STD_ZVAL(tag);
d2399a
-			MAKE_STD_ZVAL(atr);
d2399a
+				MAKE_STD_ZVAL(tag);
d2399a
+				MAKE_STD_ZVAL(atr);
d2399a
 
d2399a
-			array_init(tag);
d2399a
-			array_init(atr);
d2399a
+				array_init(tag);
d2399a
+				array_init(atr);
d2399a
 
d2399a
-			_xml_add_to_info(parser,((char *) tag_name) + parser->toffset);
d2399a
+				_xml_add_to_info(parser,((char *) tag_name) + parser->toffset);
d2399a
 
d2399a
-			add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */
d2399a
-			add_assoc_string(tag,"type","open",1);
d2399a
-			add_assoc_long(tag,"level",parser->level);
d2399a
+				add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */
d2399a
+				add_assoc_string(tag,"type","open",1);
d2399a
+				add_assoc_long(tag,"level",parser->level);
d2399a
 
d2399a
-			parser->ltags[parser->level-1] = estrdup(tag_name);
d2399a
-			parser->lastwasopen = 1;
d2399a
+				parser->ltags[parser->level-1] = estrdup(tag_name);
d2399a
+				parser->lastwasopen = 1;
d2399a
 
d2399a
-			attributes = (const XML_Char **) attrs;
d2399a
+				attributes = (const XML_Char **) attrs;
d2399a
 
d2399a
-			while (attributes && *attributes) {
d2399a
-				att = _xml_decode_tag(parser, attributes[0]);
d2399a
-				val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding);
d2399a
-				
d2399a
-				add_assoc_stringl(atr,att,val,val_len,0);
d2399a
+				while (attributes && *attributes) {
d2399a
+					att = _xml_decode_tag(parser, attributes[0]);
d2399a
+					val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding);
d2399a
 
d2399a
-				atcnt++;
d2399a
-				attributes += 2;
d2399a
+					add_assoc_stringl(atr,att,val,val_len,0);
d2399a
 
d2399a
-				efree(att);
d2399a
-			}
d2399a
+					atcnt++;
d2399a
+					attributes += 2;
d2399a
 
d2399a
-			if (atcnt) {
d2399a
-				zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL);
d2399a
-			} else {
d2399a
-				zval_ptr_dtor(&atr;;
d2399a
-			}
d2399a
+					efree(att);
d2399a
+				}
d2399a
+
d2399a
+				if (atcnt) {
d2399a
+					zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL);
d2399a
+				} else {
d2399a
+					zval_ptr_dtor(&atr;;
d2399a
+				}
d2399a
 
d2399a
-			zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag);
d2399a
+				zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag);
d2399a
+			} else if (parser->level == (XML_MAXLEVEL + 1)) {
d2399a
+				TSRMLS_FETCH();
d2399a
+				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated");
d2399a
+			}
d2399a
 		}
d2399a
 
d2399a
 		efree(tag_name);
d2399a
@@ -895,7 +900,7 @@ void _xml_endElementHandler(void *userData, const XML_Char *name)
d2399a
 
d2399a
 		efree(tag_name);
d2399a
 
d2399a
-		if (parser->ltags) {
d2399a
+		if ((parser->ltags) && (parser->level <= XML_MAXLEVEL)) {
d2399a
 			efree(parser->ltags[parser->level-1]);
d2399a
 		}
d2399a
 
d2399a
@@ -979,18 +984,23 @@ void _xml_characterDataHandler(void *userData, const XML_Char *s, int len)
d2399a
 						}
d2399a
 					}
d2399a
 
d2399a
-					MAKE_STD_ZVAL(tag);
d2399a
-					
d2399a
-					array_init(tag);
d2399a
-					
d2399a
-					_xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset);
d2399a
+					if (parser->level <= XML_MAXLEVEL) {
d2399a
+						MAKE_STD_ZVAL(tag);
d2399a
 
d2399a
-					add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1);
d2399a
-					add_assoc_string(tag,"value",decoded_value,0);
d2399a
-					add_assoc_string(tag,"type","cdata",1);
d2399a
-					add_assoc_long(tag,"level",parser->level);
d2399a
+						array_init(tag);
d2399a
 
d2399a
-					zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL);
d2399a
+						_xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset);
d2399a
+
d2399a
+						add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1);
d2399a
+						add_assoc_string(tag,"value",decoded_value,0);
d2399a
+						add_assoc_string(tag,"type","cdata",1);
d2399a
+						add_assoc_long(tag,"level",parser->level);
d2399a
+
d2399a
+						zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL);
d2399a
+					} else if (parser->level == (XML_MAXLEVEL + 1)) {
d2399a
+						TSRMLS_FETCH();
d2399a
+						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated");
d2399a
+					}
d2399a
 				}
d2399a
 			} else {
d2399a
 				efree(decoded_value);
d2399a
-- 
d2399a
1.7.11.5
d2399a
d2399a
From 710eee5555bc5c95692bd3c84f5d2b5d687349b6 Mon Sep 17 00:00:00 2001
d2399a
From: =?utf8?q?Johannes=20Schl=C3=BCter?= <johannes@php.net>
d2399a
Date: Wed, 10 Jul 2013 19:35:18 +0200
d2399a
Subject: [PATCH] add test for bug #65236
d2399a
d2399a
---
d2399a
 ext/xml/tests/bug65236.phpt | 15 +++++++++++++++
d2399a
 1 file changed, 15 insertions(+)
d2399a
 create mode 100644 ext/xml/tests/bug65236.phpt
d2399a
d2399a
diff --git a/ext/xml/tests/bug65236.phpt b/ext/xml/tests/bug65236.phpt
d2399a
new file mode 100644
d2399a
index 0000000..67b26d6
d2399a
--- /dev/null
d2399a
+++ b/ext/xml/tests/bug65236.phpt
d2399a
@@ -0,0 +1,15 @@
d2399a
+--TEST--
d2399a
+Bug #65236 (heap corruption in xml parser)
d2399a
+--SKIPIF--
d2399a
+
d2399a
+require_once("skipif.inc");
d2399a
+?>
d2399a
+--FILE--
d2399a
+
d2399a
+xml_parse_into_struct(xml_parser_create_ns(), str_repeat("<blah>", 1000), $a);
d2399a
+
d2399a
+echo "Done\n";
d2399a
+?>
d2399a
+--EXPECTF--
d2399a
+Warning: xml_parse_into_struct(): Maximum depth exceeded - Results truncated in %s on line %d
d2399a
+Done
d2399a
-- 
d2399a
1.7.11.5
d2399a