summaryrefslogtreecommitdiffstats
path: root/bug73331.patch
blob: e49be37d209c02246a4d967eb825c42c8025d411 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
Backported from 5.6.28 by Remi.


From 0cd5cdeb04946f4fa2f6613220deb6c82ea71ff7 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Sun, 23 Oct 2016 20:07:47 -0700
Subject: [PATCH] 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).
---
 ext/pdo/pdo_stmt.c           |  1 +
 ext/wddx/tests/bug45901.phpt |  4 ++-
 ext/wddx/tests/bug72790.phpt |  2 +-
 ext/wddx/tests/bug73331.phpt | 15 ++++++++++
 ext/wddx/wddx.c              | 67 +++++++++++++++++++++++---------------------
 5 files changed, 55 insertions(+), 34 deletions(-)
 create mode 100644 ext/wddx/tests/bug73331.phpt

diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index f5c295c..9f9ada9 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -2355,6 +2355,7 @@ void pdo_stmt_init(TSRMLS_D)
 	pdo_row_ce->ce_flags |= ZEND_ACC_FINAL_CLASS; /* 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;
 }
 
 static void free_statement(pdo_stmt_t *stmt TSRMLS_DC)
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 0e77826..59cc8dd 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -465,21 +465,26 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
 	ulong idx;
 	char tmp_buf[WDDX_BUF_LEN];
 	HashTable *objhash, *sleephash;
+	zend_class_entry *ce;
+	PHP_CLASS_ATTRIBUTES;
 	TSRMLS_FETCH();
 
+	PHP_SET_CLASS_ATTRIBUTES(obj);
+	ce = Z_OBJCE_P(obj);
+	if (!ce || ce->serialize || ce->unserialize) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class %s can not be serialized", class_name);
+		PHP_CLEANUP_CLASS_ATTRIBUTES();
+		return;
+	}
+
 	MAKE_STD_ZVAL(fname);
 	ZVAL_STRING(fname, "__sleep", 1);
-
 	/*
 	 * We try to call __sleep() method on object. It's supposed to return an
 	 * array of property names to be serialized.
 	 */
 	if (call_user_function_ex(CG(function_table), &obj, fname, &retval, 0, 0, 1, NULL TSRMLS_CC) == SUCCESS) {
 		if (retval && (sleephash = HASH_OF(retval))) {
-			PHP_CLASS_ATTRIBUTES;
-
-			PHP_SET_CLASS_ATTRIBUTES(obj);
-
 			php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
 			snprintf(tmp_buf, WDDX_BUF_LEN, WDDX_VAR_S, PHP_CLASS_NAME_VAR);
 			php_wddx_add_chunk(packet, tmp_buf);
@@ -488,8 +493,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 = HASH_OF(obj);
 
 			for (zend_hash_internal_pointer_reset(sleephash);
@@ -510,10 +513,6 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
 	} else {
 		uint key_len;
 
-		PHP_CLASS_ATTRIBUTES;
-
-		PHP_SET_CLASS_ATTRIBUTES(obj);
-
 		php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
 		snprintf(tmp_buf, WDDX_BUF_LEN, WDDX_VAR_S, PHP_CLASS_NAME_VAR);
 		php_wddx_add_chunk(packet, tmp_buf);
@@ -522,8 +521,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 = HASH_OF(obj);
 		for (zend_hash_internal_pointer_reset(objhash);
 			 zend_hash_get_current_data(objhash, (void**)&ent) == SUCCESS;
@@ -545,6 +542,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_dtor(fname);
 	FREE_ZVAL(fname);
 
@@ -1005,26 +1004,30 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
 							pce = &PHP_IC_ENTRY;
 						}
 
-						/* Initialize target object */
-						MAKE_STD_ZVAL(obj);
-						object_init_ex(obj, *pce);
-
-						/* Merge current hashtable with object's default properties */
-						zend_hash_merge(Z_OBJPROP_P(obj),
-										Z_ARRVAL_P(ent2->data),
-										(void (*)(void *)) zval_add_ref,
-										(void *) &tmp, sizeof(zval *), 0);
-
-						if (incomplete_class) {
-							php_store_class_name(obj, Z_STRVAL_P(ent1->data), Z_STRLEN_P(ent1->data));
+						if (pce != &PHP_IC_ENTRY && ((*pce)->serialize || (*pce)->unserialize)) {
+							ent2->data = NULL;
+							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class %s can not be unserialized", Z_STRVAL_P(ent1->data));
+						} else {
+							/* Initialize target object */
+							MAKE_STD_ZVAL(obj);
+							object_init_ex(obj, *pce);
+
+							/* Merge current hashtable with object's default properties */
+							zend_hash_merge(Z_OBJPROP_P(obj),
+											Z_ARRVAL_P(ent2->data),
+											(void (*)(void *)) zval_add_ref,
+											(void *) &tmp, sizeof(zval *), 0);
+
+							if (incomplete_class) {
+								php_store_class_name(obj, Z_STRVAL_P(ent1->data), Z_STRLEN_P(ent1->data));
+							}
+
+							/* Clean up old array entry */
+							zval_ptr_dtor(&ent2->data);
+
+							/* Set stack entry to point to the newly created object */
+							ent2->data = obj;
 						}
-
-						/* Clean up old array entry */
-						zval_ptr_dtor(&ent2->data);
-
-						/* Set stack entry to point to the newly created object */
-						ent2->data = obj;
-
 						/* Clean up class name var entry */
 						zval_ptr_dtor(&ent1->data);
 					} else if (Z_TYPE_P(ent2->data) == IS_OBJECT) {
From 87bb51eb9fcf95dd4c71eb1fbb00d00a243f4276 Mon Sep 17 00:00:00 2001
From: Anatol Belski <ab@php.net>
Date: Tue, 8 Nov 2016 12:12:58 +0100
Subject: [PATCH] fix memory leak

---
 ext/wddx/wddx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
index 59cc8dd..069ea12 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -1005,6 +1005,7 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
 						}
 
 						if (pce != &PHP_IC_ENTRY && ((*pce)->serialize || (*pce)->unserialize)) {
+							zval_ptr_dtor(&ent2->data);
 							ent2->data = NULL;
 							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class %s can not be unserialized", Z_STRVAL_P(ent1->data));
 						} else {