summaryrefslogtreecommitdiff
diff options
-rw-r--r--ext/json/generator/generator.c37
-rw-r--r--ext/json/lib/json/add/symbol.rb9
-rwxr-xr-xtest/json/json_generator_test.rb4
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