]> granicus.if.org Git - php/commitdiff
Fix bug #73065: Out-Of-Bounds Read in php_wddx_push_element of wddx.c
authorStanislav Malyshev <stas@php.net>
Mon, 12 Sep 2016 07:35:01 +0000 (00:35 -0700)
committerAnatol Belski <ab@php.net>
Mon, 12 Sep 2016 16:13:04 +0000 (18:13 +0200)
(cherry picked from commit bbaf784f8d213e201baf67e861f20b38c6e87d3b)

Conflicts:
ext/wddx/wddx.c

ext/wddx/tests/bug73065.phpt [new file with mode: 0644]
ext/wddx/wddx.c

diff --git a/ext/wddx/tests/bug73065.phpt b/ext/wddx/tests/bug73065.phpt
new file mode 100644 (file)
index 0000000..aa301aa
--- /dev/null
@@ -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
index ecbe153814c8cef90569f45a75db4ab5accbc863..7d805e484f27e6dbda86a4f66a16976c4249813b 100644 (file)
@@ -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);
                                }