diff options
author | Stanislav Malyshev <stas@php.net> | 2016-09-12 00:35:01 -0700 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2016-09-12 18:13:04 +0200 |
commit | 9528ce73156e2b6a5e96e371068b24a5975f4bcd (patch) | |
tree | 6ec912ffe0ccbeab33fde03c2babb3559bacbb38 | |
parent | c5f34c9eca28769a3cc385501ee55bf153028dc4 (diff) | |
download | php-git-9528ce73156e2b6a5e96e371068b24a5975f4bcd.tar.gz |
Fix bug #73065: Out-Of-Bounds Read in php_wddx_push_element of wddx.c
(cherry picked from commit bbaf784f8d213e201baf67e861f20b38c6e87d3b)
Conflicts:
ext/wddx/wddx.c
-rw-r--r-- | ext/wddx/tests/bug73065.phpt | 98 | ||||
-rw-r--r-- | ext/wddx/wddx.c | 19 |
2 files changed, 108 insertions, 9 deletions
diff --git a/ext/wddx/tests/bug73065.phpt b/ext/wddx/tests/bug73065.phpt new file mode 100644 index 0000000000..aa301aa838 --- /dev/null +++ b/ext/wddx/tests/bug73065.phpt @@ -0,0 +1,98 @@ +--TEST-- +Bug #73065: Out-Of-Bounds Read in php_wddx_push_element of wddx.c +--SKIPIF-- +<?php +if (!extension_loaded('wddx')) { + die('skip. wddx not available'); +} +?> +--FILE-- +<?php + +$xml1 = <<<XML +<?xml version='1.0' ?> + <!DOCTYPE et SYSTEM 'w'> + <wddxPacket ven='1.0'> + <array> + <var Name="name"> + <boolean value="keliu"></boolean> + </var> + <var name="1111"> + <var name="2222"> + <var name="3333"></var> + </var> + </var> + </array> + </wddxPacket> +XML; + +$xml2 = <<<XML +<?xml version='1.0' ?> + <!DOCTYPE et SYSTEM 'w'> + <wddxPacket ven='1.0'> + <array> + <char Name="code"> + <boolean value="keliu"></boolean> + </char> + </array> + </wddxPacket> +XML; + +$xml3 = <<<XML +<?xml version='1.0' ?> + <!DOCTYPE et SYSTEM 'w'> + <wddxPacket ven='1.0'> + <array> + <boolean Name="value"> + <boolean value="keliu"></boolean> + </boolean> + </array> + </wddxPacket> +XML; + +$xml4 = <<<XML +<?xml version='1.0' ?> + <!DOCTYPE et SYSTEM 'w'> + <wddxPacket ven='1.0'> + <array> + <recordset Name="fieldNames"> + <boolean value="keliu"></boolean> + </recordset> + </array> + </wddxPacket> +XML; + +$xml5 = <<<XML +<?xml version='1.0' ?> + <!DOCTYPE et SYSTEM 'w'> + <wddxPacket ven='1.0'> + <array> + <field Name="name"> + <boolean value="keliu"></boolean> + </field> + </array> + </wddxPacket> +XML; + +for($i=1;$i<=5;$i++) { + $xmlvar = "xml$i"; + $array = wddx_deserialize($$xmlvar); + var_dump($array); +} +?> +DONE +--EXPECTF-- +array(0) { +} +array(0) { +} +array(0) { +} +array(1) { + [0]=> + array(0) { + } +} +array(0) { +} +DONE
\ No newline at end of file diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index ecbe153814..7d805e484f 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -741,10 +741,10 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X int i; if (atts) for (i = 0; atts[i]; i++) { - if (!strcmp((char *)atts[i], EL_CHAR_CODE) && atts[++i] && atts[i][0]) { + if (!strcmp((char *)atts[i], EL_CHAR_CODE) && atts[i+1] && atts[i+1][0]) { char tmp_buf[2]; - snprintf(tmp_buf, sizeof(tmp_buf), "%c", (char)strtol((char *)atts[i], NULL, 16)); + snprintf(tmp_buf, sizeof(tmp_buf), "%c", (char)strtol((char *)atts[i+1], NULL, 16)); php_wddx_process_data(user_data, (XML_Char *) tmp_buf, strlen(tmp_buf)); break; } @@ -759,13 +759,13 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X int i; if (atts) for (i = 0; atts[i]; i++) { - if (!strcmp((char *)atts[i], EL_VALUE) && atts[++i] && atts[i][0]) { + if (!strcmp((char *)atts[i], EL_VALUE) && atts[i+1] && atts[i+1][0]) { ent.type = ST_BOOLEAN; SET_STACK_VARNAME; ZVAL_TRUE(&ent.data); wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry)); - php_wddx_process_data(user_data, atts[i], strlen((char *)atts[i])); + php_wddx_process_data(user_data, atts[i+1], strlen((char *)atts[i+1])); break; } } @@ -791,9 +791,9 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X int i; if (atts) for (i = 0; atts[i]; i++) { - if (!strcmp((char *)atts[i], EL_NAME) && atts[++i] && atts[i][0]) { + if (!strcmp((char *)atts[i], EL_NAME) && atts[i+1] && atts[i+1][0]) { if (stack->varname) efree(stack->varname); - stack->varname = estrdup((char *)atts[i]); + stack->varname = estrdup((char *)atts[i+1]); break; } } @@ -805,11 +805,12 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X array_init(&ent.data); if (atts) for (i = 0; atts[i]; i++) { - if (!strcmp((char *)atts[i], "fieldNames") && atts[++i] && atts[i][0]) { + if (!strcmp((char *)atts[i], "fieldNames") && atts[i+1] && atts[i+1][0]) { zval tmp; char *key; const char *p1, *p2, *endp; + i++; endp = (char *)atts[i] + strlen((char *)atts[i]); p1 = (char *)atts[i]; while ((p2 = php_memnstr(p1, ",", sizeof(",")-1, endp)) != NULL) { @@ -839,13 +840,13 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X ZVAL_UNDEF(&ent.data); if (atts) for (i = 0; atts[i]; i++) { - if (!strcmp((char *)atts[i], EL_NAME) && atts[++i] && atts[i][0]) { + if (!strcmp((char *)atts[i], EL_NAME) && atts[i+1] && atts[i+1][0]) { st_entry *recordset; zval *field; if (wddx_stack_top(stack, (void**)&recordset) == SUCCESS && recordset->type == ST_RECORDSET && - (field = zend_hash_str_find(Z_ARRVAL(recordset->data), (char*)atts[i], strlen((char *)atts[i]))) != NULL) { + (field = zend_hash_str_find(Z_ARRVAL(recordset->data), (char*)atts[i+1], strlen((char *)atts[i+1]))) != NULL) { ZVAL_COPY_VALUE(&ent.data, field); } |