alternator: fix checking max item depth

Maximum item depth accepted by DynamoDB is 32, and alternator
chose 39 as its arbitrary value in order to provide 7 shining
new levels absolutely free of charge. Unfortunately, our code
which checks the nesting level in rapidjson parsing bumps
the counter by 2 for every object, which is due to rapidjson's
internal implementation. In order to actually support
at least 32 levels, the threshold is simply doubled.
This commit comes with a test case which ensures that
32-nested items are accepted both by alternator and DynamoDB.
The test case failed for alternator before the fix.

Fixes #6366
Tests: unit(dev), alternator(local, remote)
This commit is contained in:
Piotr Sarna
2020-05-04 17:45:01 +02:00
committed by Nadav Har'El
parent c5cdd77f8e
commit 1c4e8f5030
2 changed files with 13 additions and 3 deletions

View File

@@ -123,7 +123,7 @@ protected:
std::string print(const rjson::value& value) {
string_buffer buffer;
guarded_yieldable_json_handler<writer, false> writer(buffer, 39);
guarded_yieldable_json_handler<writer, false> writer(buffer, 78);
value.Accept(writer);
return std::string(buffer.GetString());
}
@@ -133,7 +133,7 @@ rjson::value copy(const rjson::value& value) {
}
rjson::value parse(std::string_view str) {
guarded_yieldable_json_handler<document, false> d(39);
guarded_yieldable_json_handler<document, false> d(78);
d.Parse(str.data(), str.size());
if (d.HasParseError()) {
throw rjson::error(format("Parsing JSON failed: {}", GetParseError_En(d.GetParseError())));
@@ -143,7 +143,7 @@ rjson::value parse(std::string_view str) {
}
rjson::value parse_yieldable(std::string_view str) {
guarded_yieldable_json_handler<document, true> d(39);
guarded_yieldable_json_handler<document, true> d(78);
d.Parse(str.data(), str.size());
if (d.HasParseError()) {
throw rjson::error(format("Parsing JSON failed: {}", GetParseError_En(d.GetParseError())));

View File

@@ -81,6 +81,16 @@ def test_exceed_nested_level_a_little(dynamodb, test_table):
with pytest.raises(ClientError, match='.*Exception.*nested'):
test_table.put_item(Item={'p': p, 'c': c, 'nested': nested})
# Test that we indeed allow the maximum level of 32 nested objects
def test_almost_exceed_nested_level(dynamodb, test_table):
p = 'xxx'
c = 'yyy'
nested = dict()
nested_it = nested
for i in range(30): # 30 added levels + top level + the item itself == 32 total
nested_it['a'] = dict()
nested_it = nested_it['a']
test_table.put_item(Item={'p': p, 'c': c, 'nested': nested})
def test_too_large_request(dynamodb, test_table):
p = 'abc'