Skip to content

Commit db1ef5c

Browse files
committed
Merge branch 'PHP-5.6' into PHP-7.0
2 parents a556543 + 9164dc1 commit db1ef5c

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ PHP NEWS
5757

5858
- XML:
5959
. Fixed bug #72085 (SEGV on unknown address zif_xml_parse). (cmb)
60+
. Fixed bug #72714 (_xml_startElementHandler() segmentation fault). (cmb)
6061

6162
- ZIP:
6263
. Fixed bug #68302 (impossible to compile php with zip support). (cmb)

ext/xml/tests/bug72714.phpt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
Bug #72714 (_xml_startElementHandler() segmentation fault)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('xml')) die('skip xml extension not available');
6+
?>
7+
--FILE--
8+
<?php
9+
function startElement($parser, $name, $attribs) {
10+
var_dump($name);
11+
}
12+
13+
function endElement($parser, $name) {}
14+
15+
function parse($tagstart) {
16+
$xml = '<ns1:total>867</ns1:total>';
17+
18+
$xml_parser = xml_parser_create();
19+
xml_set_element_handler($xml_parser, 'startElement', 'endElement');
20+
21+
xml_parser_set_option($xml_parser, XML_OPTION_SKIP_TAGSTART, $tagstart);
22+
xml_parse($xml_parser, $xml);
23+
24+
xml_parser_free($xml_parser);
25+
}
26+
27+
parse(3015809298423721);
28+
parse(20);
29+
?>
30+
===DONE===
31+
--EXPECTF--
32+
Notice: xml_parser_set_option(): tagstart ignored in %s%ebug72714.php on line %d
33+
string(9) "NS1:TOTAL"
34+
string(0) ""
35+
===DONE===

ext/xml/xml.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ ZEND_GET_MODULE(xml)
6969
#endif /* COMPILE_DL_XML */
7070
/* }}} */
7171

72+
73+
#define SKIP_TAGSTART(str) ((str) + (parser->toffset > strlen(str) ? strlen(str) : + parser->toffset))
74+
75+
7276
/* {{{ function prototypes */
7377
PHP_MINIT_FUNCTION(xml);
7478
PHP_MINFO_FUNCTION(xml);
@@ -729,7 +733,7 @@ void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Ch
729733

730734
if (!Z_ISUNDEF(parser->startElementHandler)) {
731735
ZVAL_COPY(&args[0], &parser->index);
732-
ZVAL_STRING(&args[1], ZSTR_VAL(tag_name) + parser->toffset);
736+
ZVAL_STRING(&args[1], SKIP_TAGSTART(ZSTR_VAL(tag_name)));
733737
array_init(&args[2]);
734738

735739
while (attributes && *attributes) {
@@ -760,7 +764,7 @@ void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Ch
760764

761765
_xml_add_to_info(parser, ZSTR_VAL(tag_name) + parser->toffset);
762766

763-
add_assoc_string(&tag, "tag", ZSTR_VAL(tag_name) + parser->toffset); /* cast to avoid gcc-warning */
767+
add_assoc_string(&tag, "tag", SKIP_TAGSTART(ZSTR_VAL(tag_name))); /* cast to avoid gcc-warning */
764768
add_assoc_string(&tag, "type", "open");
765769
add_assoc_long(&tag, "level", parser->level);
766770

@@ -814,7 +818,7 @@ void _xml_endElementHandler(void *userData, const XML_Char *name)
814818

815819
if (!Z_ISUNDEF(parser->endElementHandler)) {
816820
ZVAL_COPY(&args[0], &parser->index);
817-
ZVAL_STRING(&args[1], ZSTR_VAL(tag_name) + parser->toffset);
821+
ZVAL_STRING(&args[1], SKIP_TAGSTART(ZSTR_VAL(tag_name)));
818822

819823
xml_call_handler(parser, &parser->endElementHandler, parser->endElementPtr, 2, args, &retval);
820824
zval_ptr_dtor(&retval);
@@ -830,7 +834,7 @@ void _xml_endElementHandler(void *userData, const XML_Char *name)
830834

831835
_xml_add_to_info(parser, ZSTR_VAL(tag_name) + parser->toffset);
832836

833-
add_assoc_string(&tag, "tag", ZSTR_VAL(tag_name) + parser->toffset); /* cast to avoid gcc-warning */
837+
add_assoc_string(&tag, "tag", SKIP_TAGSTART(ZSTR_VAL(tag_name))); /* cast to avoid gcc-warning */
834838
add_assoc_string(&tag, "type", "close");
835839
add_assoc_long(&tag, "level", parser->level);
836840

@@ -924,9 +928,9 @@ void _xml_characterDataHandler(void *userData, const XML_Char *s, int len)
924928
if (parser->level <= XML_MAXLEVEL && parser->level > 0) {
925929
array_init(&tag);
926930

927-
_xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset);
931+
_xml_add_to_info(parser,SKIP_TAGSTART(parser->ltags[parser->level-1]));
928932

929-
add_assoc_string(&tag, "tag", parser->ltags[parser->level-1] + parser->toffset);
933+
add_assoc_string(&tag, "tag", SKIP_TAGSTART(parser->ltags[parser->level-1]));
930934
add_assoc_str(&tag, "value", decoded_value);
931935
add_assoc_string(&tag, "type", "cdata");
932936
add_assoc_long(&tag, "level", parser->level);
@@ -1605,6 +1609,10 @@ PHP_FUNCTION(xml_parser_set_option)
16051609
case PHP_XML_OPTION_SKIP_TAGSTART:
16061610
convert_to_long_ex(val);
16071611
parser->toffset = Z_LVAL_P(val);
1612+
if (parser->toffset < 0) {
1613+
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "tagstart ignored");
1614+
parser->toffset = 0;
1615+
}
16081616
break;
16091617
case PHP_XML_OPTION_SKIP_WHITE:
16101618
convert_to_long_ex(val);

0 commit comments

Comments
 (0)