diff options
-rw-r--r-- | ext/json/generator/generator.c | 37 | ||||
-rw-r--r-- | ext/json/lib/json/add/symbol.rb | 9 | ||||
-rwxr-xr-x | test/json/json_generator_test.rb | 4 |
3 files changed, 40 insertions, 10 deletions
diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 119b1dfdaa..bb390d1b25 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -991,6 +991,29 @@ static void generate_json_string(FBuffer *buffer, struct generate_json_data *dat fbuffer_append_char(buffer, '"'); } +static void generate_json_fallback(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj) +{ + VALUE tmp; + if (rb_respond_to(obj, i_to_json)) { + tmp = rb_funcall(obj, i_to_json, 1, vstate_get(data)); + Check_Type(tmp, T_STRING); + fbuffer_append_str(buffer, tmp); + } else { + tmp = rb_funcall(obj, i_to_s, 0); + Check_Type(tmp, T_STRING); + generate_json_string(buffer, data, state, tmp); + } +} + +static inline void generate_json_symbol(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj) +{ + if (state->strict) { + generate_json_string(buffer, data, state, rb_sym2str(obj)); + } else { + generate_json_fallback(buffer, data, state, obj); + } +} + static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj) { fbuffer_append(buffer, "null", 4); @@ -1057,7 +1080,6 @@ static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *d static void generate_json(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj) { - VALUE tmp; bool as_json_called = false; start: if (obj == Qnil) { @@ -1071,6 +1093,8 @@ start: generate_json_fixnum(buffer, data, state, obj); } else if (RB_FLONUM_P(obj)) { generate_json_float(buffer, data, state, obj); + } else if (RB_STATIC_SYM_P(obj)) { + generate_json_symbol(buffer, data, state, obj); } else { goto general; } @@ -1092,6 +1116,9 @@ start: if (klass != rb_cString) goto general; generate_json_string(buffer, data, state, obj); break; + case T_SYMBOL: + generate_json_symbol(buffer, data, state, obj); + break; case T_FLOAT: if (klass != rb_cFloat) goto general; generate_json_float(buffer, data, state, obj); @@ -1110,14 +1137,8 @@ start: } else { raise_generator_error(obj, "%"PRIsVALUE" not allowed in JSON", CLASS_OF(obj)); } - } else if (rb_respond_to(obj, i_to_json)) { - tmp = rb_funcall(obj, i_to_json, 1, vstate_get(data)); - Check_Type(tmp, T_STRING); - fbuffer_append_str(buffer, tmp); } else { - tmp = rb_funcall(obj, i_to_s, 0); - Check_Type(tmp, T_STRING); - generate_json_string(buffer, data, state, tmp); + generate_json_fallback(buffer, data, state, obj); } } } diff --git a/ext/json/lib/json/add/symbol.rb b/ext/json/lib/json/add/symbol.rb index 1566ebc121..806be4f025 100644 --- a/ext/json/lib/json/add/symbol.rb +++ b/ext/json/lib/json/add/symbol.rb @@ -36,8 +36,13 @@ class Symbol # # # {"json_class":"Symbol","s":"foo"} # - def to_json(*a) - as_json.to_json(*a) + def to_json(state = nil, *a) + state = ::JSON::State.from_state(state) + if state.strict? + super + else + as_json.to_json(state, *a) + end end # See #as_json. diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb index d97f0505f7..942802d62f 100755 --- a/test/json/json_generator_test.rb +++ b/test/json/json_generator_test.rb @@ -86,6 +86,10 @@ class JSONGeneratorTest < Test::Unit::TestCase assert_equal '42', dump(42, strict: true) assert_equal 'true', dump(true, strict: true) + + assert_equal '"hello"', dump(:hello, strict: true) + assert_equal '"hello"', :hello.to_json(strict: true) + assert_equal '"World"', "World".to_json(strict: true) end def test_generate_pretty |