Skip to content

Commit 41a1175

Browse files
committed
PHPC-779: Switch Regex from O to C type serialization
1 parent 8ee86a1 commit 41a1175

File tree

5 files changed

+110
-7
lines changed

5 files changed

+110
-7
lines changed

src/BSON/Regex.c

Lines changed: 103 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

@@ -218,6 +224,95 @@ PHP_METHOD(Regex, __wakeup)
218224
}
219225
/* }}} */
220226

227+
/* {{{ proto string Regex::serialize()
228+
*/
229+
PHP_METHOD(Regex, serialize)
230+
{
231+
php_phongo_regex_t *intern;
232+
#if PHP_VERSION_ID >= 70000
233+
zval retval;
234+
#else
235+
zval *retval;
236+
#endif
237+
php_serialize_data_t var_hash;
238+
smart_str buf = { 0 };
239+
240+
intern = Z_REGEX_OBJ_P(getThis());
241+
242+
if (zend_parse_parameters_none() == FAILURE) {
243+
return;
244+
}
245+
246+
#if PHP_VERSION_ID >= 70000
247+
array_init_size(&retval, 2);
248+
ADD_ASSOC_STRINGL(&retval, "pattern", intern->pattern, intern->pattern_len);
249+
ADD_ASSOC_STRINGL(&retval, "flags", intern->flags, intern->flags_len);
250+
#else
251+
ALLOC_INIT_ZVAL(retval);
252+
array_init_size(retval, 2);
253+
ADD_ASSOC_STRINGL(retval, "pattern", intern->pattern, intern->pattern_len);
254+
ADD_ASSOC_STRINGL(retval, "flags", intern->flags, intern->flags_len);
255+
#endif
256+
257+
PHP_VAR_SERIALIZE_INIT(var_hash);
258+
php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
259+
smart_str_0(&buf);
260+
PHP_VAR_SERIALIZE_DESTROY(var_hash);
261+
262+
PHONGO_RETVAL_SMART_STR(buf);
263+
264+
smart_str_free(&buf);
265+
zval_ptr_dtor(&retval);
266+
}
267+
/* }}} */
268+
269+
/* {{{ proto string Regex::unserialize(string $serialized)
270+
*/
271+
PHP_METHOD(Regex, unserialize)
272+
{
273+
php_phongo_regex_t *intern;
274+
zend_error_handling error_handling;
275+
char *serialized;
276+
phongo_zpp_char_len serialized_len;
277+
#if PHP_VERSION_ID >= 70000
278+
zval props;
279+
#else
280+
zval *props;
281+
#endif
282+
php_unserialize_data_t var_hash;
283+
284+
intern = Z_REGEX_OBJ_P(getThis());
285+
286+
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
287+
288+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
289+
zend_restore_error_handling(&error_handling TSRMLS_CC);
290+
return;
291+
}
292+
zend_restore_error_handling(&error_handling TSRMLS_CC);
293+
294+
#if PHP_VERSION_ID < 70000
295+
ALLOC_INIT_ZVAL(props);
296+
#endif
297+
PHP_VAR_UNSERIALIZE_INIT(var_hash);
298+
if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char *) serialized + serialized_len, &var_hash TSRMLS_CC)) {
299+
zval_ptr_dtor(&props);
300+
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_regex_ce->name));
301+
302+
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
303+
return;
304+
}
305+
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
306+
307+
#if PHP_VERSION_ID >= 70000
308+
php_phongo_regex_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
309+
#else
310+
php_phongo_regex_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
311+
#endif
312+
zval_ptr_dtor(&props);
313+
}
314+
/* }}} */
315+
221316
/* {{{ BSON\Regex */
222317

223318
ZEND_BEGIN_ARG_INFO_EX(ai_Regex___construct, 0, 0, 2)
@@ -229,6 +324,10 @@ ZEND_BEGIN_ARG_INFO_EX(ai_Regex___set_state, 0, 0, 1)
229324
ZEND_ARG_ARRAY_INFO(0, properties, 0)
230325
ZEND_END_ARG_INFO()
231326

327+
ZEND_BEGIN_ARG_INFO_EX(ai_Regex_unserialize, 0, 0, 1)
328+
ZEND_ARG_INFO(0, serialized)
329+
ZEND_END_ARG_INFO()
330+
232331
ZEND_BEGIN_ARG_INFO_EX(ai_Regex_void, 0, 0, 0)
233332
ZEND_END_ARG_INFO()
234333

@@ -237,6 +336,8 @@ static zend_function_entry php_phongo_regex_me[] = {
237336
PHP_ME(Regex, __set_state, ai_Regex___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
238337
PHP_ME(Regex, __toString, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
239338
PHP_ME(Regex, __wakeup, ai_Regex_void, ZEND_ACC_PUBLIC)
339+
PHP_ME(Regex, serialize, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
340+
PHP_ME(Regex, unserialize, ai_Regex_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
240341
PHP_ME(Regex, getPattern, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
241342
PHP_ME(Regex, getFlags, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
242343
PHP_FE_END
@@ -362,6 +463,8 @@ PHP_MINIT_FUNCTION(Regex)
362463
PHONGO_CE_FINAL(php_phongo_regex_ce);
363464

364465
zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, php_phongo_type_ce);
466+
zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, zend_ce_serializable);
467+
365468
memcpy(&php_phongo_handler_regex, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
366469
php_phongo_handler_regex.get_properties = php_phongo_regex_get_properties;
367470
#if PHP_VERSION_ID >= 70000

tests/bson/bson-regex-serialization-001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object(MongoDB\BSON\Regex)#%d (%d) {
1717
["flags"]=>
1818
string(1) "i"
1919
}
20-
string(77) "O:18:"MongoDB\BSON\Regex":2:{s:7:"pattern";s:6:"regexp";s:5:"flags";s:1:"i";}"
20+
string(84) "C:18:"MongoDB\BSON\Regex":53:{a:2:{s:7:"pattern";s:6:"regexp";s:5:"flags";s:1:"i";}}"
2121
object(MongoDB\BSON\Regex)#%d (%d) {
2222
["pattern"]=>
2323
string(6) "regexp"

tests/bson/bson-regex-serialization-002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object(MongoDB\BSON\Regex)#%d (%d) {
1717
["flags"]=>
1818
string(0) ""
1919
}
20-
string(76) "O:18:"MongoDB\BSON\Regex":2:{s:7:"pattern";s:6:"regexp";s:5:"flags";s:0:"";}"
20+
string(83) "C:18:"MongoDB\BSON\Regex":52:{a:2:{s:7:"pattern";s:6:"regexp";s:5:"flags";s:0:"";}}"
2121
object(MongoDB\BSON\Regex)#%d (%d) {
2222
["pattern"]=>
2323
string(6) "regexp"

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

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

88
echo throws(function() {
9-
unserialize('O:18:"MongoDB\BSON\Regex":1:{s:7:"pattern";s:6:"regexp";}');
9+
unserialize('C:18:"MongoDB\BSON\Regex":33:{a:1:{s:7:"pattern";s:6:"regexp";}}');
1010
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
1111

1212
echo throws(function() {
13-
unserialize('O:18:"MongoDB\BSON\Regex":1:{s:5:"flags";s:1:"i";}');
13+
unserialize('C:18:"MongoDB\BSON\Regex":26:{a:1:{s:5:"flags";s:1:"i";}}');
1414
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
1515

1616
echo throws(function() {
17-
unserialize('O:18:"MongoDB\BSON\Regex":2:{s:7:"pattern";i:0;s:5:"flags";i:0;}');
17+
unserialize('C:18:"MongoDB\BSON\Regex":40:{a:2:{s:7:"pattern";i:0;s:5:"flags";i:0;}}');
1818
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
1919

2020
?>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ MongoDB\BSON\Regex unserialization does not allow pattern or flags to contain nu
66
require_once __DIR__ . '/../utils/tools.php';
77

88
echo throws(function() {
9-
unserialize('O:18:"MongoDB\BSON\Regex":2:{s:7:"pattern";s:7:"regexp' . "\0" . '";s:5:"flags";s:1:"i";}');
9+
unserialize('C:18:"MongoDB\BSON\Regex":54:{a:2:{s:7:"pattern";s:7:"regexp' . "\0" . '";s:5:"flags";s:1:"i";}}');
1010
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
1111

1212
echo throws(function() {
13-
unserialize('O:18:"MongoDB\BSON\Regex":2:{s:7:"pattern";s:6:"regexp";s:5:"flags";s:2:"i' . "\0" . '";}');
13+
unserialize('C:18:"MongoDB\BSON\Regex":54:{a:2:{s:7:"pattern";s:6:"regexp";s:5:"flags";s:2:"i' . "\0" . '";}}');
1414
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
1515

1616
?>

0 commit comments

Comments
 (0)