Skip to content

Commit 3cc2e10

Browse files
committed
PHPC-779: Switch Binary from O to C type serialization
1 parent 5076fb0 commit 3cc2e10

File tree

5 files changed

+109
-5
lines changed

5 files changed

+109
-5
lines changed

phongo_compat.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
# define PHONGO_RETURN_STRINGL(s, slen) RETURN_STRINGL(s, slen)
130130
# define PHONGO_RETVAL_STRING(s) RETVAL_STRING(s)
131131
# define PHONGO_RETURN_STRING(s) RETURN_STRING(s)
132+
# define PHONGO_RETVAL_SMART_STR(val) PHONGO_RETVAL_STRINGL(ZSTR_VAL((val).s), ZSTR_LEN((val).s));
132133
#else
133134
# define phongo_char char
134135
# define phongo_char_pdup(str) pestrdup(filename, 1)
@@ -162,6 +163,7 @@
162163
# define PHONGO_RETURN_STRINGL(s, slen) RETURN_STRINGL(s, slen, 1)
163164
# define PHONGO_RETVAL_STRING(s) RETVAL_STRING(s, 1)
164165
# define PHONGO_RETURN_STRING(s) RETURN_STRING(s, 1)
166+
# define PHONGO_RETVAL_SMART_STR(val) PHONGO_RETVAL_STRINGL((val).c, (val).len);
165167
# define PHP_STREAM_CONTEXT(stream) ((php_stream_context*) (stream)->context)
166168
#endif
167169

src/BSON/Binary.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@
3434
#include <ext/standard/info.h>
3535
#include <Zend/zend_interfaces.h>
3636
#include <ext/spl/spl_iterators.h>
37+
#include <ext/standard/php_var.h>
38+
#if PHP_VERSION_ID >= 70000
39+
# include <zend_smart_str.h>
40+
#else
41+
# include <ext/standard/php_smart_str.h>
42+
#endif
3743
/* Our Compatability header */
3844
#include "phongo_compat.h"
3945

@@ -199,6 +205,95 @@ PHP_METHOD(Binary, getType)
199205
}
200206
/* }}} */
201207

208+
/* {{{ proto string Binary::serialize()
209+
*/
210+
PHP_METHOD(Binary, serialize)
211+
{
212+
php_phongo_binary_t *intern;
213+
#if PHP_VERSION_ID >= 70000
214+
zval retval;
215+
#else
216+
zval *retval;
217+
#endif
218+
php_serialize_data_t var_hash;
219+
smart_str buf = { 0 };
220+
221+
intern = Z_BINARY_OBJ_P(getThis());
222+
223+
if (zend_parse_parameters_none() == FAILURE) {
224+
return;
225+
}
226+
227+
#if PHP_VERSION_ID >= 70000
228+
array_init_size(&retval, 2);
229+
ADD_ASSOC_STRINGL(&retval, "data", intern->data, intern->data_len);
230+
ADD_ASSOC_LONG_EX(&retval, "type", intern->type);
231+
#else
232+
ALLOC_INIT_ZVAL(retval);
233+
array_init_size(retval, 2);
234+
ADD_ASSOC_STRINGL(retval, "data", intern->data, intern->data_len);
235+
ADD_ASSOC_LONG_EX(retval, "type", intern->type);
236+
#endif
237+
238+
PHP_VAR_SERIALIZE_INIT(var_hash);
239+
php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
240+
smart_str_0(&buf);
241+
PHP_VAR_SERIALIZE_DESTROY(var_hash);
242+
243+
PHONGO_RETVAL_SMART_STR(buf);
244+
245+
smart_str_free(&buf);
246+
zval_ptr_dtor(&retval);
247+
}
248+
/* }}} */
249+
250+
/* {{{ proto string Binary::unserialize(string $serialized)
251+
*/
252+
PHP_METHOD(Binary, unserialize)
253+
{
254+
php_phongo_binary_t *intern;
255+
zend_error_handling error_handling;
256+
char *serialized;
257+
phongo_zpp_char_len serialized_len;
258+
#if PHP_VERSION_ID >= 70000
259+
zval props;
260+
#else
261+
zval *props;
262+
#endif
263+
php_unserialize_data_t var_hash;
264+
265+
intern = Z_BINARY_OBJ_P(getThis());
266+
267+
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
268+
269+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
270+
zend_restore_error_handling(&error_handling TSRMLS_CC);
271+
return;
272+
}
273+
zend_restore_error_handling(&error_handling TSRMLS_CC);
274+
275+
#if PHP_VERSION_ID < 70000
276+
ALLOC_INIT_ZVAL(props);
277+
#endif
278+
PHP_VAR_UNSERIALIZE_INIT(var_hash);
279+
if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char *) serialized + serialized_len, &var_hash TSRMLS_CC)) {
280+
zval_ptr_dtor(&props);
281+
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_binary_ce->name));
282+
283+
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
284+
return;
285+
}
286+
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
287+
288+
#if PHP_VERSION_ID >= 70000
289+
php_phongo_binary_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
290+
#else
291+
php_phongo_binary_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
292+
#endif
293+
zval_ptr_dtor(&props);
294+
}
295+
/* }}} */
296+
202297

