1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
--TEST--
Test for PHP-896: Segfault decoding BSON reads past buffer endpoint (strings)
--SKIPIF--
<?php require dirname(__FILE__) ."/skipif.inc"; ?>
--FILE--
<?php
function createBson($type, $len) {
$bson = pack('C', $type); // byte: field type
$bson .= pack('a*x', 'x'); // cstring: field name
$bson .= pack(str_repeat('x', $len)); // null bytes (field value)
$bson .= pack('x'); // null byte: document terminator
$bson = pack('V', 4 + strlen($bson)) . $bson; // int32: document length
return $bson;
}
function createStringElement($len, $bytes) {
$bson = pack('V', $len); // int32: string length
$bson .= pack('a*x', $bytes); // cstring: string value
return $bson;
}
function createString($type, $len, $bytes) {
$bson = pack('C', $type); // byte: field type
$bson .= pack('a*x', 'x'); // cstring: field name
$bson .= createStringElement($len, $bytes); // string value
$bson .= pack('x'); // null byte: document terminator
$bson = pack('V', 4 + strlen($bson)) . $bson; // int32: document length
return $bson;
}
/* Test boundary conditions for string-like types. These contain a length field,
* which is also checked.
*/
$tests = array(
// typeName => typeCode
'string' => 0x02,
'symbol' => 0x0E,
'code' => 0x0D,
);
foreach ($tests as $typeName => $typeCode) {
printf("\nTesting %s type with valid buffer length\n", $typeName);
var_dump(bson_decode(createString($typeCode, 1, '')));
printf("\nTesting %s type with invalid buffer length\n", $typeName);
try {
bson_decode(createBson($typeCode, 3));
echo "FAILED\n";
} catch (MongoCursorException $e) {
var_dump($e->getMessage(), $e->getCode());
}
printf("\nTesting %s type with invalid character buffer length\n", $typeName);
try {
bson_decode(createString($typeCode, 6, ''));
echo "FAILED\n";
} catch (MongoCursorException $e) {
var_dump($e->getMessage(), $e->getCode());
}
printf("\n%s\n", str_repeat('-', 80));
}
?>
--EXPECTF--
Testing string type with valid buffer length
array(1) {
["x"]=>
string(0) ""
}
Testing string type with invalid buffer length
string(56) "Reading data for type 02 would exceed buffer for key "x""
int(21)
Testing string type with invalid character buffer length
string(56) "Reading data for type 02 would exceed buffer for key "x""
int(21)
--------------------------------------------------------------------------------
Testing symbol type with valid buffer length
array(1) {
["x"]=>
string(0) ""
}
Testing symbol type with invalid buffer length
string(56) "Reading data for type 0e would exceed buffer for key "x""
int(21)
Testing symbol type with invalid character buffer length
string(56) "Reading data for type 0e would exceed buffer for key "x""
int(21)
--------------------------------------------------------------------------------
Testing code type with valid buffer length
array(1) {
["x"]=>
object(MongoCode)#%d (2) {
["code"]=>
string(0) ""
["scope"]=>
array(0) {
}
}
}
Testing code type with invalid buffer length
string(56) "Reading data for type 0d would exceed buffer for key "x""
int(21)
Testing code type with invalid character buffer length
string(56) "Reading data for type 0d would exceed buffer for key "x""
int(21)
--------------------------------------------------------------------------------
|