From bfdf02ea7290d1d76e457ffbb15cfef5e64bf547 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Fri, 18 Oct 2024 15:36:57 +0200 Subject: [PATCH] pretty_generate: don't apply object_nl / array_nl for empty containers Fix: https://github.com/ruby/json/issues/437 Before: ```json { "foo": { }, "bar": [ ] } ``` After: ```json { "foo": {}, "bar": [] } ``` --- ext/json/generator/generator.c | 14 ++++++++++++++ test/json/json_generator_test.rb | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index c35e86d9b8..fbfa2c724e 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -681,6 +681,13 @@ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_S if (max_nesting != 0 && depth > max_nesting) { rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth); } + + if (RHASH_SIZE(obj) == 0) { + fbuffer_append(buffer, "{}", 2); + --state->depth; + return; + } + fbuffer_append_char(buffer, '{'); arg.buffer = buffer; @@ -709,6 +716,13 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St if (max_nesting != 0 && depth > max_nesting) { rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth); } + + if (RARRAY_LEN(obj) == 0) { + fbuffer_append(buffer, "[]", 2); + --state->depth; + return; + } + fbuffer_append_char(buffer, '['); if (RB_UNLIKELY(state->array_nl)) fbuffer_append(buffer, state->array_nl, state->array_nl_len); for(i = 0; i < RARRAY_LEN(obj); i++) { diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb index 7dc45e3a52..32712c8343 100755 --- a/test/json/json_generator_test.rb +++ b/test/json/json_generator_test.rb @@ -90,10 +90,17 @@ EOT def test_generate_pretty json = pretty_generate({}) + assert_equal('{}', json) + + json = pretty_generate({1=>{}, 2=>[], 3=>4}) assert_equal(<<'EOT'.chomp, json) { + "1": {}, + "2": [], + "3": 4 } EOT + json = pretty_generate(@hash) # hashes aren't (insertion) ordered on every ruby implementation # assert_equal(@json3, json)