1 |
From 7d163e8a0880ae8af2dd869071393e5dc07ef271 Mon Sep 17 00:00:00 2001 |
2 |
From: Rob Richards <rrichards@php.net> |
3 |
Date: Sat, 6 Jul 2013 07:53:07 -0400 |
4 |
Subject: [PATCH] truncate results at depth of 255 to prevent corruption |
5 |
|
6 |
--- |
7 |
ext/xml/xml.c | 90 +++++++++++++++++++++++++++++++++-------------------------- |
8 |
1 file changed, 50 insertions(+), 40 deletions(-) |
9 |
|
10 |
diff --git a/ext/xml/xml.c b/ext/xml/xml.c |
11 |
index 1f0480b..9f0bc30 100644 |
12 |
--- a/ext/xml/xml.c |
13 |
+++ b/ext/xml/xml.c |
14 |
@@ -427,7 +427,7 @@ static void xml_parser_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) |
15 |
} |
16 |
if (parser->ltags) { |
17 |
int inx; |
18 |
- for (inx = 0; inx < parser->level; inx++) |
19 |
+ for (inx = 0; ((inx < parser->level) && (inx < XML_MAXLEVEL)); inx++) |
20 |
efree(parser->ltags[ inx ]); |
21 |
efree(parser->ltags); |
22 |
} |
23 |
@@ -905,45 +905,50 @@ void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Ch |
24 |
} |
25 |
|
26 |
if (parser->data) { |
27 |
- zval *tag, *atr; |
28 |
- int atcnt = 0; |
29 |
+ if (parser->level <= XML_MAXLEVEL) { |
30 |
+ zval *tag, *atr; |
31 |
+ int atcnt = 0; |
32 |
|
33 |
- MAKE_STD_ZVAL(tag); |
34 |
- MAKE_STD_ZVAL(atr); |
35 |
+ MAKE_STD_ZVAL(tag); |
36 |
+ MAKE_STD_ZVAL(atr); |
37 |
|
38 |
- array_init(tag); |
39 |
- array_init(atr); |
40 |
+ array_init(tag); |
41 |
+ array_init(atr); |
42 |
|
43 |
- _xml_add_to_info(parser,((char *) tag_name) + parser->toffset); |
44 |
+ _xml_add_to_info(parser,((char *) tag_name) + parser->toffset); |
45 |
|
46 |
- add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */ |
47 |
- add_assoc_string(tag,"type","open",1); |
48 |
- add_assoc_long(tag,"level",parser->level); |
49 |
+ add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */ |
50 |
+ add_assoc_string(tag,"type","open",1); |
51 |
+ add_assoc_long(tag,"level",parser->level); |
52 |
|
53 |
- parser->ltags[parser->level-1] = estrdup(tag_name); |
54 |
- parser->lastwasopen = 1; |
55 |
+ parser->ltags[parser->level-1] = estrdup(tag_name); |
56 |
+ parser->lastwasopen = 1; |
57 |
|
58 |
- attributes = (const XML_Char **) attrs; |
59 |
+ attributes = (const XML_Char **) attrs; |
60 |
|
61 |
- while (attributes && *attributes) { |
62 |
- att = _xml_decode_tag(parser, attributes[0]); |
63 |
- val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding); |
64 |
- |
65 |
- add_assoc_stringl(atr,att,val,val_len,0); |
66 |
+ while (attributes && *attributes) { |
67 |
+ att = _xml_decode_tag(parser, attributes[0]); |
68 |
+ val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding); |
69 |
|
70 |
- atcnt++; |
71 |
- attributes += 2; |
72 |
+ add_assoc_stringl(atr,att,val,val_len,0); |
73 |
|
74 |
- efree(att); |
75 |
- } |
76 |
+ atcnt++; |
77 |
+ attributes += 2; |
78 |
|
79 |
- if (atcnt) { |
80 |
- zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL); |
81 |
- } else { |
82 |
- zval_ptr_dtor(&atr); |
83 |
- } |
84 |
+ efree(att); |
85 |
+ } |
86 |
+ |
87 |
+ if (atcnt) { |
88 |
+ zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL); |
89 |
+ } else { |
90 |
+ zval_ptr_dtor(&atr); |
91 |
+ } |
92 |
|
93 |
- zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag); |
94 |
+ zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag); |
95 |
+ } else if (parser->level == (XML_MAXLEVEL + 1)) { |
96 |
+ TSRMLS_FETCH(); |
97 |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated"); |
98 |
+ } |
99 |
} |
100 |
|
101 |
efree(tag_name); |
102 |
@@ -995,7 +1000,7 @@ void _xml_endElementHandler(void *userData, const XML_Char *name) |
103 |
|
104 |
efree(tag_name); |
105 |
|
106 |
- if (parser->ltags) { |
107 |
+ if ((parser->ltags) && (parser->level <= XML_MAXLEVEL)) { |
108 |
efree(parser->ltags[parser->level-1]); |
109 |
} |
110 |
|
111 |
@@ -1079,18 +1084,23 @@ void _xml_characterDataHandler(void *userData, const XML_Char *s, int len) |
112 |
} |
113 |
} |
114 |
|
115 |
- MAKE_STD_ZVAL(tag); |
116 |
- |
117 |
- array_init(tag); |
118 |
- |
119 |
- _xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset); |
120 |
+ if (parser->level <= XML_MAXLEVEL) { |
121 |
+ MAKE_STD_ZVAL(tag); |
122 |
|
123 |
- add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1); |
124 |
- add_assoc_string(tag,"value",decoded_value,0); |
125 |
- add_assoc_string(tag,"type","cdata",1); |
126 |
- add_assoc_long(tag,"level",parser->level); |
127 |
+ array_init(tag); |
128 |
|
129 |
- zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL); |
130 |
+ _xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset); |
131 |
+ |
132 |
+ add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1); |
133 |
+ add_assoc_string(tag,"value",decoded_value,0); |
134 |
+ add_assoc_string(tag,"type","cdata",1); |
135 |
+ add_assoc_long(tag,"level",parser->level); |
136 |
+ |
137 |
+ zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL); |
138 |
+ } else if (parser->level == (XML_MAXLEVEL + 1)) { |
139 |
+ TSRMLS_FETCH(); |
140 |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated"); |
141 |
+ } |
142 |
} |
143 |
} else { |
144 |
efree(decoded_value); |
145 |
-- |
146 |
1.7.11.5 |
147 |
|
148 |
From 710eee5555bc5c95692bd3c84f5d2b5d687349b6 Mon Sep 17 00:00:00 2001 |
149 |
From: =?utf8?q?Johannes=20Schl=C3=BCter?= <johannes@php.net> |
150 |
Date: Wed, 10 Jul 2013 19:35:18 +0200 |
151 |
Subject: [PATCH] add test for bug #65236 |
152 |
|
153 |
--- |
154 |
ext/xml/tests/bug65236.phpt | 15 +++++++++++++++ |
155 |
1 file changed, 15 insertions(+) |
156 |
create mode 100644 ext/xml/tests/bug65236.phpt |
157 |
|
158 |
diff --git a/ext/xml/tests/bug65236.phpt b/ext/xml/tests/bug65236.phpt |
159 |
new file mode 100644 |
160 |
index 0000000..67b26d6 |
161 |
--- /dev/null |
162 |
+++ b/ext/xml/tests/bug65236.phpt |
163 |
@@ -0,0 +1,15 @@ |
164 |
+--TEST-- |
165 |
+Bug #65236 (heap corruption in xml parser) |
166 |
+--SKIPIF-- |
167 |
+<?php |
168 |
+require_once("skipif.inc"); |
169 |
+?> |
170 |
+--FILE-- |
171 |
+<?php |
172 |
+xml_parse_into_struct(xml_parser_create_ns(), str_repeat("<blah>", 1000), $a); |
173 |
+ |
174 |
+echo "Done\n"; |
175 |
+?> |
176 |
+--EXPECTF-- |
177 |
+Warning: xml_parse_into_struct(): Maximum depth exceeded - Results truncated in %s on line %d |
178 |
+Done |
179 |
-- |
180 |
1.7.11.5 |
181 |
|