aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/json/ut/json_reader_ut.cpp
diff options
context:
space:
mode:
authorionagamed <ionagamed@yandex-team.com>2023-11-29 08:16:34 +0300
committerionagamed <ionagamed@yandex-team.com>2023-11-29 08:51:03 +0300
commit55fc158d4d2d8ae4d9f026e1afac03c7daae294d (patch)
treebff2aa2edeae94bbf21a7a9875c6d8a1cbe8974c /library/cpp/json/ut/json_reader_ut.cpp
parent4c48882379d93a43bd74060add09e309ce5e5002 (diff)
downloadydb-55fc158d4d2d8ae4d9f026e1afac03c7daae294d.tar.gz
library/json: add MaxDepth and iterative parsing into config
rationale: у нас была проблема где приезжает пользовательский json небольшой (на пару-тройку кб) и рвет нам стек из-за глубины. Со стороны rapidjson это проще всего поправить включив у них итеративный парсинг, который не будет использовать системный стек. Но это не совсем все — с нашей стороны оно все развалится когда надо будет вызвать рекурсивно деструкторы TJsonValue — и тут уже можно будет покрутить MaxDepth.
Diffstat (limited to 'library/cpp/json/ut/json_reader_ut.cpp')
-rw-r--r--library/cpp/json/ut/json_reader_ut.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/library/cpp/json/ut/json_reader_ut.cpp b/library/cpp/json/ut/json_reader_ut.cpp
index cd31afa0b8..115c85e1c7 100644
--- a/library/cpp/json/ut/json_reader_ut.cpp
+++ b/library/cpp/json/ut/json_reader_ut.cpp
@@ -66,6 +66,17 @@ public:
}
};
+void GenerateDeepJson(TStringStream& stream, ui64 depth) {
+ stream << "{\"key\":";
+ for (ui32 i = 0; i < depth - 1; ++i) {
+ stream << "[";
+ }
+ for (ui32 i = 0; i < depth - 1; ++i) {
+ stream << "]";
+ }
+ stream << "}";
+}
+
Y_UNIT_TEST_SUITE(TJsonReaderTest) {
Y_UNIT_TEST(JsonReformatTest) {
TString data = "{\"null value\": null, \"intkey\": 10, \"double key\": 11.11, \"string key\": \"string\", \"array\": [1,2,3,\"TString\"], \"bool key\": true}";
@@ -396,6 +407,44 @@ Y_UNIT_TEST_SUITE(TJsonReaderTest) {
UNIT_ASSERT(v.GetMap().begin()->second.IsString());
UNIT_ASSERT_VALUES_EQUAL("", v.GetMap().begin()->second.GetString());
}
+
+ // Parsing an extremely deep json tree would result in stack overflow.
+ // Not crashing on one is a good indicator of iterative mode.
+ Y_UNIT_TEST(TJsonIterativeTest) {
+ constexpr ui32 brackets = static_cast<ui32>(1e5);
+
+ TStringStream jsonStream;
+ GenerateDeepJson(jsonStream, brackets);
+
+ TJsonReaderConfig config;
+ config.UseIterativeParser = true;
+ config.MaxDepth = static_cast<ui32>(1e3);
+
+ TJsonValue v;
+ UNIT_ASSERT(!ReadJsonTree(&jsonStream, &config, &v));
+ }
+
+ Y_UNIT_TEST(TJsonMaxDepthTest) {
+ constexpr ui32 depth = static_cast<ui32>(1e3);
+
+ {
+ TStringStream jsonStream;
+ GenerateDeepJson(jsonStream, depth);
+ TJsonReaderConfig config;
+ config.MaxDepth = depth;
+ TJsonValue v;
+ UNIT_ASSERT(ReadJsonTree(&jsonStream, &config, &v));
+ }
+
+ {
+ TStringStream jsonStream;
+ GenerateDeepJson(jsonStream, depth);
+ TJsonReaderConfig config;
+ config.MaxDepth = depth - 1;
+ TJsonValue v;
+ UNIT_ASSERT(!ReadJsonTree(&jsonStream, &config, &v));
+ }
+ }
}