From 84dbfe07f7afb2c2ee3ae3fbceeddad0796ad1df Mon Sep 17 00:00:00 2001 From: Jeremy Mikola Date: Mon, 9 Jan 2017 12:39:02 -0500 Subject: [PATCH] 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. --- src/bson.c | 12 ++++++++++++ tests/bson/bson-fromPHP-006.phpt | 28 ++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/bson.c b/src/bson.c index 7364979b6..72796c79e 100644 --- a/src/bson.c +++ b/src/bson.c @@ -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; diff --git a/tests/bson/bson-fromPHP-006.phpt b/tests/bson/bson-fromPHP-006.phpt index e68b2bd7d..b48a9c3ce 100644 --- a/tests/bson/bson-fromPHP-006.phpt +++ b/tests/bson/bson-fromPHP-006.phpt @@ -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])); --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 [.....]