Skip to content

Commit

Permalink
Fix bug #73065: Out-Of-Bounds Read in php_wddx_push_element of wddx.c
Browse files Browse the repository at this point in the history
  • Loading branch information
smalyshev committed Sep 13, 2016
1 parent f5a9592 commit c4cca4c
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 9 deletions.
98 changes: 98 additions & 0 deletions ext/wddx/tests/bug73065.phpt
Original file line number Diff line number Diff line change
@@ -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
19 changes: 10 additions & 9 deletions ext/wddx/wddx.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,10 +780,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(atts[i], EL_CHAR_CODE) && atts[++i] && atts[i][0]) {
if (!strcmp(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(atts[i], NULL, 16));
snprintf(tmp_buf, sizeof(tmp_buf), "%c", (char)strtol(atts[i+1], NULL, 16));
php_wddx_process_data(user_data, tmp_buf, strlen(tmp_buf));
break;
}
Expand All @@ -801,15 +801,15 @@ 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(atts[i], EL_VALUE) && atts[++i] && atts[i][0]) {
if (!strcmp(atts[i], EL_VALUE) && atts[i+1] && atts[i+1][0]) {
ent.type = ST_BOOLEAN;
SET_STACK_VARNAME;

ALLOC_ZVAL(ent.data);
INIT_PZVAL(ent.data);
Z_TYPE_P(ent.data) = IS_BOOL;
wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
php_wddx_process_data(user_data, atts[i], strlen(atts[i]));
php_wddx_process_data(user_data, atts[i+1], strlen(atts[i+1]));
break;
}
}
Expand Down Expand Up @@ -842,9 +842,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(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
if (!strcmp(atts[i], EL_NAME) && atts[i+1] && atts[i+1][0]) {
if (stack->varname) efree(stack->varname);
stack->varname = estrdup(atts[i]);
stack->varname = estrdup(atts[i+1]);
break;
}
}
Expand All @@ -857,11 +857,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(atts[i], "fieldNames") && atts[++i] && atts[i][0]) {
if (!strcmp(atts[i], "fieldNames") && atts[i+1] && atts[i+1][0]) {
zval *tmp;
char *key;
char *p1, *p2, *endp;

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

if (atts) for (i = 0; atts[i]; i++) {
if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
if (!strcmp(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 &&
zend_hash_find(Z_ARRVAL_P(recordset->data), (char*)atts[i], strlen(atts[i])+1, (void**)&field) == SUCCESS) {
zend_hash_find(Z_ARRVAL_P(recordset->data), (char*)atts[i+1], strlen(atts[i+1])+1, (void**)&field) == SUCCESS) {
ent.data = *field;
}

Expand Down

0 comments on commit c4cca4c

Please sign in to comment.