Skip to content

Commit

Permalink
PHPC-891: BSON encoding should throw if PHP keys contain null bytes
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jmikola committed Jan 10, 2017
1 parent caa4650 commit 84dbfe0
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 8 deletions.
12 changes: 12 additions & 0 deletions src/bson.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
28 changes: 20 additions & 8 deletions tests/bson/bson-fromPHP-006.phpt
Expand Up @@ -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
Expand All @@ -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]));
Expand All @@ -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 [.....]
Expand Down

0 comments on commit 84dbfe0

Please sign in to comment.