diff --git a/src/core/json/json_object.cc b/src/core/json/json_object.cc index 2f14545b5..2fa26033a 100644 --- a/src/core/json/json_object.cc +++ b/src/core/json/json_object.cc @@ -18,8 +18,13 @@ optional JsonFromString(string_view input, PMR_NS::memory_resource* mr return false; }; - // The maximum allowed JSON nesting depth is 256. - const uint32_t json_nesting_depth_limit = 256; + // The maximum allowed JSON nesting depth is 64. + // The limit was reduced from 256 to 64. This change is reasonable, as most documents contain + // no more than 20-30 levels of nesting. In the test case, over 128 levels were used, causing + // the parser to enter a long stall due to excessive resource consumption. Even a limit of 128 + // does not mitigate the issue. A limit of 64 is a sensible compromise. + // See https://github.com/dragonflydb/dragonfly/issues/5028 + const uint32_t json_nesting_depth_limit = 64; /* The maximum possible JSON nesting depth is either the specified json_nesting_depth_limit or half of the input size. Since nesting a JSON object requires at least 2 characters. */ diff --git a/src/server/json_family_test.cc b/src/server/json_family_test.cc index 19e22be62..334d455b1 100644 --- a/src/server/json_family_test.cc +++ b/src/server/json_family_test.cc @@ -3079,4 +3079,12 @@ TEST_F(JsonFamilyTest, ArrPopWithFormatParameter) { ASSERT_THAT(resp, ErrArg("value is not an integer or out of range")); } +TEST_F(JsonFamilyTest, DepthLimitExceeded) { + string deep_json = + R"({"jdiqr":{"nro":{"uzuf":{"bq":{"yc":{"zodmw":{"zbbq":{"sf":{"oule":{"j":{"mjsss":{"tap":{"bh":{"f":{"zlwgu":{"s":{"kt":{"fnmo":{"hub":{"xj":{"jo":{"ofara":{"kx":{"uw":{"z":{"mwvk":{"jo":{"qqz":{"b":{"tbp":{"esx":{"g":{"p":{"tpzk":{"i":{"azq":{"ttcd":{"wl":{"zo":{"l":{"nsq":{"tulso":{"uk":{"imfzw":{"vlub":{"k":{"ypml":{"voack":{"sosd":{"f":{"x":{"usv":{"hnw":{"ax":{"e":{"ozi":{"doi":{"k":{"bz":{"vxhp":{"e":{"vnpv":{"rhs":{"j":{"esp":{"f":{"ykyvy":{"xvmhg":{"eks":{"oijy":{"sjk":{"a":{"sejgy":{"msd":{"acyo":{"yxss":{"slbf":{"ssuns":{"c":{"kv":{"i":{"y":{"ubqz":{"uam":{"igaq":{"jl":{"vy":{"zlu":{"gscx":{"mb":{"idca":{"k":{"twx":{"ngjs":{"k":{"xcx":{"sxc":{"ye":{"fty":{"pho":{"lrn":{"wmv":{"h":{"sfuk":{"ilwzy":{"nlofv":{"mpcms":{"bg":{"jykgm":{"x":{"nbe":{"ixbyh":{"tmus":{"nqulr":{"cqxdw":{"wwpi":{"kj":{"udb":{"oct":{"tqkv":{"r":{"zev":{"rsu":{"gs":{"pyzm":{"au":{"__leaf":42}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})"; + + auto resp = Run({"JSON.SET", "test", "$", deep_json}); + ASSERT_THAT(resp, ErrArg("ERR failed to parse JSON")); +} + } // namespace dfly