ruby-changes:58301
From: Aaron <ko1@a...>
Date: Fri, 18 Oct 2019 05:30:40 +0900 (JST)
Subject: [ruby-changes:58301] 9026e12f93 (master): Look up constant instead of caching in a global
https://git.ruby-lang.org/ruby.git/commit/?id=9026e12f93 From 9026e12f93bb0f3f63d7449cdb5eabb2e660088f Mon Sep 17 00:00:00 2001 From: Aaron Patterson <tenderlove@r...> Date: Thu, 17 Oct 2019 13:30:09 -0700 Subject: Look up constant instead of caching in a global The global can go bad if the compactor runs, so we need to look up the constant instead of caching it in a global. diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 443b4d3..e996161 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -15,7 +15,7 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject, https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L15 #endif mFloat, mString, mString_Extend, mTrueClass, mFalseClass, mNilClass, eGeneratorError, - eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE, + eNestingError, CRegexp_MULTILINE, i_SAFE_STATE_PROTOTYPE; static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before, @@ -1082,10 +1082,8 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts) https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L1082 } else if (rb_obj_is_kind_of(opts, rb_cHash)) { return rb_funcall(self, i_new, 1, opts); } else { - if (NIL_P(CJSON_SAFE_STATE_PROTOTYPE)) { - CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE); - } - return rb_funcall(CJSON_SAFE_STATE_PROTOTYPE, i_dup, 0); + VALUE prototype = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE); + return rb_funcall(prototype, i_dup, 0); } } @@ -1499,5 +1497,4 @@ void Init_generator(void) https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L1497 i_encode = rb_intern("encode"); #endif i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE"); - CJSON_SAFE_STATE_PROTOTYPE = Qnil; } diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb index d7f9ebe..3d9ab7a 100644 --- a/test/json/json_generator_test.rb +++ b/test/json/json_generator_test.rb @@ -40,6 +40,43 @@ class JSONGeneratorTest < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/json/json_generator_test.rb#L40 EOT end + def silence + v = $VERBOSE + $VERBOSE = nil + yield + ensure + $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 + def test_generate json = generate(@hash) assert_equal(parse(@json2), parse(json)) -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/