Skip to content

Commit caa4650

Browse files
committed
PHPC-886: Always recalculate field name length when encoding BSON
1 parent b3b3a55 commit caa4650

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

src/bson.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,19 +1444,14 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
14441444
flags &= ~PHONGO_BSON_ADD_ID;
14451445
}
14461446
}
1447-
1448-
/* PHP's HashTable API includes the terminating NULL byte in key's
1449-
* string length, so subtract to track the equivalent strlen(). */
1450-
string_key_len -= 1;
14511447
}
14521448

14531449
/* Ensure we're working with a string key */
14541450
if (hash_type == HASH_KEY_IS_LONG) {
14551451
spprintf(&string_key, 0, "%ld", num_key);
1456-
string_key_len = strlen(string_key);
14571452
}
14581453

1459-
phongo_bson_append(bson, flags & ~PHONGO_BSON_ADD_ID, string_key, string_key_len, *value TSRMLS_CC);
1454+
phongo_bson_append(bson, flags & ~PHONGO_BSON_ADD_ID, string_key, strlen(string_key), *value TSRMLS_CC);
14601455

14611456
if (hash_type == HASH_KEY_IS_LONG) {
14621457
efree(string_key);

tests/bson/bson-fromPHP-006.phpt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--TEST--
2+
BSON\fromPHP(): PHP documents with null bytes in field name
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/tools.php';
7+
8+
echo "\nTesting array with one leading null byte in field name\n";
9+
hex_dump(fromPHP(["\0" => 1]));
10+
11+
echo "\nTesting array with one trailing null byte in field name\n";
12+
hex_dump(fromPHP(["a\0" => 1]));
13+
14+
echo "\nTesting array with multiple null bytes in field name\n";
15+
hex_dump(fromPHP(["\0\0\0" => 1]));
16+
17+
/* Per PHPC-884, field names with a leading null byte are ignored when encoding
18+
* a document from an object's property hash table, since PHP uses leading bytes
19+
* to denote protected and private properties. */
20+
echo "\nTesting object with one leading null byte in field name\n";
21+
hex_dump(fromPHP((object) ["\0" => 1]));
22+
23+
echo "\nTesting object with one trailing null byte in field name\n";
24+
hex_dump(fromPHP((object) ["a\0" => 1]));
25+
26+
echo "\nTesting object with multiple null bytes in field name\n";
27+
hex_dump(fromPHP((object) ["\0\0\0" => 1]));
28+
29+
?>
30+
===DONE===
31+
<?php exit(0); ?>
32+
--EXPECT--
33+
Testing array with one leading null byte in field name
34+
0 : 0b 00 00 00 10 00 01 00 00 00 00 [...........]
35+
36+
Testing array with one trailing null byte in field name
37+
0 : 0c 00 00 00 10 61 00 01 00 00 00 00 [.....a......]
38+
39+
Testing array with multiple null bytes in field name
40+
0 : 0b 00 00 00 10 00 01 00 00 00 00 [...........]
41+
42+
Testing object with one leading null byte in field name
43+
0 : 05 00 00 00 00 [.....]
44+
45+
Testing object with one trailing null byte in field name
46+
0 : 0c 00 00 00 10 61 00 01 00 00 00 00 [.....a......]
47+
48+
Testing object with multiple null bytes in field name
49+
0 : 05 00 00 00 00 [.....]
50+
===DONE===

0 commit comments

Comments
 (0)