diff options
author | Florian Frank <flori@ping.de> | 2011-08-29 23:10:36 +0200 |
---|---|---|
committer | Florian Frank <flori@ping.de> | 2011-08-29 23:10:36 +0200 |
commit | e63431185a04d897c70fdef57e4260f410d997c2 (patch) | |
tree | c2dc96fad99a86081555a032ab4e5f110286f424 | |
parent | 2b5de6d03750b113333eded00177b14f8719042e (diff) | |
download | json-e63431185a04d897c70fdef57e4260f410d997c2.tar.gz |
Apply patch by Eric Wong <nocode@yhbt.net>
See https://github.com/flori/json/issues/46
-rw-r--r-- | ext/json/ext/generator/generator.c | 16 | ||||
-rw-r--r-- | ext/json/ext/generator/generator.h | 2 | ||||
-rwxr-xr-x | tests/test_json_generate.rb | 13 |
3 files changed, 26 insertions, 5 deletions
diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 26b667b..9a90d5f 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -349,6 +349,16 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len) } } +static void fbuffer_append_str(FBuffer *fb, VALUE str) +{ + const char *newstr = StringValuePtr(str); + unsigned long len = RSTRING_LEN(str); + + RB_GC_GUARD(str); + + fbuffer_append(fb, newstr, len); +} + static void fbuffer_append_char(FBuffer *fb, char newchr) { fbuffer_inc_capa(fb, 1); @@ -855,7 +865,7 @@ static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_S static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) { VALUE tmp = rb_funcall(obj, i_to_s, 0); - fbuffer_append(buffer, RSTRING_PAIR(tmp)); + fbuffer_append_str(buffer, tmp); } static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) @@ -872,7 +882,7 @@ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_St rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp)); } } - fbuffer_append(buffer, RSTRING_PAIR(tmp)); + fbuffer_append_str(buffer, tmp); } static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) @@ -900,7 +910,7 @@ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *s } else if (rb_respond_to(obj, i_to_json)) { tmp = rb_funcall(obj, i_to_json, 1, Vstate); Check_Type(tmp, T_STRING); - fbuffer_append(buffer, RSTRING_PAIR(tmp)); + fbuffer_append_str(buffer, tmp); } else { tmp = rb_funcall(obj, i_to_s, 0); Check_Type(tmp, T_STRING); diff --git a/ext/json/ext/generator/generator.h b/ext/json/ext/generator/generator.h index 6379f05..d72f71f 100644 --- a/ext/json/ext/generator/generator.h +++ b/ext/json/ext/generator/generator.h @@ -45,8 +45,6 @@ #define RSTRING_LEN(string) RSTRING(string)->len #endif -#define RSTRING_PAIR(string) RSTRING_PTR(string), RSTRING_LEN(string) - /* fbuffer implementation */ typedef struct FBufferStruct { diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index dc1450a..da96603 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -197,4 +197,17 @@ EOT assert_raises(JSON::NestingError) { ary.to_json(s) } assert_equal 19, s.depth end + + def test_gc + bignum_too_long_to_embed_as_string = 1234567890123456789012345 + expect = bignum_too_long_to_embed_as_string.to_s + stress, GC.stress = GC.stress, true + + 10.times do |i| + tmp = bignum_too_long_to_embed_as_string.to_json + assert_equal expect, tmp + end + ensure + GC.stress = stress + end if GC.respond_to?(:stress=) end |