Project

General

Profile

Bug #5173 ยป 0001-ext-json-generator-generator.c-prevent-GC-for-tempor.patch

normalperson (Eric Wong), 08/09/2011 10:45 AM

View differences:

ext/json/generator/generator.c
349 349
    }
350 350
}
351 351

  
352
static void fbuffer_append_str(FBuffer *fb, VALUE str)
353
{
354
    const char *newstr = RSTRING_PTR(str);
355
    unsigned long len = RSTRING_LEN(str);
356

  
357
    RB_GC_GUARD(str);
358

  
359
    fbuffer_append(fb, newstr, len);
360
}
361

  
352 362
static void fbuffer_append_char(FBuffer *fb, char newchr)
353 363
{
354 364
    fbuffer_inc_capa(fb, 1);
......
852 862
static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
853 863
{
854 864
    VALUE tmp = rb_funcall(obj, i_to_s, 0);
855
    fbuffer_append(buffer, RSTRING_PAIR(tmp));
865
    fbuffer_append_str(buffer, tmp);
856 866
}
857 867

  
858 868
static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
......
869 879
            rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
870 880
        }
871 881
    }
872
    fbuffer_append(buffer, RSTRING_PAIR(tmp));
882
    fbuffer_append_str(buffer, tmp);
873 883
}
874 884

  
875 885
static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
......
897 907
    } else if (rb_respond_to(obj, i_to_json)) {
898 908
        tmp = rb_funcall(obj, i_to_json, 1, Vstate);
899 909
        Check_Type(tmp, T_STRING);
900
        fbuffer_append(buffer, RSTRING_PAIR(tmp));
910
        fbuffer_append_str(buffer, tmp);
901 911
    } else {
902 912
        tmp = rb_funcall(obj, i_to_s, 0);
903 913
        Check_Type(tmp, T_STRING);
ext/json/generator/generator.h
45 45
#define RSTRING_LEN(string) RSTRING(string)->len
46 46
#endif
47 47

  
48
#define RSTRING_PAIR(string) RSTRING_PTR(string), RSTRING_LEN(string)
49

  
50 48
/* fbuffer implementation */
51 49

  
52 50
typedef struct FBufferStruct {
test/json/test_json_generate.rb
177 177
    assert_raises(JSON::NestingError) { ary.to_json(s) }
178 178
    assert_equal 19, s.depth
179 179
  end
180

  
181
  def test_gc
182
    bignum_too_long_to_embed_as_string = 1234567890123456789012345
183
    expect = bignum_too_long_to_embed_as_string.to_s
184
    stress, GC.stress = GC.stress, true
185

  
186
    10.times do |i|
187
      tmp = bignum_too_long_to_embed_as_string.to_json
188
      assert_equal expect, tmp
189
    end
190
    ensure
191
      GC.stress = stress
192
  end
180 193
end