summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenta Murata <mrkn@mrkn.jp>2020-12-20 12:17:32 +0900
committerKenta Murata <mrkn@mrkn.jp>2020-12-21 22:10:33 +0900
commit98cc15ed1e9193e17fad6b87cccf8f8b5ade7801 (patch)
treeabc25c0a1e0509478e7d86045160897477b22e84
parentd84dd66da065cc40da69df5e042205209411c086 (diff)
[json] Stop using prototype objects
-rw-r--r--ext/json/generator/generator.c7
-rw-r--r--ext/json/lib/json/common.rb21
-rw-r--r--test/json/json_generator_test.rb39
3 files changed, 18 insertions, 49 deletions
diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c
index 80d1ca7bf3b..2e802c8ea40 100644
--- a/ext/json/generator/generator.c
+++ b/ext/json/generator/generator.c
@@ -15,8 +15,7 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
#endif
mFloat, mString, mString_Extend,
mTrueClass, mFalseClass, mNilClass, eGeneratorError,
- eNestingError,
- i_SAFE_STATE_PROTOTYPE;
+ eNestingError;
static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
@@ -1166,8 +1165,7 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts)
} else if (rb_obj_is_kind_of(opts, rb_cHash)) {
return rb_funcall(self, i_new, 1, opts);
} else {
- VALUE prototype = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
- return rb_funcall(prototype, i_dup, 0);
+ return rb_class_new_instance(0, NULL, cState);
}
}
@@ -1608,5 +1606,4 @@ void Init_generator(void)
i_encoding = rb_intern("encoding");
i_encode = rb_intern("encode");
#endif
- i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE");
}
diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb
index 111d70c3322..c34fa61eb7d 100644
--- a/ext/json/lib/json/common.rb
+++ b/ext/json/lib/json/common.rb
@@ -71,22 +71,27 @@ module JSON
end
self.state = generator::State
const_set :State, self.state
- const_set :SAFE_STATE_PROTOTYPE, State.new
- const_set :FAST_STATE_PROTOTYPE, State.new(
+ ensure
+ $VERBOSE = old
+ end
+
+ def create_fast_state
+ State.new(
:indent => '',
:space => '',
:object_nl => "",
:array_nl => "",
:max_nesting => false
)
- const_set :PRETTY_STATE_PROTOTYPE, State.new(
+ end
+
+ def create_pretty_state
+ State.new(
:indent => ' ',
:space => ' ',
:object_nl => "\n",
:array_nl => "\n"
)
- ensure
- $VERBOSE = old
end
# Returns the JSON generator module that is used by JSON. This is
@@ -276,7 +281,7 @@ module JSON
if State === opts
state, opts = opts, nil
else
- state = SAFE_STATE_PROTOTYPE.dup
+ state = State.new
end
if opts
if opts.respond_to? :to_hash
@@ -315,7 +320,7 @@ module JSON
if State === opts
state, opts = opts, nil
else
- state = FAST_STATE_PROTOTYPE.dup
+ state = JSON.create_fast_state
end
if opts
if opts.respond_to? :to_hash
@@ -370,7 +375,7 @@ module JSON
if State === opts
state, opts = opts, nil
else
- state = PRETTY_STATE_PROTOTYPE.dup
+ state = JSON.create_pretty_state
end
if opts
if opts.respond_to? :to_hash
diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb
index 2ecdc97298e..5bafc3ead46 100644
--- a/test/json/json_generator_test.rb
+++ b/test/json/json_generator_test.rb
@@ -48,35 +48,6 @@ EOT
$VERBOSE = v
end
- def test_remove_const_segv
- stress = GC.stress
- const = JSON::SAFE_STATE_PROTOTYPE.dup
-
- bignum_too_long_to_embed_as_string = 1234567890123456789012345
- expect = bignum_too_long_to_embed_as_string.to_s
- GC.stress = true
-
- 10.times do |i|
- tmp = bignum_too_long_to_embed_as_string.to_json
- raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect
- end
-
- silence do
- JSON.const_set :SAFE_STATE_PROTOTYPE, nil
- end
-
- 10.times do |i|
- assert_raise TypeError do
- bignum_too_long_to_embed_as_string.to_json
- end
- end
- ensure
- GC.stress = stress
- silence do
- JSON.const_set :SAFE_STATE_PROTOTYPE, const
- end
- end if JSON.const_defined?("Ext") && RUBY_ENGINE != 'jruby'
-
def test_generate
json = generate(@hash)
assert_equal(parse(@json2), parse(json))
@@ -171,7 +142,7 @@ EOT
end
def test_pretty_state
- state = PRETTY_STATE_PROTOTYPE.dup
+ state = JSON.create_pretty_state
assert_equal({
:allow_nan => false,
:array_nl => "\n",
@@ -188,7 +159,7 @@ EOT
end
def test_safe_state
- state = SAFE_STATE_PROTOTYPE.dup
+ state = JSON::State.new
assert_equal({
:allow_nan => false,
:array_nl => "",
@@ -205,7 +176,7 @@ EOT
end
def test_fast_state
- state = FAST_STATE_PROTOTYPE.dup
+ state = JSON.create_fast_state
assert_equal({
:allow_nan => false,
:array_nl => "",
@@ -241,12 +212,8 @@ EOT
def test_depth
ary = []; ary << ary
- assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
assert_raise(JSON::NestingError) { generate(ary) }
- assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
- assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
assert_raise(JSON::NestingError) { JSON.pretty_generate(ary) }
- assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
s = JSON.state.new
assert_equal 0, s.depth
assert_raise(JSON::NestingError) { ary.to_json(s) }