diff options
author | Stanislav Malyshev <stas@php.net> | 2016-08-04 00:17:42 -0700 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2016-08-16 23:36:14 +0200 |
commit | e3829b88694460a2e5af10ad5eee9966fa55e589 (patch) | |
tree | 1878f7f1403459713a69db12d362b865a14b8eff | |
parent | 24fb60ffe9d23a6af27d96b74a85f6a237bbd14a (diff) | |
download | php-git-e3829b88694460a2e5af10ad5eee9966fa55e589.tar.gz |
Fix bug #72749: wddx_deserialize allows illegal memory access
(cherry picked from commit 659a21dc20f0b64dafd8cb16573059d3b45cce6b)
Conflicts:
ext/wddx/wddx.c
-rw-r--r-- | ext/wddx/tests/bug72749.phpt | 34 | ||||
-rw-r--r-- | ext/wddx/wddx.c | 16 |
2 files changed, 46 insertions, 4 deletions
diff --git a/ext/wddx/tests/bug72749.phpt b/ext/wddx/tests/bug72749.phpt new file mode 100644 index 0000000000..ee17d0f229 --- /dev/null +++ b/ext/wddx/tests/bug72749.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #72749: wddx_deserialize allows illegal memory access +--SKIPIF-- +<?php +if (!extension_loaded('wddx')) { + die('skip. wddx not available'); +} +?> +--FILE-- +<?php +$xml = <<<XML +<?xml version='1.0'?> +<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'> +<wddxPacket version='1.0'> +<header/> + <data> + <struct> + <var name='aDateTime3'> + <dateTime>2\r2004-09-10T05:52:49+00</dateTime> + </var> + </struct> + </data> +</wddxPacket> +XML; + +$array = wddx_deserialize($xml); +var_dump($array); +?> +--EXPECT-- +array(1) { + ["aDateTime3"]=> + string(24) "2 +2004-09-10T05:52:49+00" +} diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index 40b41ba373..a11efe66de 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -1038,14 +1038,22 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len) case ST_DATETIME: { char *tmp; - tmp = emalloc(len + 1); - memcpy(tmp, (char *)s, len); + if (Z_TYPE(ent->data) == IS_STRING) { + tmp = safe_emalloc(Z_STRLEN(ent->data), 1, (size_t)len + 1); + memcpy(tmp, Z_STRVAL(ent->data), Z_STRLEN(ent->data)); + memcpy(tmp + Z_STRLEN(ent->data), s, len); + len += Z_STRLEN(ent->data); + zval_dtor(&ent->data); + } else { + tmp = emalloc(len + 1); + memcpy(tmp, (char *)s, len); + } tmp[len] = '\0'; - Z_LVAL(ent->data) = php_parse_date(tmp, NULL); + ZVAL_LONG(&ent->data, php_parse_date(tmp, NULL)); /* date out of range < 1969 or > 2038 */ if (Z_LVAL(ent->data) == -1) { - ZVAL_STRINGL(&ent->data, (char *)s, len); + ZVAL_STRINGL(&ent->data, (char *)tmp, len); } efree(tmp); } |