Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions ext/json/ext/generator/generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 4 additions & 6 deletions java/src/json/ext/GeneratorState.java
Original file line number Diff line number Diff line change
Expand Up @@ -649,23 +649,21 @@ public RubyHash to_h(ThreadContext context) {
}

public int increaseDepth(ThreadContext context) {
depth++;
checkMaxNesting(context);
return depth;
return ++depth;
}

public int decreaseDepth() {
return --depth;
}

/**
* 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?");
}
}
}
12 changes: 12 additions & 0 deletions test/json/json_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading