From ecdbaeb6ef8180a4c06352e77f59ecadfe73453f Mon Sep 17 00:00:00 2001 From: ydah Date: Mon, 5 Oct 2026 23:15:50 +0900 Subject: [PATCH] Report the attempted depth in generator nesting errors --- ext/json/ext/generator/generator.c | 7 +++---- java/src/json/ext/GeneratorState.java | 10 ++++------ test/json/json_generator_test.rb | 12 ++++++++++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index fbef1980b..abe5fd2c8 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -1045,11 +1045,10 @@ json_object_i(VALUE key, VALUE val, VALUE _arg) static inline long increase_depth(struct generate_json_data *data) { JSON_Generator_State *state = data->state; - long depth = ++data->depth; - if (RB_UNLIKELY(depth > state->max_nesting && state->max_nesting)) { - rb_raise(eNestingError, "nesting of %ld is too deep. Did you try to serialize objects with circular references?", --data->depth); + if (RB_UNLIKELY(data->depth >= state->max_nesting && state->max_nesting)) { + rb_raise(eNestingError, "nesting of %ld is too deep. Did you try to serialize objects with circular references?", data->depth + 1); } - return depth; + return ++data->depth; } static void generate_json_object(FBuffer *buffer, struct generate_json_data *data, VALUE obj) diff --git a/java/src/json/ext/GeneratorState.java b/java/src/json/ext/GeneratorState.java index 778500ef7..97809134c 100644 --- a/java/src/json/ext/GeneratorState.java +++ b/java/src/json/ext/GeneratorState.java @@ -649,9 +649,8 @@ public RubyHash to_h(ThreadContext context) { } public int increaseDepth(ThreadContext context) { - depth++; checkMaxNesting(context); - return depth; + return ++depth; } public int decreaseDepth() { @@ -659,13 +658,12 @@ public int decreaseDepth() { } /** - * Checks if the current depth is allowed as per this state's options. + * Checks if increasing the depth is allowed as per this state's options. * @param context The current context */ private void checkMaxNesting(ThreadContext context) { - if (maxNesting != 0 && depth > maxNesting) { - depth--; - throw Utils.newException(context, Utils.M_NESTING_ERROR, "nesting of " + depth + " is too deep. Did you try to serialize objects with circular references?"); + if (maxNesting != 0 && depth >= maxNesting) { + throw Utils.newException(context, Utils.M_NESTING_ERROR, "nesting of " + (depth + 1) + " is too deep. Did you try to serialize objects with circular references?"); } } } diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb index 326780177..8f3ca4395 100755 --- a/test/json/json_generator_test.rb +++ b/test/json/json_generator_test.rb @@ -477,6 +477,18 @@ def test_depth_nesting_error assert_raise(JSON::NestingError) { JSON.pretty_generate(ary) } end + def test_nesting_error_reports_attempted_depth + [[[]], { a: {} }].each do |object| + [0, 1].each do |depth| + state = JSON.state.new(depth: depth, max_nesting: depth + 1) + error = assert_raise(JSON::NestingError) { state.generate(object) } + assert_match(/\Anesting of #{depth + 2} is too deep\./, error.message) + assert_equal depth, state.depth + assert_equal '[]', state.generate([]) + end + end + end + def test_depth_nesting_error_to_json ary = []; ary << ary s = JSON.state.new(depth: 1)