From 062d2ee6f798205c3046730d0d348cfd0d0bc09d Mon Sep 17 00:00:00 2001 From: naruse Date: Tue, 12 Feb 2013 03:05:45 +0000 Subject: * ext/json: merge JSON 1.7.7. This includes security fix. [CVE-2013-0269] https://github.com/flori/json/commit/d0a62f3ced7560daba2ad546d83f0479a5ae2cf2 https://groups.google.com/d/topic/rubyonrails-security/4_YvCpLzL58/discussion git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39208 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/json/generator/generator.c | 62 ++++++++++++++++++++++++++++++++---------- ext/json/generator/generator.h | 9 +++++- 2 files changed, 56 insertions(+), 15 deletions(-) (limited to 'ext/json/generator') diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 3cff87d7d5..ae4593c940 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -522,7 +522,7 @@ static VALUE cState_configure(VALUE self, VALUE opts) unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); - state->indent = fstrndup(RSTRING_PTR(tmp), len); + state->indent = fstrndup(RSTRING_PTR(tmp), len + 1); state->indent_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_space)); @@ -530,7 +530,7 @@ static VALUE cState_configure(VALUE self, VALUE opts) unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); - state->space = fstrndup(RSTRING_PTR(tmp), len); + state->space = fstrndup(RSTRING_PTR(tmp), len + 1); state->space_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_space_before)); @@ -538,7 +538,7 @@ static VALUE cState_configure(VALUE self, VALUE opts) unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); - state->space_before = fstrndup(RSTRING_PTR(tmp), len); + state->space_before = fstrndup(RSTRING_PTR(tmp), len + 1); state->space_before_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_array_nl)); @@ -546,7 +546,7 @@ static VALUE cState_configure(VALUE self, VALUE opts) unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); - state->array_nl = fstrndup(RSTRING_PTR(tmp), len); + state->array_nl = fstrndup(RSTRING_PTR(tmp), len + 1); state->array_nl_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_object_nl)); @@ -554,11 +554,11 @@ static VALUE cState_configure(VALUE self, VALUE opts) unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); - state->object_nl = fstrndup(RSTRING_PTR(tmp), len); + state->object_nl = fstrndup(RSTRING_PTR(tmp), len + 1); state->object_nl_len = len; } tmp = ID2SYM(i_max_nesting); - state->max_nesting = 19; + state->max_nesting = 100; if (option_given_p(opts, tmp)) { VALUE max_nesting = rb_hash_aref(opts, tmp); if (RTEST(max_nesting)) { @@ -598,6 +598,18 @@ static VALUE cState_configure(VALUE self, VALUE opts) return self; } +static void set_state_ivars(VALUE hash, VALUE state) +{ + VALUE ivars = rb_obj_instance_variables(state); + int i = 0; + for (i = 0; i < RARRAY_LEN(ivars); i++) { + VALUE key = rb_funcall(rb_ary_entry(ivars, i), i_to_s, 0); + long key_len = RSTRING_LEN(key); + VALUE value = rb_iv_get(state, StringValueCStr(key)); + rb_hash_aset(hash, rb_str_intern(rb_str_substr(key, 1, key_len - 1)), value); + } +} + /* * call-seq: to_h * @@ -608,6 +620,7 @@ static VALUE cState_to_h(VALUE self) { VALUE result = rb_hash_new(); GET_STATE(self); + set_state_ivars(result, self); rb_hash_aset(result, ID2SYM(i_indent), rb_str_new(state->indent, state->indent_len)); rb_hash_aset(result, ID2SYM(i_space), rb_str_new(state->space, state->space_len)); rb_hash_aset(result, ID2SYM(i_space_before), rb_str_new(state->space_before, state->space_before_len)); @@ -629,14 +642,33 @@ static VALUE cState_to_h(VALUE self) */ static VALUE cState_aref(VALUE self, VALUE name) { - GET_STATE(self); + name = rb_funcall(name, i_to_s, 0); if (RTEST(rb_funcall(self, i_respond_to_p, 1, name))) { return rb_funcall(self, i_send, 1, name); } else { - return Qnil; + return rb_ivar_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name))); } } +/* +* call-seq: []=(name, value) +* +* Set the attribute name to value. +*/ +static VALUE cState_aset(VALUE self, VALUE name, VALUE value) +{ + VALUE name_writer; + + name = rb_funcall(name, i_to_s, 0); + name_writer = rb_str_cat2(rb_str_dup(name), "="); + if (RTEST(rb_funcall(self, i_respond_to_p, 1, name_writer))) { + return rb_funcall(self, i_send, 2, name_writer, value); + } else { + rb_ivar_set(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)), value); + } + return Qnil; +} + static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) { char *object_nl = state->object_nl; @@ -908,7 +940,7 @@ static VALUE cState_initialize(int argc, VALUE *argv, VALUE self) { VALUE opts; GET_STATE(self); - state->max_nesting = 19; + state->max_nesting = 100; state->buffer_initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT; rb_scan_args(argc, argv, "01", &opts); if (!NIL_P(opts)) cState_configure(self, opts); @@ -970,7 +1002,7 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts) static VALUE cState_indent(VALUE self) { GET_STATE(self); - return state->indent ? rb_str_new2(state->indent) : rb_str_new2(""); + return state->indent ? rb_str_new(state->indent, state->indent_len) : rb_str_new2(""); } /* @@ -1007,7 +1039,7 @@ static VALUE cState_indent_set(VALUE self, VALUE indent) static VALUE cState_space(VALUE self) { GET_STATE(self); - return state->space ? rb_str_new2(state->space) : rb_str_new2(""); + return state->space ? rb_str_new(state->space, state->space_len) : rb_str_new2(""); } /* @@ -1044,7 +1076,7 @@ static VALUE cState_space_set(VALUE self, VALUE space) static VALUE cState_space_before(VALUE self) { GET_STATE(self); - return state->space_before ? rb_str_new2(state->space_before) : rb_str_new2(""); + return state->space_before ? rb_str_new(state->space_before, state->space_before_len) : rb_str_new2(""); } /* @@ -1081,7 +1113,7 @@ static VALUE cState_space_before_set(VALUE self, VALUE space_before) static VALUE cState_object_nl(VALUE self) { GET_STATE(self); - return state->object_nl ? rb_str_new2(state->object_nl) : rb_str_new2(""); + return state->object_nl ? rb_str_new(state->object_nl, state->object_nl_len) : rb_str_new2(""); } /* @@ -1117,7 +1149,7 @@ static VALUE cState_object_nl_set(VALUE self, VALUE object_nl) static VALUE cState_array_nl(VALUE self) { GET_STATE(self); - return state->array_nl ? rb_str_new2(state->array_nl) : rb_str_new2(""); + return state->array_nl ? rb_str_new(state->array_nl, state->array_nl_len) : rb_str_new2(""); } /* @@ -1327,7 +1359,9 @@ void Init_generator() rb_define_method(cState, "configure", cState_configure, 1); rb_define_alias(cState, "merge", "configure"); rb_define_method(cState, "to_h", cState_to_h, 0); + rb_define_alias(cState, "to_hash", "to_h"); rb_define_method(cState, "[]", cState_aref, 1); + rb_define_method(cState, "[]=", cState_aset, 2); rb_define_method(cState, "generate", cState_generate, 1); mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods"); diff --git a/ext/json/generator/generator.h b/ext/json/generator/generator.h index 7d429d512c..b58cc4bc2f 100644 --- a/ext/json/generator/generator.h +++ b/ext/json/generator/generator.h @@ -2,7 +2,6 @@ #define _GENERATOR_H_ #include -#include #include #include @@ -14,6 +13,14 @@ #include "re.h" #endif +#ifndef rb_intern_str +#define rb_intern_str(string) SYM2ID(rb_str_intern(string)) +#endif + +#ifndef rb_obj_instance_variables +#define rb_obj_instance_variables(object) rb_funcall(object, rb_intern("instance_variables"), 0) +#endif + #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key)) /* unicode defintions */ -- cgit v1.2.3