Skip to content

Commit fdac27b

Browse files
committed
Fix JSON.generate strict: true mode to also restrict hash keys
1 parent e77f610 commit fdac27b

5 files changed

Lines changed: 24 additions & 0 deletions

File tree

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
### Unreleased
44

5+
* Fix `JSON.generate` `strict: true` mode to also restrict hash keys.
6+
57
### 2025-07-28 (2.13.2)
68

79
* Improve duplicate key warning and errors to include the key name and point to the right caller.

ext/json/ext/generator/generator.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,9 @@ json_object_i(VALUE key, VALUE val, VALUE _arg)
10411041
key_to_s = rb_sym2str(key);
10421042
break;
10431043
default:
1044+
if (data->state->strict) {
1045+
raise_generator_error(key, "%"PRIsVALUE" not allowed in JSON", rb_funcall(key, i_to_s, 0));
1046+
}
10441047
key_to_s = rb_convert_type(key, T_STRING, "String", "to_s");
10451048
break;
10461049
}

java/src/json/ext/Generator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,9 @@ private static void processEntry(ThreadContext context, Session session, OutputS
544544
} else if (keyClass == runtime.getSymbol()) {
545545
keyStr = ((RubySymbol) key).id2name(context);
546546
} else {
547+
if (session.getState(context).strict()) {
548+
throw Utils.buildGeneratorError(context, key, key + " not allowed in JSON").toThrowable();
549+
}
547550
keyStr = TypeConverter.convertToType(key, runtime.getString(), "to_s");
548551
}
549552

lib/json/truffle_ruby/generator.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,10 @@ def json_transform(state)
476476
result << delim unless first
477477
result << state.indent * depth if indent
478478

479+
if state.strict? && !(Symbol === key || String === key)
480+
raise GeneratorError.new("#{key.class} not allowed in JSON", value)
481+
end
482+
479483
key_str = key.to_s
480484
if key_str.is_a?(String)
481485
key_json = key_str.to_json(state)

test/json/json_generator_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,18 @@ def test_json_generate_unsupported_types
404404
assert_raise JSON::GeneratorError do
405405
generate(Object.new, strict: true)
406406
end
407+
408+
assert_raise JSON::GeneratorError do
409+
generate([Object.new], strict: true)
410+
end
411+
412+
assert_raise JSON::GeneratorError do
413+
generate({ "key" => Object.new }, strict: true)
414+
end
415+
416+
assert_raise JSON::GeneratorError do
417+
generate({ Object.new => "value" }, strict: true)
418+
end
407419
end
408420

409421
def test_nesting

0 commit comments

Comments
 (0)