Skip to content

Commit 66822bf

Browse files
committed
PHPC-724: Do not allow null bytes in Regex pattern or flags
These fields are cstrings in the BSON spec, so any null bytes would result in unexpected truncation.
1 parent b6754f6 commit 66822bf

File tree

4 files changed

+91
-5
lines changed

4 files changed

+91
-5
lines changed

src/BSON/Regex.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,20 @@ PHONGO_API zend_class_entry *php_phongo_regex_ce;
4646

4747
zend_object_handlers php_phongo_handler_regex;
4848

49-
/* Initialize the object and return whether it was successful. */
50-
static bool php_phongo_regex_init(php_phongo_regex_t *intern, const char *pattern, phongo_zpp_char_len pattern_len, const char *flags, phongo_zpp_char_len flags_len)
49+
/* Initialize the object and return whether it was successful. An exception will
50+
* be thrown on error. */
51+
static bool php_phongo_regex_init(php_phongo_regex_t *intern, const char *pattern, phongo_zpp_char_len pattern_len, const char *flags, phongo_zpp_char_len flags_len TSRMLS_DC)
5152
{
53+
if (strlen(pattern) != pattern_len) {
54+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Pattern cannot contain null bytes");
55+
return false;
56+
}
57+
58+
if (strlen(flags) != flags_len) {
59+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Flags cannot contain null bytes");
60+
return false;
61+
}
62+
5263
intern->pattern = estrndup(pattern, pattern_len);
5364
intern->pattern_len = pattern_len;
5465
intern->flags = estrndup(flags, flags_len);
@@ -66,14 +77,14 @@ static bool php_phongo_regex_init_from_hash(php_phongo_regex_t *intern, HashTabl
6677

6778
if ((pattern = zend_hash_str_find(props, "pattern", sizeof("pattern")-1)) && Z_TYPE_P(pattern) == IS_STRING &&
6879
(flags = zend_hash_str_find(props, "flags", sizeof("flags")-1)) && Z_TYPE_P(flags) == IS_STRING) {
69-
return php_phongo_regex_init(intern, Z_STRVAL_P(pattern), Z_STRLEN_P(pattern), Z_STRVAL_P(flags), Z_STRLEN_P(flags));
80+
return php_phongo_regex_init(intern, Z_STRVAL_P(pattern), Z_STRLEN_P(pattern), Z_STRVAL_P(flags), Z_STRLEN_P(flags) TSRMLS_CC);
7081
}
7182
#else
7283
zval **pattern, **flags;
7384

7485
if (zend_hash_find(props, "pattern", sizeof("pattern"), (void**) &pattern) == SUCCESS && Z_TYPE_PP(pattern) == IS_STRING &&
7586
zend_hash_find(props, "flags", sizeof("flags"), (void**) &flags) == SUCCESS && Z_TYPE_PP(flags) == IS_STRING) {
76-
return php_phongo_regex_init(intern, Z_STRVAL_PP(pattern), Z_STRLEN_PP(pattern), Z_STRVAL_PP(flags), Z_STRLEN_PP(flags));
87+
return php_phongo_regex_init(intern, Z_STRVAL_PP(pattern), Z_STRLEN_PP(pattern), Z_STRVAL_PP(flags), Z_STRLEN_PP(flags) TSRMLS_CC);
7788
}
7889
#endif
7990

@@ -102,7 +113,7 @@ PHP_METHOD(Regex, __construct)
102113
}
103114
zend_restore_error_handling(&error_handling TSRMLS_CC);
104115

105-
php_phongo_regex_init(intern, pattern, pattern_len, flags, flags_len);
116+
php_phongo_regex_init(intern, pattern, pattern_len, flags, flags_len TSRMLS_CC);
106117
}
107118
/* }}} */
108119
/* {{{ proto void Regex::getPattern()
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
MongoDB\BSON\Regex unserialization does not allow pattern or flags to contain null bytes
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
echo throws(function() {
10+
unserialize('O:18:"MongoDB\BSON\Regex":2:{s:7:"pattern";s:7:"regexp' . "\0" . '";s:5:"flags";s:1:"i";}');
11+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
12+
13+
echo throws(function() {
14+
unserialize('O:18:"MongoDB\BSON\Regex":2:{s:7:"pattern";s:6:"regexp";s:5:"flags";s:2:"i' . "\0" . '";}');
15+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
16+
17+
?>
18+
===DONE===
19+
<?php exit(0); ?>
20+
--EXPECT--
21+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
22+
Pattern cannot contain null bytes
23+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
24+
Flags cannot contain null bytes
25+
===DONE===
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
MongoDB\BSON\Regex::__set_state() does not allow pattern or flags to contain null bytes
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
echo throws(function() {
10+
MongoDB\BSON\Regex::__set_state(['pattern' => "regexp\0", 'flags' => 'i']);
11+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
12+
13+
echo throws(function() {
14+
MongoDB\BSON\Regex::__set_state(['pattern' => 'regexp', 'flags' => "i\0"]);
15+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
16+
17+
?>
18+
===DONE===
19+
<?php exit(0); ?>
20+
--EXPECT--
21+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
22+
Pattern cannot contain null bytes
23+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
24+
Flags cannot contain null bytes
25+
===DONE===
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
MongoDB\BSON\Regex::__construct() does not allow pattern or flags to contain null bytes
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
echo throws(function() {
10+
new MongoDB\BSON\Regex("regexp\0", 'i');
11+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
12+
13+
echo throws(function() {
14+
new MongoDB\BSON\Regex('regexp', "i\0");
15+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
16+
17+
?>
18+
===DONE===
19+
<?php exit(0); ?>
20+
--EXPECT--
21+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
22+
Pattern cannot contain null bytes
23+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
24+
Flags cannot contain null bytes
25+
===DONE===

0 commit comments

Comments
 (0)