203298
/* {{{ BSON\Binary */
204299

@@ -211,6 +306,10 @@ ZEND_BEGIN_ARG_INFO_EX(ai_Binary___set_state, 0, 0, 1)
211306
ZEND_ARG_ARRAY_INFO(0, properties, 0)
212307
ZEND_END_ARG_INFO()
213308

309+
ZEND_BEGIN_ARG_INFO_EX(ai_Binary_unserialize, 0, 0, 1)
310+
ZEND_ARG_INFO(0, serialized)
311+
ZEND_END_ARG_INFO()
312+
214313
ZEND_BEGIN_ARG_INFO_EX(ai_Binary_void, 0, 0, 0)
215314
ZEND_END_ARG_INFO()
216315

@@ -219,6 +318,8 @@ static zend_function_entry php_phongo_binary_me[] = {
219318
PHP_ME(Binary, __set_state, ai_Binary___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
220319
PHP_ME(Binary, __toString, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
221320
PHP_ME(Binary, __wakeup, ai_Binary_void, ZEND_ACC_PUBLIC)
321+
PHP_ME(Binary, serialize, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
322+
PHP_ME(Binary, unserialize, ai_Binary_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
222323
PHP_ME(Binary, getData, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
223324
PHP_ME(Binary, getType, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
224325
PHP_FE_END
@@ -318,6 +419,7 @@ PHP_MINIT_FUNCTION(Binary)
318419
PHONGO_CE_FINAL(php_phongo_binary_ce);
319420

320421
zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, php_phongo_type_ce);
422+
zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, zend_ce_serializable);
321423

322424
memcpy(&php_phongo_handler_binary, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
323425
php_phongo_handler_binary.get_properties = php_phongo_binary_get_properties;
-46 Bytes
Binary file not shown.

tests/bson/bson-binary-serialization_error-001.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ MongoDB\BSON\Binary unserialization requires "data" string and "type" integer fi
66
require_once __DIR__ . '/../utils/tools.php';
77

88
echo throws(function() {
9-
unserialize('O:19:"MongoDB\BSON\Binary":1:{s:4:"data";s:6:"foobar";}');
9+
unserialize('C:19:"MongoDB\BSON\Binary":30:{a:1:{s:4:"data";s:6:"foobar";}}');
1010
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
1111

1212
echo throws(function() {
13-
unserialize('O:19:"MongoDB\BSON\Binary":1:{s:4:"type";i:0;}');
13+
unserialize('C:19:"MongoDB\BSON\Binary":21:{a:1:{s:4:"type";i:0;}}');
1414
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
1515

1616
echo throws(function() {
17-
unserialize('O:19:"MongoDB\BSON\Binary":1:{s:4:"data";i:0;s:4:"type";s:6:"foobar";}');
17+
unserialize('C:19:"MongoDB\BSON\Binary":45:{a:2:{s:4:"data";i:0;s:4:"type";s:6:"foobar";}}');
1818
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
1919

2020
?>

tests/bson/bson-binary-serialization_error-002.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ MongoDB\BSON\Binary unserialization requires unsigned 8-bit integer for type
66
require_once __DIR__ . '/../utils/tools.php';
77

88
echo throws(function() {
9-
unserialize('O:19:"MongoDB\BSON\Binary":2:{s:4:"data";s:6:"foobar";s:4:"type";i:-1;}');
9+
unserialize('C:19:"MongoDB\BSON\Binary":46:{a:2:{s:4:"data";s:6:"foobar";s:4:"type";i:-1;}}');
1010
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
1111

1212
echo throws(function() {
13-
unserialize('O:19:"MongoDB\BSON\Binary":2:{s:4:"data";s:6:"foobar";s:4:"type";i:256;}');
13+
unserialize('C:19:"MongoDB\BSON\Binary":47:{a:2:{s:4:"data";s:6:"foobar";s:4:"type";i:256;}}');
1414
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
1515

1616
?>

0 commit comments

Comments
 (0)