summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Frank <flori@ping.de>2011-08-29 23:10:36 +0200
committerFlorian Frank <flori@ping.de>2011-08-29 23:10:36 +0200
commite63431185a04d897c70fdef57e4260f410d997c2 (patch)
treec2dc96fad99a86081555a032ab4e5f110286f424
parent2b5de6d03750b113333eded00177b14f8719042e (diff)
downloadjson-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.c16
-rw-r--r--ext/json/ext/generator/generator.h2
-rwxr-xr-xtests/test_json_generate.rb13
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