BSON: Bugfix for non-empty arrays

This commit is contained in:
Julian Becker 2018-09-15 14:08:38 +02:00
parent cf485c2907
commit df33a90774
3 changed files with 55 additions and 54 deletions

View file

@ -157,17 +157,21 @@ class binary_reader
return success; return success;
} }
void parse_bson_entries() void parse_bson_entries(bool is_array)
{ {
while (auto entry_type = get()) while (auto entry_type = get())
{ {
string_t key;
get_bson_cstr(key);
if (!is_array)
{
sax->key(key);
}
switch (entry_type) switch (entry_type)
{ {
case 0x01: // double case 0x01: // double
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
double number; double number;
get_number_little_endian(number); get_number_little_endian(number);
sax->number_float(static_cast<number_float_t>(number), ""); sax->number_float(static_cast<number_float_t>(number), "");
@ -175,9 +179,6 @@ class binary_reader
break; break;
case 0x02: // string case 0x02: // string
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
std::int32_t len; std::int32_t len;
string_t value; string_t value;
get_number_little_endian(len); get_number_little_endian(len);
@ -188,17 +189,11 @@ class binary_reader
break; break;
case 0x08: // boolean case 0x08: // boolean
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
sax->boolean(static_cast<bool>(get())); sax->boolean(static_cast<bool>(get()));
} }
break; break;
case 0x10: // int32 case 0x10: // int32
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
std::int32_t value; std::int32_t value;
get_number_little_endian(value); get_number_little_endian(value);
sax->number_integer(static_cast<std::int32_t>(value)); sax->number_integer(static_cast<std::int32_t>(value));
@ -206,9 +201,6 @@ class binary_reader
break; break;
case 0x12: // int64 case 0x12: // int64
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
std::int64_t value; std::int64_t value;
get_number_little_endian(value); get_number_little_endian(value);
sax->number_integer(static_cast<std::int64_t>(value)); sax->number_integer(static_cast<std::int64_t>(value));
@ -216,25 +208,16 @@ class binary_reader
break; break;
case 0x0A: // null case 0x0A: // null
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
sax->null(); sax->null();
} }
break; break;
case 0x03: // object case 0x03: // object
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
parse_bson_internal(); parse_bson_internal();
} }
break; break;
case 0x04: // array case 0x04: // array
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
parse_bson_array(); parse_bson_array();
} }
break; break;
@ -252,7 +235,7 @@ class binary_reader
return false; return false;
} }
parse_bson_entries(); parse_bson_entries(/*is_array*/true);
const auto result = sax->end_array(); const auto result = sax->end_array();
@ -269,7 +252,7 @@ class binary_reader
return false; return false;
} }
parse_bson_entries(); parse_bson_entries(/*is_array*/false);
const auto result = sax->end_object(); const auto result = sax->end_object();

View file

@ -6141,17 +6141,21 @@ class binary_reader
return success; return success;
} }
void parse_bson_entries() void parse_bson_entries(bool is_array)
{ {
while (auto entry_type = get()) while (auto entry_type = get())
{ {
string_t key;
get_bson_cstr(key);
if (!is_array)
{
sax->key(key);
}
switch (entry_type) switch (entry_type)
{ {
case 0x01: // double case 0x01: // double
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
double number; double number;
get_number_little_endian(number); get_number_little_endian(number);
sax->number_float(static_cast<number_float_t>(number), ""); sax->number_float(static_cast<number_float_t>(number), "");
@ -6159,9 +6163,6 @@ class binary_reader
break; break;
case 0x02: // string case 0x02: // string
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
std::int32_t len; std::int32_t len;
string_t value; string_t value;
get_number_little_endian(len); get_number_little_endian(len);
@ -6172,17 +6173,11 @@ class binary_reader
break; break;
case 0x08: // boolean case 0x08: // boolean
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
sax->boolean(static_cast<bool>(get())); sax->boolean(static_cast<bool>(get()));
} }
break; break;
case 0x10: // int32 case 0x10: // int32
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
std::int32_t value; std::int32_t value;
get_number_little_endian(value); get_number_little_endian(value);
sax->number_integer(static_cast<std::int32_t>(value)); sax->number_integer(static_cast<std::int32_t>(value));
@ -6190,9 +6185,6 @@ class binary_reader
break; break;
case 0x12: // int64 case 0x12: // int64
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
std::int64_t value; std::int64_t value;
get_number_little_endian(value); get_number_little_endian(value);
sax->number_integer(static_cast<std::int64_t>(value)); sax->number_integer(static_cast<std::int64_t>(value));
@ -6200,25 +6192,16 @@ class binary_reader
break; break;
case 0x0A: // null case 0x0A: // null
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
sax->null(); sax->null();
} }
break; break;
case 0x03: // object case 0x03: // object
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
parse_bson_internal(); parse_bson_internal();
} }
break; break;
case 0x04: // array case 0x04: // array
{ {
string_t key;
get_bson_cstr(key);
sax->key(key);
parse_bson_array(); parse_bson_array();
} }
break; break;
@ -6236,7 +6219,7 @@ class binary_reader
return false; return false;
} }
parse_bson_entries(); parse_bson_entries(/*is_array*/true);
const auto result = sax->end_array(); const auto result = sax->end_array();
@ -6253,7 +6236,7 @@ class binary_reader
return false; return false;
} }
parse_bson_entries(); parse_bson_entries(/*is_array*/false);
const auto result = sax->end_object(); const auto result = sax->end_object();

View file

@ -408,6 +408,41 @@ TEST_CASE("BSON")
CHECK(json::from_bson(result, true, false) == j); CHECK(json::from_bson(result, true, false) == j);
} }
SECTION("non-empty object with non-empty array member")
{
json j =
{
{ "entry", json::array({1, 2, 3, 4, 5, 6, 7, 8}) }
};
std::vector<uint8_t> expected =
{
0x41, 0x00, 0x00, 0x00, // size (little endian)
0x04, /// entry: embedded document
'e', 'n', 't', 'r', 'y', '\x00',
0x35, 0x00, 0x00, 0x00, // size (little endian)
0x10, 0x00, 0x01, 0x00, 0x00, 0x00,
0x10, 0x00, 0x02, 0x00, 0x00, 0x00,
0x10, 0x00, 0x03, 0x00, 0x00, 0x00,
0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
0x10, 0x00, 0x05, 0x00, 0x00, 0x00,
0x10, 0x00, 0x06, 0x00, 0x00, 0x00,
0x10, 0x00, 0x07, 0x00, 0x00, 0x00,
0x10, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, // end marker (embedded document)
0x00 // end marker
};
const auto result = json::to_bson(j);
CHECK(result == expected);
// roundtrip
CHECK(json::from_bson(result) == j);
CHECK(json::from_bson(result, true, false) == j);
}
SECTION("Some more complex document") SECTION("Some more complex document")
{ {
// directly encoding uint64 is not supported in bson (only for timestamp values) // directly encoding uint64 is not supported in bson (only for timestamp values)