PHPC-891: BSON encoding should throw if PHP keys contain null bytes

Since PHP uses leading null bytes in object properties to denote protected and private members, we ignore those keys in lieu of throwing an exception.
This commit is contained in:
Jeremy Mikola
2017-01-09 12:39:02 -05:00
parent caa4650f73
commit 84dbfe07f7
2 changed files with 32 additions and 8 deletions

View File

@@ -1393,6 +1393,12 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
}
}
if (strlen(ZSTR_VAL(string_key)) != ZSTR_LEN(string_key)) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "BSON keys cannot contain null bytes. Unexpected null byte after \"%s\".", ZSTR_VAL(string_key));
return;
}
if (flags & PHONGO_BSON_ADD_ID) {
if (!strcmp(ZSTR_VAL(string_key), "_id")) {
flags &= ~PHONGO_BSON_ADD_ID;
@@ -1439,6 +1445,12 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
}
}
if (strlen(string_key) != string_key_len - 1) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "BSON keys cannot contain null bytes. Unexpected null byte after \"%s\".", ZSTR_VAL(string_key));
return;
}
if (flags & PHONGO_BSON_ADD_ID) {
if (!strcmp(string_key, "_id")) {
flags &= ~PHONGO_BSON_ADD_ID;

View File

@@ -6,13 +6,19 @@ BSON\fromPHP(): PHP documents with null bytes in field name
require_once __DIR__ . '/../utils/tools.php';
echo "\nTesting array with one leading null byte in field name\n";
hex_dump(fromPHP(["\0" => 1]));
echo throws(function() {
fromPHP(["\0" => 1]);
}, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n";
echo "\nTesting array with one trailing null byte in field name\n";
hex_dump(fromPHP(["a\0" => 1]));
echo throws(function() {
fromPHP(["a\0" => 1]);
}, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n";
echo "\nTesting array with multiple null bytes in field name\n";
hex_dump(fromPHP(["\0\0\0" => 1]));
echo throws(function() {
fromPHP(["\0\0\0" => 1]);
}, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n";
/* Per PHPC-884, field names with a leading null byte are ignored when encoding
* a document from an object's property hash table, since PHP uses leading bytes
@@ -21,7 +27,9 @@ echo "\nTesting object with one leading null byte in field name\n";
hex_dump(fromPHP((object) ["\0" => 1]));
echo "\nTesting object with one trailing null byte in field name\n";
hex_dump(fromPHP((object) ["a\0" => 1]));
echo throws(function() {
fromPHP((object) ["a\0" => 1]);
}, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n";
echo "\nTesting object with multiple null bytes in field name\n";
hex_dump(fromPHP((object) ["\0\0\0" => 1]));
@@ -31,19 +39,23 @@ hex_dump(fromPHP((object) ["\0\0\0" => 1]));
<?php exit(0); ?>
--EXPECT--
Testing array with one leading null byte in field name
0 : 0b 00 00 00 10 00 01 00 00 00 00 [...........]
OK: Got MongoDB\Driver\Exception\UnexpectedValueException
BSON keys cannot contain null bytes. Unexpected null byte after "".
Testing array with one trailing null byte in field name
0 : 0c 00 00 00 10 61 00 01 00 00 00 00 [.....a......]
OK: Got MongoDB\Driver\Exception\UnexpectedValueException
BSON keys cannot contain null bytes. Unexpected null byte after "a".
Testing array with multiple null bytes in field name
0 : 0b 00 00 00 10 00 01 00 00 00 00 [...........]
OK: Got MongoDB\Driver\Exception\UnexpectedValueException
BSON keys cannot contain null bytes. Unexpected null byte after "".
Testing object with one leading null byte in field name
0 : 05 00 00 00 00 [.....]
Testing object with one trailing null byte in field name
0 : 0c 00 00 00 10 61 00 01 00 00 00 00 [.....a......]
OK: Got MongoDB\Driver\Exception\UnexpectedValueException
BSON keys cannot contain null bytes. Unexpected null byte after "a".
Testing object with multiple null bytes in field name
0 : 05 00 00 00 00 [.....]