com php-src: Fix bug #73331 - do not try to serialize/unserialize objects wddx can not handle: ext/pdo/pdo_stmt.c ext/wddx/tests/bu g45901.phpt
ext/wddx/tests/bug72790.p hpt ext/wddx/tests/bug73331.phpt ext/wddx/wddx .c
| From: | Anatol Belski | Date: | Tue, 08 Nov 2016 11:58:56 +0000 |
| Subject: | com php-src: Fix bug #73331 - do not try to serialize/unserialize objects wddx can not handle: ext/pdo/pdo_stmt.c ext/wddx/tests/bu g45901.phpt ext/wddx/tests/bug72790.p hpt ext/wddx/tests/bug73331.phpt ext/wddx/wddx .c |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-95452@lists.php.net to get a copy of this message | ||
Commit: 9e1bc792df55712850b705d2d1379742a37c7c4a
Author: Stanislav Malyshev <stas@php.net> Sun, 23 Oct 2016 20:07:47 -0700
Committer: Anatol Belski <ab@php.net> Tue, 8 Nov 2016 12:58:56 +0100
Parents: 3106f0e746a6fdea07fbd3aa22ed01d1b70816f0
Branches: PHP-7.0.13
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=9e1bc792df55712850b705d2d1379742a37c7c4a
Log:
Fix bug #73331 - do not try to serialize/unserialize objects wddx can not handle
Proper soltion would be to call serialize/unserialize and deal with the result,
but this requires more work that should be done by wddx maintainer (not me).
(cherry picked from commit 6045de69c7dedcba3eadf7c4bba424b19c81d00d)
Conflicts:
ext/wddx/wddx.c
(cherry picked from commit 8c67460a10865f53435c705d08bbc2d60a49f781)
Bugs:
https://bugs.php.net/73331
Changed paths:
M ext/pdo/pdo_stmt.c
M ext/wddx/tests/bug45901.phpt
M ext/wddx/tests/bug72790.phpt
A ext/wddx/tests/bug73331.phpt
M ext/wddx/wddx.c
Diff:
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index d135467..0ff8a04 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -2299,6 +2299,7 @@ void pdo_stmt_init(void)
pdo_row_ce->ce_flags |= ZEND_ACC_FINAL; /* when removing this a lot of handlers need to be
redone */
pdo_row_ce->create_object = pdo_row_new;
pdo_row_ce->serialize = pdo_row_serialize;
+ pdo_row_ce->unserialize = zend_class_unserialize_deny;
}
PDO_API void php_pdo_free_statement(pdo_stmt_t *stmt)
diff --git a/ext/wddx/tests/bug45901.phpt b/ext/wddx/tests/bug45901.phpt
index 4084ccb..e76e47e 100644
--- a/ext/wddx/tests/bug45901.phpt
+++ b/ext/wddx/tests/bug45901.phpt
@@ -14,5 +14,7 @@ echo wddx_serialize_value($xml, 'Variables') . "\n";
echo "DONE";
?>
--EXPECTF--
-<wddxPacket
version='1.0'><header><comment>Variables</comment></header><data><struct><var
name='php_class_name'><string>SimpleXMLElement</string></var><var
name='test'><struct><var
name='php_class_name'><string>SimpleXMLElement</string></var></struct></var></struct></data></wddxPacket>
+
+Warning: wddx_serialize_value(): Class SimpleXMLElement can not be serialized in %sbug45901.php on
line %d
+<wddxPacket
version='1.0'><header><comment>Variables</comment></header><data></data></wddxPacket>
DONE
\ No newline at end of file
diff --git a/ext/wddx/tests/bug72790.phpt b/ext/wddx/tests/bug72790.phpt
index a60524b..3b08e58 100644
--- a/ext/wddx/tests/bug72790.phpt
+++ b/ext/wddx/tests/bug72790.phpt
@@ -1,5 +1,5 @@
--TEST--
-Bug 72790: wddx_deserialize null dereference with invalid xml
+Bug #72790: wddx_deserialize null dereference with invalid xml
--SKIPIF--
<?php
if (!extension_loaded('wddx')) {
diff --git a/ext/wddx/tests/bug73331.phpt b/ext/wddx/tests/bug73331.phpt
new file mode 100644
index 0000000..7e4cda1
--- /dev/null
+++ b/ext/wddx/tests/bug73331.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Bug #73331 (NULL Pointer Dereference in WDDX Packet Deserialization with PDORow)
+--SKIPIF--
+<?php if (!extension_loaded("wddx") || !extension_loaded("pdo")) print
"skip"; ?>
+--FILE--
+<?php
+
+$wddx = "<wddxPacket
version='1.0'><header/><data><struct><var
name='php_class_name'><string>PDORow</string></var></struct></data></wddxPacket>";
+var_dump(wddx_deserialize($wddx));
+?>
+--EXPECTF--
+
+Warning: wddx_deserialize(): Class pdorow can not be unserialized in %s73331.php on line %d
+NULL
+
diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
index 7d805e4..11b66f1 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -453,6 +453,16 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
zend_ulong idx;
char tmp_buf[WDDX_BUF_LEN];
HashTable *objhash, *sleephash;
+ zend_class_entry *ce;
+ PHP_CLASS_ATTRIBUTES;
+
+ PHP_SET_CLASS_ATTRIBUTES(obj);
+ ce = Z_OBJCE_P(obj);
+ if (!ce || ce->serialize || ce->unserialize) {
+ php_error_docref(NULL, E_WARNING, "Class %s can not be serialized",
ZSTR_VAL(class_name));
+ PHP_CLEANUP_CLASS_ATTRIBUTES();
+ return;
+ }
ZVAL_STRING(&fname, "__sleep");
/*
@@ -473,8 +483,6 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
php_wddx_add_chunk_static(packet, WDDX_STRING_E);
php_wddx_add_chunk_static(packet, WDDX_VAR_E);
- PHP_CLEANUP_CLASS_ATTRIBUTES();
-
objhash = Z_OBJPROP_P(obj);
ZEND_HASH_FOREACH_VAL(sleephash, varname) {
@@ -491,9 +499,7 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
}
} else {
- PHP_CLASS_ATTRIBUTES;
-
- PHP_SET_CLASS_ATTRIBUTES(obj);
+ uint key_len;
php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
snprintf(tmp_buf, WDDX_BUF_LEN, WDDX_VAR_S, PHP_CLASS_NAME_VAR);
@@ -503,8 +509,6 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
php_wddx_add_chunk_static(packet, WDDX_STRING_E);
php_wddx_add_chunk_static(packet, WDDX_VAR_E);
- PHP_CLEANUP_CLASS_ATTRIBUTES();
-
objhash = Z_OBJPROP_P(obj);
ZEND_HASH_FOREACH_KEY_VAL(objhash, idx, key, ent) {
if (ent == obj) {
@@ -528,6 +532,8 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
}
+ PHP_CLEANUP_CLASS_ATTRIBUTES();
+
zval_ptr_dtor(&fname);
zval_ptr_dtor(&retval);
}
@@ -947,23 +953,28 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
pce = PHP_IC_ENTRY;
}
- /* Initialize target object */
- object_init_ex(&obj, pce);
+ if (pce != PHP_IC_ENTRY && (pce->serialize || pce->unserialize)) {
+ ZVAL_UNDEF(&ent2->data);
+ php_error_docref(NULL, E_WARNING, "Class %s can not be unserialized",
Z_STRVAL(ent1->data));
+ } else {
+ /* Initialize target object */
+ object_init_ex(&obj, pce);
- /* Merge current hashtable with object's default properties */
- zend_hash_merge(Z_OBJPROP(obj),
- Z_ARRVAL(ent2->data),
- zval_add_ref, 0);
+ /* Merge current hashtable with object's default properties */
+ zend_hash_merge(Z_OBJPROP(obj),
+ Z_ARRVAL(ent2->data),
+ zval_add_ref, 0);
- if (incomplete_class) {
- php_store_class_name(&obj, Z_STRVAL(ent1->data), Z_STRLEN(ent1->data));
- }
+ if (incomplete_class) {
+ php_store_class_name(&obj, Z_STRVAL(ent1->data), Z_STRLEN(ent1->data));
+ }
- /* Clean up old array entry */
- zval_ptr_dtor(&ent2->data);
+ /* Clean up old array entry */
+ zval_ptr_dtor(&ent2->data);
- /* Set stack entry to point to the newly created object */
- ZVAL_COPY_VALUE(&ent2->data, &obj);
+ /* Set stack entry to point to the newly created object */
+ ZVAL_COPY_VALUE(&ent2->data, &obj);
+ }
/* Clean up class name var entry */
zval_ptr_dtor(&ent1->data);