Skip to content

Commit c4cca4c

Browse files
committed
Fix bug #73065: Out-Of-Bounds Read in php_wddx_push_element of wddx.c
1 parent f5a9592 commit c4cca4c

File tree

2 files changed

+108
-9
lines changed

2 files changed

+108
-9
lines changed

Diff for: ext/wddx/tests/bug73065.phpt

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
--TEST--
2+
Bug #73065: Out-Of-Bounds Read in php_wddx_push_element of wddx.c
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('wddx')) {
6+
die('skip. wddx not available');
7+
}
8+
?>
9+
--FILE--
10+
<?php
11+
12+
$xml1 = <<<XML
13+
<?xml version='1.0' ?>
14+
<!DOCTYPE et SYSTEM 'w'>
15+
<wddxPacket ven='1.0'>
16+
<array>
17+
<var Name="name">
18+
<boolean value="keliu"></boolean>
19+
</var>
20+
<var name="1111">
21+
<var name="2222">
22+
<var name="3333"></var>
23+
</var>
24+
</var>
25+
</array>
26+
</wddxPacket>
27+
XML;
28+
29+
$xml2 = <<<XML
30+
<?xml version='1.0' ?>
31+
<!DOCTYPE et SYSTEM 'w'>
32+
<wddxPacket ven='1.0'>
33+
<array>
34+
<char Name="code">
35+
<boolean value="keliu"></boolean>
36+
</char>
37+
</array>
38+
</wddxPacket>
39+
XML;
40+
41+
$xml3 = <<<XML
42+
<?xml version='1.0' ?>
43+
<!DOCTYPE et SYSTEM 'w'>
44+
<wddxPacket ven='1.0'>
45+
<array>
46+
<boolean Name="value">
47+
<boolean value="keliu"></boolean>
48+
</boolean>
49+
</array>
50+
</wddxPacket>
51+
XML;
52+
53+
$xml4 = <<<XML
54+
<?xml version='1.0' ?>
55+
<!DOCTYPE et SYSTEM 'w'>
56+
<wddxPacket ven='1.0'>
57+
<array>
58+
<recordset Name="fieldNames">
59+
<boolean value="keliu"></boolean>
60+
</recordset>
61+
</array>
62+
</wddxPacket>
63+
XML;
64+
65+
$xml5 = <<<XML
66+
<?xml version='1.0' ?>
67+
<!DOCTYPE et SYSTEM 'w'>
68+
<wddxPacket ven='1.0'>
69+
<array>
70+
<field Name="name">
71+
<boolean value="keliu"></boolean>
72+
</field>
73+
</array>
74+
</wddxPacket>
75+
XML;
76+
77+
for($i=1;$i<=5;$i++) {
78+
$xmlvar = "xml$i";
79+
$array = wddx_deserialize($$xmlvar);
80+
var_dump($array);
81+
}
82+
?>
83+
DONE
84+
--EXPECTF--
85+
array(0) {
86+
}
87+
array(0) {
88+
}
89+
array(0) {
90+
}
91+
array(1) {
92+
[0]=>
93+
array(0) {
94+
}
95+
}
96+
array(0) {
97+
}
98+
DONE

Diff for: ext/wddx/wddx.c

+10-9
Original file line numberDiff line numberDiff line change
@@ -780,10 +780,10 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X
780780
int i;
781781

782782
if (atts) for (i = 0; atts[i]; i++) {
783-
if (!strcmp(atts[i], EL_CHAR_CODE) && atts[++i] && atts[i][0]) {
783+
if (!strcmp(atts[i], EL_CHAR_CODE) && atts[i+1] && atts[i+1][0]) {
784784
char tmp_buf[2];
785785

786-
snprintf(tmp_buf, sizeof(tmp_buf), "%c", (char)strtol(atts[i], NULL, 16));
786+
snprintf(tmp_buf, sizeof(tmp_buf), "%c", (char)strtol(atts[i+1], NULL, 16));
787787
php_wddx_process_data(user_data, tmp_buf, strlen(tmp_buf));
788788
break;
789789
}
@@ -801,15 +801,15 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X
801801
int i;
802802

803803
if (atts) for (i = 0; atts[i]; i++) {
804-
if (!strcmp(atts[i], EL_VALUE) && atts[++i] && atts[i][0]) {
804+
if (!strcmp(atts[i], EL_VALUE) && atts[i+1] && atts[i+1][0]) {
805805
ent.type = ST_BOOLEAN;
806806
SET_STACK_VARNAME;
807807

808808
ALLOC_ZVAL(ent.data);
809809
INIT_PZVAL(ent.data);
810810
Z_TYPE_P(ent.data) = IS_BOOL;
811811
wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
812-
php_wddx_process_data(user_data, atts[i], strlen(atts[i]));
812+
php_wddx_process_data(user_data, atts[i+1], strlen(atts[i+1]));
813813
break;
814814
}
815815
}
@@ -842,9 +842,9 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X
842842
int i;
843843

844844
if (atts) for (i = 0; atts[i]; i++) {
845-
if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
845+
if (!strcmp(atts[i], EL_NAME) && atts[i+1] && atts[i+1][0]) {
846846
if (stack->varname) efree(stack->varname);
847-
stack->varname = estrdup(atts[i]);
847+
stack->varname = estrdup(atts[i+1]);
848848
break;
849849
}
850850
}
@@ -857,11 +857,12 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X
857857
array_init(ent.data);
858858

859859
if (atts) for (i = 0; atts[i]; i++) {
860-
if (!strcmp(atts[i], "fieldNames") && atts[++i] && atts[i][0]) {
860+
if (!strcmp(atts[i], "fieldNames") && atts[i+1] && atts[i+1][0]) {
861861
zval *tmp;
862862
char *key;
863863
char *p1, *p2, *endp;
864864

865+
i++;
865866
endp = (char *)atts[i] + strlen(atts[i]);
866867
p1 = (char *)atts[i];
867868
while ((p2 = php_memnstr(p1, ",", sizeof(",")-1, endp)) != NULL) {
@@ -893,13 +894,13 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X
893894
ent.data = NULL;
894895

895896
if (atts) for (i = 0; atts[i]; i++) {
896-
if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
897+
if (!strcmp(atts[i], EL_NAME) && atts[i+1] && atts[i+1][0]) {
897898
st_entry *recordset;
898899
zval **field;
899900

900901
if (wddx_stack_top(stack, (void**)&recordset) == SUCCESS &&
901902
recordset->type == ST_RECORDSET &&
902-
zend_hash_find(Z_ARRVAL_P(recordset->data), (char*)atts[i], strlen(atts[i])+1, (void**)&field) == SUCCESS) {
903+
zend_hash_find(Z_ARRVAL_P(recordset->data), (char*)atts[i+1], strlen(atts[i+1])+1, (void**)&field) == SUCCESS) {
903904
ent.data = *field;
904905
}
905906

0 commit comments

Comments
 (0)