Skip to content
Open
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
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

### Unreleased

* Emit a deprecation warning for the outdated `quirks_mode: true` argument.
* Emit a deprecation for `JSON.dump` positional `limit` argument.

### 2026-07-31 (2.21.2)

* Fix a use-after-free bug in `JSON::ResumableParser`. [GHSA-9hj4-r449-hfvc][CVE-2026-71847].
Expand Down
15 changes: 14 additions & 1 deletion lib/json/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,9 @@ def to_json(state = nil, *)
# JSON.parse('')
#
def parse(source, opts = nil)
if opts&.key?(:quirks_mode)
deprecation_warning("The `quirks_mode` option was removed since json 2.0 and has no effect. It will raise an error on json 3.0")
end
opts = ParserOptions.prepare(opts) unless opts.nil?
Parser.parse(source, opts)
end
Expand Down Expand Up @@ -451,6 +454,9 @@ def generate(obj, opts = nil)
if State === opts
opts.generate(obj)
else
if opts&.key?(:quirks_mode)
deprecation_warning("The `quirks_mode` option was removed since json 2.0 and has no effect. It will raise an error on json 3.0")
end
State.generate(obj, opts, nil)
end
end
Expand Down Expand Up @@ -960,7 +966,14 @@ def dump(obj, anIO = nil, limit = nil, kwargs = nil)
end

opts = JSON._dump_default_options
opts = opts.merge(:max_nesting => limit) if limit
if limit
if RUBY_VERSION >= "3.0"
warn "JSON.dump's positional `limit` argument is deprecated and will be removed in json 3.0.0. Pass `max_nesting:` instead.", uplevel: 1, category: :deprecated
else
warn "JSON.dump's positional `limit` argument is deprecated and will be removed in json 3.0.0. Pass `max_nesting:` instead.", uplevel: 1
end
opts = opts.merge(:max_nesting => limit)
end
opts = opts.merge(kwargs) if kwargs

begin
Expand Down
32 changes: 24 additions & 8 deletions test/json/json_common_interface_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -241,21 +241,37 @@ def test_dump
obj = eval(too_deep)
assert_equal too_deep, dump(obj)
assert_kind_of String, Marshal.dump(obj)
assert_raise(ArgumentError) { dump(obj, 100) }
assert_deprecated_warning(/max_nesting/) do
assert_raise(ArgumentError) { dump(obj, 100) }
end
assert_raise(ArgumentError) { Marshal.dump(obj, 100) }
assert_equal too_deep, dump(obj, 101)
assert_deprecated_warning(/max_nesting/) do
assert_equal too_deep, dump(obj, 101)
end
assert_kind_of String, Marshal.dump(obj, 101)

assert_equal too_deep, JSON.dump(obj, StringIO.new, 101, strict: false).string
assert_equal too_deep, dump(obj, StringIO.new, 101, strict: false).string
assert_raise(JSON::GeneratorError) { JSON.dump(Object.new, StringIO.new, 101, strict: true).string }
assert_raise(JSON::GeneratorError) { dump(Object.new, StringIO.new, 101, strict: true).string }
assert_deprecated_warning(/max_nesting/) do
assert_equal too_deep, JSON.dump(obj, StringIO.new, 101, strict: false).string
end
assert_deprecated_warning(/max_nesting/) do
assert_equal too_deep, dump(obj, StringIO.new, 101, strict: false).string
end
assert_deprecated_warning(/max_nesting/) do
assert_raise(JSON::GeneratorError) { JSON.dump(Object.new, StringIO.new, 101, strict: true).string }
end
assert_deprecated_warning(/max_nesting/) do
assert_raise(JSON::GeneratorError) { dump(Object.new, StringIO.new, 101, strict: true).string }
end

assert_equal too_deep, dump(obj, nil, nil, strict: false)
assert_equal too_deep, dump(obj, nil, 101, strict: false)
assert_deprecated_warning(/max_nesting/) do
assert_equal too_deep, dump(obj, nil, 101, strict: false)
end
assert_equal too_deep, dump(obj, StringIO.new, nil, strict: false).string
assert_equal too_deep, dump(obj, nil, strict: false)
assert_equal too_deep, dump(obj, 101, strict: false)
assert_deprecated_warning(/max_nesting/) do
assert_equal too_deep, dump(obj, 101, strict: false)
end
assert_equal too_deep, dump(obj, StringIO.new, strict: false).string
assert_equal too_deep, dump(obj, strict: false)
end
Expand Down
Loading