From be7320fe65ddb20998fa0d7bccfcddcbc7cb09b9 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Wed, 13 Feb 2013 17:15:15 +0100 Subject: [PATCH 001/312] Correct typo --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index e3d12a7fc..4ad50b510 100644 --- a/CHANGES +++ b/CHANGES @@ -5,7 +5,7 @@ using the JSON.load/dump interface. If JSON::GenericObject is supposed to be automatically deserialised, this has to be explicitely enabled by setting - JSON::GenericObject.json_createble = true + JSON::GenericObject.json_creatable = true as well. * Remove useless assert in fbuffer implementation. * Apply patch attached to https://github.com/flori/json/issues#issue/155 From 22da7f38a2670a9afbd2352c7265697c5db8afb4 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Wed, 20 Feb 2013 23:47:56 +0100 Subject: [PATCH 002/312] Try to convert first with to_hash, then to_h rb_convert_type doesn't return if conversion fails, so use rb_check_convert_type and the raise vi rb_convert_type. Make sure, that this behaviour is consisten across all generator implementations. Fixes https://github.com/flori/json/issues/162 --- CHANGES | 3 +++ VERSION | 2 +- ext/json/ext/generator/generator.c | 5 +---- java/src/json/ext/OptionsReader.java | 5 +++-- json.gemspec | 8 ++++---- json_pure.gemspec | 8 ++++---- lib/json/pure/generator.rb | 7 +++++++ lib/json/version.rb | 2 +- tests/test_json_generate.rb | 16 ++++++++++++++++ 9 files changed, 40 insertions(+), 16 deletions(-) diff --git a/CHANGES b/CHANGES index 4ad50b510..da98e1f2e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2013-02-21 (1.7.8) + * Fix https://github.com/flori/json/issues/162 reported by Marc-Andre + Lafortune . Thanks! 2013-02-04 (1.7.7) * Security fix for JSON create_additions default value and JSON::GenericObject. It should not be possible to create additions unless diff --git a/VERSION b/VERSION index 91c74a589..84298f96d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.7.7 +1.7.8 diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index ae4593c94..6180f15fc 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -511,11 +511,8 @@ static VALUE cState_configure(VALUE self, VALUE opts) { VALUE tmp; GET_STATE(self); - tmp = rb_convert_type(opts, T_HASH, "Hash", "to_hash"); + tmp = rb_check_convert_type(opts, T_HASH, "Hash", "to_hash"); if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h"); - if (NIL_P(tmp)) { - rb_raise(rb_eArgError, "opts has to be hash like or convertable into a hash"); - } opts = tmp; tmp = rb_hash_aref(opts, ID2SYM(i_indent)); if (RTEST(tmp)) { diff --git a/java/src/json/ext/OptionsReader.java b/java/src/json/ext/OptionsReader.java index 683573570..821250311 100644 --- a/java/src/json/ext/OptionsReader.java +++ b/java/src/json/ext/OptionsReader.java @@ -24,13 +24,14 @@ final class OptionsReader { OptionsReader(ThreadContext context, IRubyObject vOpts) { this.context = context; this.runtime = context.getRuntime(); - if (vOpts == null || vOpts.isNil()) { opts = null; } else if (vOpts.respondsTo("to_hash")) { opts = vOpts.convertToHash(); - } else { + } else if (vOpts.respondsTo("to_h")) { opts = vOpts.callMethod(context, "to_h").convertToHash(); + } else { + opts = vOpts.convertToHash(); /* Should just raise the correct TypeError */ } } diff --git a/json.gemspec b/json.gemspec index bd83be9da..cbe644048 100644 --- a/json.gemspec +++ b/json.gemspec @@ -2,23 +2,23 @@ Gem::Specification.new do |s| s.name = "json" - s.version = "1.7.7" + s.version = "1.7.8" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2013-02-11" + s.date = "2013-02-20" s.description = "This is a JSON implementation as a Ruby extension in C." s.email = "flori@ping.de" s.extensions = ["ext/json/ext/generator/extconf.rb", "ext/json/ext/parser/extconf.rb"] s.extra_rdoc_files = ["README.rdoc"] - s.files = [".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] + s.files = [".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_unicode.rb", "./tests/test_json_addition.rb", "./tests/test_json_generate.rb", "./tests/test_json_encoding.rb", "./tests/test_json_generic_object.rb", "./tests/test_json.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for Ruby", "--main", "README.rdoc"] s.require_paths = ["lib"] s.rubygems_version = "1.8.25" s.summary = "JSON Implementation for Ruby" - s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] + s.test_files = ["./tests/test_json_string_matching.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_unicode.rb", "./tests/test_json_addition.rb", "./tests/test_json_generate.rb", "./tests/test_json_encoding.rb", "./tests/test_json_generic_object.rb", "./tests/test_json.rb"] if s.respond_to? :specification_version then s.specification_version = 3 diff --git a/json_pure.gemspec b/json_pure.gemspec index 2d8ccf36d..3ddcc16e1 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -2,22 +2,22 @@ Gem::Specification.new do |s| s.name = "json_pure" - s.version = "1.7.7" + s.version = "1.7.8" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2013-02-11" + s.date = "2013-02-20" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] - s.files = [".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] + s.files = [".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_unicode.rb", "./tests/test_json_addition.rb", "./tests/test_json_generate.rb", "./tests/test_json_encoding.rb", "./tests/test_json_generic_object.rb", "./tests/test_json.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] s.require_paths = ["lib"] s.rubygems_version = "1.8.25" s.summary = "JSON Implementation for Ruby" - s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] + s.test_files = ["./tests/test_json_string_matching.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_unicode.rb", "./tests/test_json_addition.rb", "./tests/test_json_generate.rb", "./tests/test_json_encoding.rb", "./tests/test_json_generic_object.rb", "./tests/test_json.rb"] if s.respond_to? :specification_version then s.specification_version = 3 diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index fcbc60411..76948fb06 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -220,6 +220,13 @@ def quirks_mode? # Configure this State instance with the Hash _opts_, and return # itself. def configure(opts) + if opts.respond_to?(:to_hash) + opts = opts.to_hash + elsif opts.respond_to?(:to_h) + opts = opts.to_h + else + raise TypeError, "can't convert #{opts.class} into Hash" + end for key, value in opts instance_variable_set "@#{key}", value end diff --git a/lib/json/version.rb b/lib/json/version.rb index 1de3d696f..01c06ffd7 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.7.7' + VERSION = '1.7.8' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index 978c6258d..ab3c74cc9 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -251,6 +251,22 @@ def test_configure_using_configure_and_merge assert_equal '5', state2.array_nl end + def test_configure_hash_conversion + state = JSON.state.new + state.configure(:indent => '1') + assert_equal '1', state.indent + state = JSON.state.new + foo = 'foo' + assert_raise(TypeError) do + state.configure(foo) + end + def foo.to_h + { :indent => '2' } + end + state.configure(foo) + assert_equal '2', state.indent + end + if defined?(JSON::Ext::Generator) def test_broken_bignum # [ruby-core:38867] pid = fork do From ca25df027a3b7b1baf786228e47f6dadfdb6af2e Mon Sep 17 00:00:00 2001 From: "NARUSE, Yui" Date: Mon, 11 Jun 2012 11:07:31 +0900 Subject: [PATCH 003/312] Validate UTF-8 strings. Raise JSON::GeneratorError on converting Ruby UTF-8 string to JSON as to JSON ASCII does. --- ext/json/ext/generator/generator.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 6180f15fc..8ceaa2bc7 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -273,7 +273,18 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string) escape_len = 2; break; default: - end++; + { + unsigned short clen = trailingBytesForUTF8[c] + 1; + if (end + clen > len) { + rb_raise(rb_path2class("JSON::GeneratorError"), + "partial character in source, but hit end"); + } + if (!isLegalUTF8((UTF8 *) p, clen)) { + rb_raise(rb_path2class("JSON::GeneratorError"), + "source sequence is illegal/malformed utf-8"); + } + end += clen; + } continue; break; } From 3e158410e81f94dbbc3da6b7b35f4f64983aa4e3 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 14 Feb 2013 23:56:57 +0100 Subject: [PATCH 004/312] Add test and implement pure versiong --- lib/json/pure/generator.rb | 25 ++++++++++++++++++++++++- tests/test_json_generate.rb | 6 ++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index 76948fb06..59e224569 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -70,6 +70,13 @@ def utf8_to_json_ascii(string) # :nodoc: rescue => e raise GeneratorError.wrap(e) end + + def valid_utf8?(string) + encoding = string.encoding + (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) && + string.valid_encoding? + end + module_function :valid_utf8? else def utf8_to_json(string) # :nodoc: string.gsub(/["\\\x0-\x1f]/n) { MAP[$&] } @@ -93,8 +100,22 @@ def utf8_to_json_ascii(string) # :nodoc: rescue => e raise GeneratorError.wrap(e) end + + def valid_utf8?(string) + string =~ + /\A( [\x09\x0A\x0D\x20-\x7E] # ASCII + | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 + )*\z/x + end end - module_function :utf8_to_json, :utf8_to_json_ascii + module_function :utf8_to_json, :utf8_to_json_ascii, :valid_utf8? + module Pure module Generator @@ -270,6 +291,8 @@ def to_h # GeneratorError exception. def generate(obj) result = obj.to_json(self) + JSON.valid_utf8?(result) or raise GeneratorError, + "source sequence #{result.inspect} is illegal/malformed utf-8" unless @quirks_mode unless result =~ /\A\s*\[/ && result =~ /\]\s*\Z/ || result =~ /\A\s*\{/ && result =~ /\}\s*\Z/ diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index ab3c74cc9..117a1553f 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -313,4 +313,10 @@ def test_hash_likeness_set_string assert_kind_of Hash, state_hash assert_equal :bar, state_hash[:foo] end + + def test_json_generate + assert_raise JSON::GeneratorError do + assert_equal true, JSON.generate(["\xea"]) + end + end end From a1f8f1487e1f37a78e775354d17b24a288ab8cbd Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 22 Feb 2013 03:02:22 +0100 Subject: [PATCH 005/312] Avoid funny http warning --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index e405da255..65d039b3d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ # vim: set ft=ruby: -source :rubygems +source 'https://rubygems.org' gemspec :name => 'json' gemspec :name => 'json_pure' From 4d77909d2d482670a455fff45215d5858cd6d87f Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 22 Feb 2013 03:10:36 +0100 Subject: [PATCH 006/312] Fix regex encoding problem on ruby-head, ouch --- json.gemspec | 2 +- json_pure.gemspec | 2 +- lib/json/pure/generator.rb | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/json.gemspec b/json.gemspec index cbe644048..d3c048927 100644 --- a/json.gemspec +++ b/json.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2013-02-20" + s.date = "2013-02-22" s.description = "This is a JSON implementation as a Ruby extension in C." s.email = "flori@ping.de" s.extensions = ["ext/json/ext/generator/extconf.rb", "ext/json/ext/parser/extconf.rb"] diff --git a/json_pure.gemspec b/json_pure.gemspec index 3ddcc16e1..d4a8433ed 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2013-02-20" + s.date = "2013-02-22" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index 59e224569..b6cf5e545 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -103,15 +103,15 @@ def utf8_to_json_ascii(string) # :nodoc: def valid_utf8?(string) string =~ - /\A( [\x09\x0A\x0D\x20-\x7E] # ASCII - | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte - | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs - | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte - | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates - | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 - | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 - | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 - )*\z/x + /\A( [\x09\x0a\x0d\x20-\x7e] # ASCII + | [\xc2-\xdf][\x80-\xbf] # non-overlong 2-byte + | \xe0[\xa0-\xbf][\x80-\xbf] # excluding overlongs + | [\xe1-\xec\xee\xef][\x80-\xbf]{2} # straight 3-byte + | \xed[\x80-\x9f][\x80-\xbf] # excluding surrogates + | \xf0[\x90-\xbf][\x80-\xbf]{2} # planes 1-3 + | [\xf1-\xf3][\x80-\xbf]{3} # planes 4-15 + | \xf4[\x80-\x8f][\x80-\xbf]{2} # plane 16 + )*\z/nx end end module_function :utf8_to_json, :utf8_to_json_ascii, :valid_utf8? From a8e9999eb134a422fa189b8ea1866538df56f0e6 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 25 Feb 2013 15:35:55 +0100 Subject: [PATCH 007/312] test ruby 2.0.0 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 185b3e5dd..f5b49d0c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ rvm: - 1.8.7 - 1.9.2 - 1.9.3 + - 2.0.0 - ree - rbx-18mode - rbx-19mode From 00d7a14b3e954126754ba36478f6d69e6c591249 Mon Sep 17 00:00:00 2001 From: ginriki Date: Mon, 29 Apr 2013 04:55:35 +0900 Subject: [PATCH 008/312] remove unnecessary if --- lib/json/pure/generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index b6cf5e545..9056a5d7f 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -368,7 +368,7 @@ def json_transform(state) } depth = state.depth -= 1 result << state.object_nl - result << state.indent * depth if indent if indent + result << state.indent * depth if indent result << '}' result end From 855c63bdfb1051176c5f5cd36ff8b1cc1ff364a7 Mon Sep 17 00:00:00 2001 From: "NARUSE, Yui" Date: Wed, 8 May 2013 13:55:11 +0900 Subject: [PATCH 009/312] Suppress warning: -Wchar-subscripts On some platforms char is signed char and giving signed char to isspace(int c) can cause unexpected behavior. To avoid such situation, it should cast as unsigned char. --- ext/json/ext/generator/generator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 8ceaa2bc7..ed7bb8288 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -902,8 +902,8 @@ static int isArrayOrObject(VALUE string) long string_len = RSTRING_LEN(string); char *p = RSTRING_PTR(string), *q = p + string_len - 1; if (string_len < 2) return 0; - for (; p < q && isspace(*p); p++); - for (; q > p && isspace(*q); q--); + for (; p < q && isspace((unsigned char)*p); p++); + for (; q > p && isspace((unsigned char)*q); q--); return (*p == '[' && *q == ']') || (*p == '{' && *q == '}'); } From 07950f1ab2b1ad2c35cf0a8366f63dd9f2a6f730 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 10 May 2013 17:37:02 +0200 Subject: [PATCH 010/312] resolved --- lib/json/generic_object.rb | 9 +++++++++ tests/test_json_generic_object.rb | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/json/generic_object.rb b/lib/json/generic_object.rb index 8b1074c94..8b8fd53be 100644 --- a/lib/json/generic_object.rb +++ b/lib/json/generic_object.rb @@ -31,6 +31,15 @@ def from_hash(object) object end end + + def load(source, proc = nil, opts = {}) + result = ::JSON.load(source, proc, opts.merge(:object_class => self)) + result.nil? ? new : result + end + + def dump(obj, *args) + ::JSON.dump(obj, *args) + end end self.json_creatable = false diff --git a/tests/test_json_generic_object.rb b/tests/test_json_generic_object.rb index 77ef22e6a..b96b73501 100644 --- a/tests/test_json_generic_object.rb +++ b/tests/test_json_generic_object.rb @@ -49,6 +49,16 @@ def test_from_hash assert_equal true, GenericObject.from_hash(true) end + def test_json_generic_object_load + empty = JSON::GenericObject.load(nil) + assert_kind_of JSON::GenericObject, empty + simple = JSON::GenericObject.load('{ "hello": "world" }') + assert_kind_of JSON::GenericObject, simple + assert_equal "world", simple.hello + json = JSON::GenericObject.dump(JSON::GenericObject[:hello => 'world']) + assert_equal json, '{ "hello": "world" }' + end + private def switch_json_creatable From e84d0cc31c8703f3120d49a0359b2d4b504e288c Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 10 May 2013 17:41:13 +0200 Subject: [PATCH 011/312] complete testing --- json.gemspec | 10 +++++----- json_pure.gemspec | 10 +++++----- tests/test_json_generic_object.rb | 9 +++++++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/json.gemspec b/json.gemspec index d3c048927..8262ddb50 100644 --- a/json.gemspec +++ b/json.gemspec @@ -6,22 +6,22 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2013-02-22" + s.date = "2013-05-10" s.description = "This is a JSON implementation as a Ruby extension in C." s.email = "flori@ping.de" s.extensions = ["ext/json/ext/generator/extconf.rb", "ext/json/ext/parser/extconf.rb"] s.extra_rdoc_files = ["README.rdoc"] - s.files = [".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_unicode.rb", "./tests/test_json_addition.rb", "./tests/test_json_generate.rb", "./tests/test_json_encoding.rb", "./tests/test_json_generic_object.rb", "./tests/test_json.rb"] + s.files = [".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for Ruby", "--main", "README.rdoc"] s.require_paths = ["lib"] - s.rubygems_version = "1.8.25" + s.rubygems_version = "2.0.3" s.summary = "JSON Implementation for Ruby" - s.test_files = ["./tests/test_json_string_matching.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_unicode.rb", "./tests/test_json_addition.rb", "./tests/test_json_generate.rb", "./tests/test_json_encoding.rb", "./tests/test_json_generic_object.rb", "./tests/test_json.rb"] + s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] if s.respond_to? :specification_version then - s.specification_version = 3 + s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) diff --git a/json_pure.gemspec b/json_pure.gemspec index d4a8433ed..f69d294e0 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -6,21 +6,21 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2013-02-22" + s.date = "2013-05-10" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] - s.files = [".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_unicode.rb", "./tests/test_json_addition.rb", "./tests/test_json_generate.rb", "./tests/test_json_encoding.rb", "./tests/test_json_generic_object.rb", "./tests/test_json.rb"] + s.files = [".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] s.require_paths = ["lib"] - s.rubygems_version = "1.8.25" + s.rubygems_version = "2.0.3" s.summary = "JSON Implementation for Ruby" - s.test_files = ["./tests/test_json_string_matching.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_unicode.rb", "./tests/test_json_addition.rb", "./tests/test_json_generate.rb", "./tests/test_json_encoding.rb", "./tests/test_json_generic_object.rb", "./tests/test_json.rb"] + s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] if s.respond_to? :specification_version then - s.specification_version = 3 + s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) diff --git a/tests/test_json_generic_object.rb b/tests/test_json_generic_object.rb index b96b73501..c196f4418 100644 --- a/tests/test_json_generic_object.rb +++ b/tests/test_json_generic_object.rb @@ -52,11 +52,16 @@ def test_from_hash def test_json_generic_object_load empty = JSON::GenericObject.load(nil) assert_kind_of JSON::GenericObject, empty - simple = JSON::GenericObject.load('{ "hello": "world" }') + simple_json = '{"json_class":"JSON::GenericObject","hello":"world"}' + simple = JSON::GenericObject.load(simple_json) assert_kind_of JSON::GenericObject, simple assert_equal "world", simple.hello + converting = JSON::GenericObject.load('{ "hello": "world" }') + assert_kind_of JSON::GenericObject, converting + assert_equal "world", converting.hello + json = JSON::GenericObject.dump(JSON::GenericObject[:hello => 'world']) - assert_equal json, '{ "hello": "world" }' + assert_equal json, '{"json_class":"JSON::GenericObject","hello":"world"}' end private From 6a8589c84d148b4f466a059bccd27ec59f54f64e Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 10 May 2013 17:53:09 +0200 Subject: [PATCH 012/312] forgot about 1.8 again --- tests/test_json_generic_object.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_json_generic_object.rb b/tests/test_json_generic_object.rb index c196f4418..c43c7762b 100644 --- a/tests/test_json_generic_object.rb +++ b/tests/test_json_generic_object.rb @@ -61,7 +61,7 @@ def test_json_generic_object_load assert_equal "world", converting.hello json = JSON::GenericObject.dump(JSON::GenericObject[:hello => 'world']) - assert_equal json, '{"json_class":"JSON::GenericObject","hello":"world"}' + assert_equal JSON(json), JSON('{"json_class":"JSON::GenericObject","hello":"world"}') end private From ce6ae3876e4b23b7387637d6416ad808d1dd3d31 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 13 May 2013 10:55:36 +0200 Subject: [PATCH 013/312] Bump to version 1.8.0 --- VERSION | 2 +- json.gemspec | 4 ++-- json_pure.gemspec | 4 ++-- lib/json/version.rb | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/VERSION b/VERSION index 84298f96d..27f9cd322 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.7.8 +1.8.0 diff --git a/json.gemspec b/json.gemspec index 8262ddb50..057756da9 100644 --- a/json.gemspec +++ b/json.gemspec @@ -2,11 +2,11 @@ Gem::Specification.new do |s| s.name = "json" - s.version = "1.7.8" + s.version = "1.8.0" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2013-05-10" + s.date = "2013-05-13" s.description = "This is a JSON implementation as a Ruby extension in C." s.email = "flori@ping.de" s.extensions = ["ext/json/ext/generator/extconf.rb", "ext/json/ext/parser/extconf.rb"] diff --git a/json_pure.gemspec b/json_pure.gemspec index f69d294e0..218520290 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -2,11 +2,11 @@ Gem::Specification.new do |s| s.name = "json_pure" - s.version = "1.7.8" + s.version = "1.8.0" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2013-05-10" + s.date = "2013-05-13" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] diff --git a/lib/json/version.rb b/lib/json/version.rb index 01c06ffd7..935484524 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.7.8' + VERSION = '1.8.0' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: From e6f3fdc135f10458e090201fbb15fafbaa166a0d Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 13 May 2013 12:55:41 +0200 Subject: [PATCH 014/312] Add to the CHANGES --- CHANGES | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index da98e1f2e..edccaeec0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,13 @@ -2013-02-21 (1.7.8) +2013-05-13 (1.8.0) * Fix https://github.com/flori/json/issues/162 reported by Marc-Andre Lafortune . Thanks! + * Applied patches by Yui NARUSE to suppress warning with + -Wchar-subscripts and better validate UTF-8 strings. + * Applied patch by ginriki@github to remove unnecessary if. + * Add load/dump interface to JSON::GenericObject to make + serialize :some_attribute, JSON::GenericObject + work in Rails active models for convenient SomeModel#some_attribute.foo.bar + access to serialised JSON data. 2013-02-04 (1.7.7) * Security fix for JSON create_additions default value and JSON::GenericObject. It should not be possible to create additions unless From ac60f654af91c301997b70107388cd1dbee4d0e1 Mon Sep 17 00:00:00 2001 From: Brian Shirai Date: Sat, 21 Sep 2013 10:13:12 -0700 Subject: [PATCH 015/312] Removed unnecessary and incorrect condition for Rubinius. --- lib/json/common.rb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/json/common.rb b/lib/json/common.rb index 65a74a1aa..e24f637f6 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -412,10 +412,7 @@ def self.swap!(string) # :nodoc: end # Shortuct for iconv. - if ::String.method_defined?(:encode) && - # XXX Rubinius doesn't support ruby 1.9 encoding yet - defined?(RUBY_ENGINE) && RUBY_ENGINE != 'rbx' - then + if ::String.method_defined?(:encode) # Encodes string using Ruby's _String.encode_ def self.iconv(to, from, string) string.encode(to, from) From a9b1820cd2c627e1ea4db9bb686012776a1a485c Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 17 Oct 2013 09:03:37 +0200 Subject: [PATCH 016/312] New version 1.8.1 --- .gitignore | 1 + CHANGES | 2 ++ VERSION | 2 +- json.gemspec | 7 ++++--- json_pure.gemspec | 7 ++++--- lib/json/version.rb | 2 +- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index c810962c7..297633e64 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ Gemfile.lock *.rbc .rbx .AppleDouble +.DS_Store diff --git a/CHANGES b/CHANGES index edccaeec0..6a67cfc54 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +2013-05-13 (1.8.1) + * Remove Rubinius exception since transcoding should be working now. 2013-05-13 (1.8.0) * Fix https://github.com/flori/json/issues/162 reported by Marc-Andre Lafortune . Thanks! diff --git a/VERSION b/VERSION index 27f9cd322..a8fdfda1c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8.0 +1.8.1 diff --git a/json.gemspec b/json.gemspec index 057756da9..a970ad51c 100644 --- a/json.gemspec +++ b/json.gemspec @@ -1,12 +1,13 @@ # -*- encoding: utf-8 -*- +# stub: json 1.8.1 ruby lib Gem::Specification.new do |s| s.name = "json" - s.version = "1.8.0" + s.version = "1.8.1" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2013-05-13" + s.date = "2013-10-17" s.description = "This is a JSON implementation as a Ruby extension in C." s.email = "flori@ping.de" s.extensions = ["ext/json/ext/generator/extconf.rb", "ext/json/ext/parser/extconf.rb"] @@ -16,7 +17,7 @@ Gem::Specification.new do |s| s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for Ruby", "--main", "README.rdoc"] s.require_paths = ["lib"] - s.rubygems_version = "2.0.3" + s.rubygems_version = "2.1.4" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] diff --git a/json_pure.gemspec b/json_pure.gemspec index 218520290..7d05093ea 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -1,12 +1,13 @@ # -*- encoding: utf-8 -*- +# stub: json_pure 1.8.1 ruby lib Gem::Specification.new do |s| s.name = "json_pure" - s.version = "1.8.0" + s.version = "1.8.1" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2013-05-13" + s.date = "2013-10-17" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] @@ -15,7 +16,7 @@ Gem::Specification.new do |s| s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] s.require_paths = ["lib"] - s.rubygems_version = "2.0.3" + s.rubygems_version = "2.1.4" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] diff --git a/lib/json/version.rb b/lib/json/version.rb index 935484524..47cdcd607 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.8.0' + VERSION = '1.8.1' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: From 92a96dea2b24b9c68856004d69491f46aedd0925 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 17 Oct 2013 13:53:47 +0200 Subject: [PATCH 017/312] Newest rubygems --- json.gemspec | 2 +- json_pure.gemspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/json.gemspec b/json.gemspec index a970ad51c..75926b199 100644 --- a/json.gemspec +++ b/json.gemspec @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for Ruby", "--main", "README.rdoc"] s.require_paths = ["lib"] - s.rubygems_version = "2.1.4" + s.rubygems_version = "2.1.9" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] diff --git a/json_pure.gemspec b/json_pure.gemspec index 7d05093ea..228458e09 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |s| s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] s.require_paths = ["lib"] - s.rubygems_version = "2.1.4" + s.rubygems_version = "2.1.9" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] From 833278428c8d3a80e69b1ed897585c7e307a4ca4 Mon Sep 17 00:00:00 2001 From: Ignacio Galindo Date: Thu, 31 Oct 2013 18:06:09 -0600 Subject: [PATCH 018/312] Fix typo in comment --- lib/json/common.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/common.rb b/lib/json/common.rb index e24f637f6..c01590b7b 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -411,7 +411,7 @@ def self.swap!(string) # :nodoc: string end - # Shortuct for iconv. + # Shortcut for iconv. if ::String.method_defined?(:encode) # Encodes string using Ruby's _String.encode_ def self.iconv(to, from, string) From 730440714b31c276407f562e492e0b96d7219084 Mon Sep 17 00:00:00 2001 From: Josh Kline Date: Sat, 28 Dec 2013 14:58:30 -0800 Subject: [PATCH 019/312] Spelling and grammar fixes for comments. --- lib/json/pure/generator.rb | 2 +- lib/json/pure/parser.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index 9056a5d7f..fc93e3f34 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -468,7 +468,7 @@ def to_json(state = nil, *args) end end - # Module that holds the extinding methods if, the String module is + # Module that holds the extending methods if, the String module is # included. module Extend # Raw Strings are JSON Objects (the raw bytes are stored in an diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index a41d1eeb1..937f56f02 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -64,7 +64,7 @@ class Parser < StringScanner # (keys) in a JSON object. Otherwise strings are returned, which is also # the default. # * *create_additions*: If set to true, the Parser creates - # additions when if a matching class and create_id was found. This + # additions when a matching class and create_id are found. This # option defaults to false. # * *object_class*: Defaults to Hash # * *array_class*: Defaults to Array From 0126f30ed8e277a50763d116f8d53b7111e0f61c Mon Sep 17 00:00:00 2001 From: Salimane Adjao Moustapha Date: Fri, 3 Jan 2014 11:19:03 +0100 Subject: [PATCH 020/312] Add Ruby 2.1.0 to .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f5b49d0c1..c98729010 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ rvm: - 1.9.2 - 1.9.3 - 2.0.0 + - 2.1.0 - ree - rbx-18mode - rbx-19mode From 22e724c4a2fbeb47009320c90f58f4532045f60c Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 1 Apr 2014 12:17:15 +0200 Subject: [PATCH 021/312] Change documentation to reflect new default value --- ext/json/ext/parser/parser.c | 2 +- lib/json/common.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index df89f2c58..90709204b 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1627,7 +1627,7 @@ static VALUE convert_encoding(VALUE source) * the default. * * *create_additions*: If set to false, the Parser doesn't create * additions even if a matchin class and create_id was found. This option - * defaults to true. + * defaults to false. * * *object_class*: Defaults to Hash * * *array_class*: Defaults to Array */ diff --git a/lib/json/common.rb b/lib/json/common.rb index c01590b7b..426d933b4 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -148,7 +148,7 @@ class MissingUnicodeSupport < JSONError; end # the default. # * *create_additions*: If set to false, the Parser doesn't create # additions even if a matching class and create_id was found. This option - # defaults to true. + # defaults to false. # * *object_class*: Defaults to Hash # * *array_class*: Defaults to Array def parse(source, opts = {}) @@ -169,7 +169,7 @@ def parse(source, opts = {}) # to true. # * *create_additions*: If set to false, the Parser doesn't create # additions even if a matching class and create_id was found. This option - # defaults to true. + # defaults to false. def parse!(source, opts = {}) opts = { :max_nesting => false, From 039dd9bc19ed407e467f7a4e9182028afb656a00 Mon Sep 17 00:00:00 2001 From: Daniel Grippi Date: Wed, 2 Apr 2014 11:11:25 -0400 Subject: [PATCH 022/312] Update json-java.gemspec Pluralize "license" to match other gemspecs. --- json-java.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json-java.gemspec b/json-java.gemspec index 79d8e3ad0..14864f8c4 100644 --- a/json-java.gemspec +++ b/json-java.gemspec @@ -11,7 +11,7 @@ spec = Gem::Specification.new do |s| s.homepage = "http://json-jruby.rubyforge.org/" s.platform = 'java' s.rubyforge_project = "json-jruby" - s.license = "Ruby" + s.licenses = ["Ruby"] s.files = Dir["{docs,lib,tests}/**/*"] end From 8594c69af548ce9c3f8240f40f1d64f5378cd245 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Thu, 3 Jul 2014 10:41:16 +0530 Subject: [PATCH 023/312] Use method_defined? to check if method exists instead of slower check on instance_methods --- lib/json/add/time.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/add/time.rb b/lib/json/add/time.rb index 338209d89..d9834677a 100644 --- a/lib/json/add/time.rb +++ b/lib/json/add/time.rb @@ -10,7 +10,7 @@ def self.json_create(object) if usec = object.delete('u') # used to be tv_usec -> tv_nsec object['n'] = usec * 1000 end - if instance_methods.include?(:tv_nsec) + if method_defined?(:tv_nsec) at(object['s'], Rational(object['n'], 1000)) else at(object['s'], object['n'] / 1000) From fdba825edd018f237a17637d00529d2d31a1b144 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Thu, 3 Jul 2014 10:49:29 +0530 Subject: [PATCH 024/312] Document `Complex` json generation methods. --- lib/json/add/complex.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/json/add/complex.rb b/lib/json/add/complex.rb index d7ebebf5f..2723f6010 100644 --- a/lib/json/add/complex.rb +++ b/lib/json/add/complex.rb @@ -4,10 +4,15 @@ defined?(::Complex) or require 'complex' class Complex + + # Deserializes JSON string by converting Real value r, imaginary + # value i, to a Complex object. def self.json_create(object) Complex(object['r'], object['i']) end + # Returns a hash, that will be turned into a JSON object and represent this + # object. def as_json(*) { JSON.create_id => self.class.name, @@ -16,7 +21,8 @@ def as_json(*) } end + # Stores class name (Complex) along with real value r and imaginary value i as JSON string def to_json(*) as_json.to_json end -end +end \ No newline at end of file From eede80ffc99f181db2b6610b2ce7fd144855b74a Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Thu, 3 Jul 2014 10:46:53 +0530 Subject: [PATCH 025/312] Document `Rational` json generation methods. --- lib/json/add/rational.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/json/add/rational.rb b/lib/json/add/rational.rb index 867cd92f0..c100d1386 100644 --- a/lib/json/add/rational.rb +++ b/lib/json/add/rational.rb @@ -4,19 +4,25 @@ defined?(::Rational) or require 'rational' class Rational + + # Deserializes JSON string by converting numerator value n, denominator + # value d, to a Rational object. def self.json_create(object) Rational(object['n'], object['d']) end + # Returns a hash, that will be turned into a JSON object and represent this + # object. def as_json(*) { - JSON.create_id => self.class.name, - 'n' => numerator, - 'd' => denominator, + JSON.create_id => self.class.name, + 'n' => numerator, + 'd' => denominator, } end + # Stores class name (Rational) along with numerator value n and denominator value d as JSON string def to_json(*) as_json.to_json end -end +end \ No newline at end of file From 54c8e4978264092090b354ff5f656e4a80bb6178 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 3 Jul 2014 10:47:44 +0200 Subject: [PATCH 026/312] Reindented --- lib/json/add/rational.rb | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/json/add/rational.rb b/lib/json/add/rational.rb index c100d1386..ee39c20e8 100644 --- a/lib/json/add/rational.rb +++ b/lib/json/add/rational.rb @@ -4,9 +4,8 @@ defined?(::Rational) or require 'rational' class Rational - - # Deserializes JSON string by converting numerator value n, denominator - # value d, to a Rational object. + # Deserializes JSON string by converting numerator value n, + # denominator value d, to a Rational object. def self.json_create(object) Rational(object['n'], object['d']) end @@ -15,9 +14,9 @@ def self.json_create(object) # object. def as_json(*) { - JSON.create_id => self.class.name, - 'n' => numerator, - 'd' => denominator, + JSON.create_id => self.class.name, + 'n' => numerator, + 'd' => denominator, } end @@ -25,4 +24,4 @@ def as_json(*) def to_json(*) as_json.to_json end -end \ No newline at end of file +end From 975b817c230f7412a3966d5579f8fbd4d646955a Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 3 Jul 2014 10:51:33 +0200 Subject: [PATCH 027/312] Newest ruby 2.1.x --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c98729010..94f3ed231 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ rvm: - 1.9.2 - 1.9.3 - 2.0.0 - - 2.1.0 + - 2.1.2 - ree - rbx-18mode - rbx-19mode From ce109bd35d97b7055064ca4dc52d8ddc30ee5132 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 3 Jul 2014 10:57:42 +0200 Subject: [PATCH 028/312] No binstubs --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 94f3ed231..e482ab1a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ # Passes arguments to bundle install (http://gembundler.com/man/bundle-install.1.html) -bundler_args: --binstubs +#bundler_args: --binstubs # Specify which ruby versions you wish to run your tests on, each version will be used rvm: From 12dfad5dc865a04aaa1a038f49ca445139edbd8e Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Thu, 3 Jul 2014 14:34:20 +0530 Subject: [PATCH 029/312] - Pass over generator.c for grammar fixes. - Typo fixes across json ext --- ext/json/ext/generator/generator.c | 20 ++++++++++---------- ext/json/ext/generator/generator.h | 2 +- ext/json/ext/parser/parser.c | 2 +- ext/json/ext/parser/parser.rl | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index ed7bb8288..976afc54b 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -646,7 +646,7 @@ static VALUE cState_to_h(VALUE self) /* * call-seq: [](name) * -* Return the value returned by method +name+. +* Returns the value returned by method +name+. */ static VALUE cState_aref(VALUE self, VALUE name) { @@ -661,7 +661,7 @@ static VALUE cState_aref(VALUE self, VALUE name) /* * call-seq: []=(name, value) * -* Set the attribute name to value. +* Sets the attribute name to value. */ static VALUE cState_aset(VALUE self, VALUE name, VALUE value) { @@ -958,7 +958,7 @@ static VALUE cState_initialize(int argc, VALUE *argv, VALUE self) /* * call-seq: initialize_copy(orig) * - * Initializes this object from orig if it to be duplicated/cloned and returns + * Initializes this object from orig if it can be duplicated/cloned and returns * it. */ static VALUE cState_init_copy(VALUE obj, VALUE orig) @@ -1005,7 +1005,7 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts) /* * call-seq: indent() * - * This string is used to indent levels in the JSON text. + * Returns the string that is used to indent levels in the JSON text. */ static VALUE cState_indent(VALUE self) { @@ -1016,7 +1016,7 @@ static VALUE cState_indent(VALUE self) /* * call-seq: indent=(indent) * - * This string is used to indent levels in the JSON text. + * Sets the string that is used to indent levels in the JSON text. */ static VALUE cState_indent_set(VALUE self, VALUE indent) { @@ -1041,7 +1041,7 @@ static VALUE cState_indent_set(VALUE self, VALUE indent) /* * call-seq: space() * - * This string is used to insert a space between the tokens in a JSON + * Returns the string that is used to insert a space between the tokens in a JSON * string. */ static VALUE cState_space(VALUE self) @@ -1053,7 +1053,7 @@ static VALUE cState_space(VALUE self) /* * call-seq: space=(space) * - * This string is used to insert a space between the tokens in a JSON + * Sets _space_ to the string that is used to insert a space between the tokens in a JSON * string. */ static VALUE cState_space_set(VALUE self, VALUE space) @@ -1079,7 +1079,7 @@ static VALUE cState_space_set(VALUE self, VALUE space) /* * call-seq: space_before() * - * This string is used to insert a space before the ':' in JSON objects. + * Returns the string that is used to insert a space before the ':' in JSON objects. */ static VALUE cState_space_before(VALUE self) { @@ -1090,7 +1090,7 @@ static VALUE cState_space_before(VALUE self) /* * call-seq: space_before=(space_before) * - * This string is used to insert a space before the ':' in JSON objects. + * Sets the string that is used to insert a space before the ':' in JSON objects. */ static VALUE cState_space_before_set(VALUE self, VALUE space_before) { @@ -1297,7 +1297,7 @@ static VALUE cState_depth_set(VALUE self, VALUE depth) /* * call-seq: buffer_initial_length * - * This integer returns the current inital length of the buffer. + * This integer returns the current initial length of the buffer. */ static VALUE cState_buffer_initial_length(VALUE self) { diff --git a/ext/json/ext/generator/generator.h b/ext/json/ext/generator/generator.h index b58cc4bc2..e2fbf1277 100644 --- a/ext/json/ext/generator/generator.h +++ b/ext/json/ext/generator/generator.h @@ -23,7 +23,7 @@ #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key)) -/* unicode defintions */ +/* unicode definitions */ #define UNI_STRICT_CONVERSION 1 diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 90709204b..e91e1611c 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1626,7 +1626,7 @@ static VALUE convert_encoding(VALUE source) * (keys) in a JSON object. Otherwise strings are returned, which is also * the default. * * *create_additions*: If set to false, the Parser doesn't create - * additions even if a matchin class and create_id was found. This option + * additions even if a matching class and create_id was found. This option * defaults to false. * * *object_class*: Defaults to Hash * * *array_class*: Defaults to Array diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index ab8d31817..c60e35cf8 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -610,7 +610,7 @@ static VALUE convert_encoding(VALUE source) * (keys) in a JSON object. Otherwise strings are returned, which is also * the default. * * *create_additions*: If set to false, the Parser doesn't create - * additions even if a matchin class and create_id was found. This option + * additions even if a matching class and create_id was found. This option * defaults to true. * * *object_class*: Defaults to Hash * * *array_class*: Defaults to Array From 61c255ca311d12ae2be0d6a58237054a2acdabff Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 3 Jul 2014 11:29:05 +0200 Subject: [PATCH 030/312] Test on Ruby 2.1.x as well --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f5b49d0c1..93916a0fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ rvm: - 1.9.2 - 1.9.3 - 2.0.0 + - 2.1 - ree - rbx-18mode - rbx-19mode From 6da014149519902b2797a32c869690c7d4eec77e Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 3 Jul 2014 11:35:24 +0200 Subject: [PATCH 031/312] Fix documentation wording --- ext/json/ext/generator/generator.c | 20 ++++++++++---------- ext/json/ext/generator/generator.h | 2 +- ext/json/ext/parser/parser.c | 4 ++-- ext/json/ext/parser/parser.rl | 2 +- java/src/json/ext/Parser.rl | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index ed7bb8288..976afc54b 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -646,7 +646,7 @@ static VALUE cState_to_h(VALUE self) /* * call-seq: [](name) * -* Return the value returned by method +name+. +* Returns the value returned by method +name+. */ static VALUE cState_aref(VALUE self, VALUE name) { @@ -661,7 +661,7 @@ static VALUE cState_aref(VALUE self, VALUE name) /* * call-seq: []=(name, value) * -* Set the attribute name to value. +* Sets the attribute name to value. */ static VALUE cState_aset(VALUE self, VALUE name, VALUE value) { @@ -958,7 +958,7 @@ static VALUE cState_initialize(int argc, VALUE *argv, VALUE self) /* * call-seq: initialize_copy(orig) * - * Initializes this object from orig if it to be duplicated/cloned and returns + * Initializes this object from orig if it can be duplicated/cloned and returns * it. */ static VALUE cState_init_copy(VALUE obj, VALUE orig) @@ -1005,7 +1005,7 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts) /* * call-seq: indent() * - * This string is used to indent levels in the JSON text. + * Returns the string that is used to indent levels in the JSON text. */ static VALUE cState_indent(VALUE self) { @@ -1016,7 +1016,7 @@ static VALUE cState_indent(VALUE self) /* * call-seq: indent=(indent) * - * This string is used to indent levels in the JSON text. + * Sets the string that is used to indent levels in the JSON text. */ static VALUE cState_indent_set(VALUE self, VALUE indent) { @@ -1041,7 +1041,7 @@ static VALUE cState_indent_set(VALUE self, VALUE indent) /* * call-seq: space() * - * This string is used to insert a space between the tokens in a JSON + * Returns the string that is used to insert a space between the tokens in a JSON * string. */ static VALUE cState_space(VALUE self) @@ -1053,7 +1053,7 @@ static VALUE cState_space(VALUE self) /* * call-seq: space=(space) * - * This string is used to insert a space between the tokens in a JSON + * Sets _space_ to the string that is used to insert a space between the tokens in a JSON * string. */ static VALUE cState_space_set(VALUE self, VALUE space) @@ -1079,7 +1079,7 @@ static VALUE cState_space_set(VALUE self, VALUE space) /* * call-seq: space_before() * - * This string is used to insert a space before the ':' in JSON objects. + * Returns the string that is used to insert a space before the ':' in JSON objects. */ static VALUE cState_space_before(VALUE self) { @@ -1090,7 +1090,7 @@ static VALUE cState_space_before(VALUE self) /* * call-seq: space_before=(space_before) * - * This string is used to insert a space before the ':' in JSON objects. + * Sets the string that is used to insert a space before the ':' in JSON objects. */ static VALUE cState_space_before_set(VALUE self, VALUE space_before) { @@ -1297,7 +1297,7 @@ static VALUE cState_depth_set(VALUE self, VALUE depth) /* * call-seq: buffer_initial_length * - * This integer returns the current inital length of the buffer. + * This integer returns the current initial length of the buffer. */ static VALUE cState_buffer_initial_length(VALUE self) { diff --git a/ext/json/ext/generator/generator.h b/ext/json/ext/generator/generator.h index b58cc4bc2..e2fbf1277 100644 --- a/ext/json/ext/generator/generator.h +++ b/ext/json/ext/generator/generator.h @@ -23,7 +23,7 @@ #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key)) -/* unicode defintions */ +/* unicode definitions */ #define UNI_STRICT_CONVERSION 1 diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index df89f2c58..e91e1611c 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1626,8 +1626,8 @@ static VALUE convert_encoding(VALUE source) * (keys) in a JSON object. Otherwise strings are returned, which is also * the default. * * *create_additions*: If set to false, the Parser doesn't create - * additions even if a matchin class and create_id was found. This option - * defaults to true. + * additions even if a matching class and create_id was found. This option + * defaults to false. * * *object_class*: Defaults to Hash * * *array_class*: Defaults to Array */ diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index ab8d31817..c60e35cf8 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -610,7 +610,7 @@ static VALUE convert_encoding(VALUE source) * (keys) in a JSON object. Otherwise strings are returned, which is also * the default. * * *create_additions*: If set to false, the Parser doesn't create - * additions even if a matchin class and create_id was found. This option + * additions even if a matching class and create_id was found. This option * defaults to true. * * *object_class*: Defaults to Hash * * *array_class*: Defaults to Array diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 6dd335ab8..7dcdd2ecb 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -128,7 +128,7 @@ public class Parser extends RubyObject { * *
:create_additions *
If set to false, the Parser doesn't create additions - * even if a matchin class and create_id was found. This option + * even if a matching class and create_id was found. This option * defaults to true. * *
:object_class From 6ae8732ef0e7a59e3457495f150c582301c00c7c Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Thu, 3 Jul 2014 14:34:20 +0530 Subject: [PATCH 032/312] - Pass over generator.c for grammar fixes. - Typo fixes across json ext --- Gemfile | 1 - json.gemspec | Bin 4869 -> 4942 bytes json_pure.gemspec | 8 ++++---- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 65d039b3d..ef9ce01fc 100644 --- a/Gemfile +++ b/Gemfile @@ -8,4 +8,3 @@ gemspec :name => 'json-java' gem 'utils' gem 'test-unit' -gem 'debugger', :platform => :mri_19 diff --git a/json.gemspec b/json.gemspec index 75926b199badba6cab46d410bb1b8f80a04e0a82..259b2362f7b07f897a0b9b404ea1c2873f4e1d8a 100644 GIT binary patch delta 94 zcmZowJEu0mj6+$WxTG}6N@21;vmztI= 0") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2013-10-17" + s.date = "2014-07-03" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] - s.files = [".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] + s.files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] - s.require_paths = ["lib"] - s.rubygems_version = "2.1.9" + s.rubygems_version = "2.2.2" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] From ddafccd28802c86fb2f5418566799742473bf2b2 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 3 Jul 2014 11:29:05 +0200 Subject: [PATCH 033/312] Test on Ruby 2.1.x as well --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e482ab1a8..d4f8f7abc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ rvm: - 1.9.2 - 1.9.3 - 2.0.0 - - 2.1.2 + - 2.1 - ree - rbx-18mode - rbx-19mode From 2a61ba5572a2bb484f6bfefe5bff350f4756bc21 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 3 Jul 2014 11:35:24 +0200 Subject: [PATCH 034/312] Fix documentation wording --- java/src/json/ext/Parser.rl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 6dd335ab8..7dcdd2ecb 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -128,7 +128,7 @@ public class Parser extends RubyObject { * *
:create_additions *
If set to false, the Parser doesn't create additions - * even if a matchin class and create_id was found. This option + * even if a matching class and create_id was found. This option * defaults to true. * *
:object_class From 5a4331918f61a8a4dbe12df8a12f66e5b4e4811a Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Thu, 3 Jul 2014 14:34:20 +0530 Subject: [PATCH 035/312] - Pass over generator.c for grammar fixes. - Typo fixes across json ext --- Gemfile | 1 - json.gemspec | Bin 4869 -> 4942 bytes json_pure.gemspec | 8 ++++---- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 65d039b3d..ef9ce01fc 100644 --- a/Gemfile +++ b/Gemfile @@ -8,4 +8,3 @@ gemspec :name => 'json-java' gem 'utils' gem 'test-unit' -gem 'debugger', :platform => :mri_19 diff --git a/json.gemspec b/json.gemspec index 75926b199badba6cab46d410bb1b8f80a04e0a82..259b2362f7b07f897a0b9b404ea1c2873f4e1d8a 100644 GIT binary patch delta 94 zcmZowJEu0mj6+$WxTG}6N@21;vmztI= 0") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2013-10-17" + s.date = "2014-07-03" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] - s.files = [".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] + s.files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] - s.require_paths = ["lib"] - s.rubygems_version = "2.1.9" + s.rubygems_version = "2.2.2" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] From 98780de119d7857f0b83fa61123fd7d768414abb Mon Sep 17 00:00:00 2001 From: "Jason R. Clark" Date: Fri, 19 Sep 2014 15:43:45 -0700 Subject: [PATCH 036/312] Don't mutate JSON.dump_default_options from dump The use of Hash#update from the JSON.dump method was mutating the dump_default_options hash on any call to dump with a limit provided. An individual method call with an overriding value shouldn't update the defaults in this way. --- lib/json/common.rb | 2 +- tests/test_json.rb | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/json/common.rb b/lib/json/common.rb index 426d933b4..32d989258 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -390,7 +390,7 @@ def dump(obj, anIO = nil, limit = nil) end end opts = JSON.dump_default_options - limit and opts.update(:max_nesting => limit) + opts = opts.merge(:max_nesting => limit) if limit result = generate(obj, opts) if anIO anIO.write result diff --git a/tests/test_json.rb b/tests/test_json.rb index 6af6b3220..f4e6696c3 100755 --- a/tests/test_json.rb +++ b/tests/test_json.rb @@ -515,6 +515,12 @@ def test_dump assert_equal too_deep, output.string end + def test_dump_should_modify_defaults + max_nesting = JSON.dump_default_options[:max_nesting] + JSON.dump([], StringIO.new, 10) + assert_equal max_nesting, JSON.dump_default_options[:max_nesting] + end + def test_big_integers json1 = JSON([orig = (1 << 31) - 1]) assert_equal orig, JSON[json1][0] From 0f02c30a54f9fd8d9e3400c8155d583dfec5b42d Mon Sep 17 00:00:00 2001 From: Iain Beeston Date: Tue, 4 Nov 2014 08:48:41 +0000 Subject: [PATCH 037/312] Added ruby-head to travis allowed-failures This is probably a contraversial idea. ruby-head can be fairly unstable but then json is a core gem. At least if it's an allowed-failure then builds will always be run against ruby-head, but pull requests (and master) won't report build failures if something is broken in ruby-head --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d4f8f7abc..5907de769 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,4 +18,5 @@ matrix: allow_failures: - rvm: rbx-18mode - rvm: rbx-19mode + - rvm: ruby-head script: "bundle exec rake" From 0c096ac8b9dae94d051439f98cbd6a21d2b1d212 Mon Sep 17 00:00:00 2001 From: Michael Mac-Vicar Date: Sun, 7 Dec 2014 15:17:17 -0200 Subject: [PATCH 038/312] Add test for format options used by the generator The space_before, space, indent, object_nl and array_nl options of the space were not covered. --- tests/test_json_generate.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index 117a1553f..a39e161d2 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -73,6 +73,19 @@ def test_generate_pretty assert_equal '666', pretty_generate(666, :quirks_mode => true) end + def test_generate_custom + state = State.new(space_before: " ", space: " ", indent:"", object_nl: "\n", array_nl: "") + json = generate({1=>{2=>3,4=>[5,6]}}, state) + assert_equal(<<'EOT'.chomp, json) +{ +"1" : { +"2" : 3, +"4" : [5,6] +} +} +EOT + end + def test_fast_generate json = fast_generate(@hash) assert_equal(JSON.parse(@json2), JSON.parse(json)) From c7b3a70cd649095ba46db5f8adcfcf5e688beb56 Mon Sep 17 00:00:00 2001 From: Michael Mac-Vicar Date: Sun, 7 Dec 2014 15:18:39 -0200 Subject: [PATCH 039/312] Use space_before as documented in the generator This option was already documented but not implemented, allows setting the separator used before the ":" during generation. --- ext/json/ext/generator/generator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 976afc54b..22d895241 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -871,6 +871,7 @@ static FBuffer *cState_prepare_buffer(VALUE self) } else { state->object_delim2 = fbuffer_alloc(16); } + if (state->space_before) fbuffer_append(state->object_delim2, state->space_before, state->space_before_len); fbuffer_append_char(state->object_delim2, ':'); if (state->space) fbuffer_append(state->object_delim2, state->space, state->space_len); From b3819dc971b700c58ecbbcded2450cd208a9400e Mon Sep 17 00:00:00 2001 From: Michael Mac-Vicar Date: Sun, 7 Dec 2014 15:48:40 -0200 Subject: [PATCH 040/312] Make generator format test backwards compatible --- tests/test_json_generate.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index a39e161d2..c47ae8811 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -74,7 +74,7 @@ def test_generate_pretty end def test_generate_custom - state = State.new(space_before: " ", space: " ", indent:"", object_nl: "\n", array_nl: "") + state = State.new(:space_before => " ", :space => " ", :indent => "", :object_nl => "\n", :array_nl => "") json = generate({1=>{2=>3,4=>[5,6]}}, state) assert_equal(<<'EOT'.chomp, json) { From eaac48419d196e909fcdf526c4e3dbec2cc3d19b Mon Sep 17 00:00:00 2001 From: Ben Browning Date: Tue, 16 Dec 2014 10:12:10 -0500 Subject: [PATCH 041/312] Improve JRuby perf. by removing source of multithreaded contention The RuntimeInfo.forRuntime method synchronizes all invocations and ParserSession#parseString was calling this many times when parsing large JSON strings. Thus, when running in a heavily multithreaded environment, threads were spending a large portion of their time waiting on that synchronization instead of doing work parsing the JSON. This fix simply passes in the RuntimeInfo object to the ParserSession when it's instantiated, since the RuntimeInfo is already known and we've already incurred the synchronization cost at that time. Using the test script at https://gist.github.com/bbrowning/0b89580b03a5f19e7a9f, I get the following results before and after this fix on my machine: Before: $ jruby ~/tmp/json_contention.rb 337.920000 0.570000 338.490000 ( 57.955000) After: $ jruby ~/tmp/json_contention.rb 326.400000 0.580000 326.980000 ( 43.084000) That's a 25% reduction in processing time for parsing the same JSON on my quad core machine. I'd expect an even higher percentage improvement on a machine with more CPUs. --- java/src/json/ext/Parser.java | 171 +++++++++++++++++----------------- java/src/json/ext/Parser.rl | 9 +- 2 files changed, 91 insertions(+), 89 deletions(-) diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index 6cb5886a7..37423f540 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -130,7 +130,7 @@ public Parser(Ruby runtime, RubyClass metaClass) { * *
:create_additions *
If set to false, the Parser doesn't create additions - * even if a matchin class and create_id was found. This option + * even if a matching class and create_id was found. This option * defaults to true. * *
:object_class @@ -248,7 +248,7 @@ private RubyString reinterpretEncoding(ThreadContext context, */ @JRubyMethod public IRubyObject parse(ThreadContext context) { - return new ParserSession(this, context).parse(); + return new ParserSession(this, context, info).parse(); } /** @@ -304,6 +304,7 @@ private RubyString getCreateId(ThreadContext context) { private static class ParserSession { private final Parser parser; private final ThreadContext context; + private final RuntimeInfo info; private final ByteList byteList; private final ByteList view; private final byte[] data; @@ -315,9 +316,10 @@ private static class ParserSession { // no idea about the origins of this value, ask Flori ;) private static final int EVIL = 0x666; - private ParserSession(Parser parser, ThreadContext context) { + private ParserSession(Parser parser, ThreadContext context, RuntimeInfo info) { this.parser = parser; this.context = context; + this.info = info; this.byteList = parser.checkAndGetSource().getByteList(); this.data = byteList.unsafeBytes(); this.view = new ByteList(data, false); @@ -337,11 +339,11 @@ private Ruby getRuntime() { } -// line 363 "Parser.rl" +// line 365 "Parser.rl" -// line 345 "Parser.java" +// line 347 "Parser.java" private static byte[] init__JSON_value_actions_0() { return new byte [] { @@ -455,7 +457,7 @@ private static byte[] init__JSON_value_from_state_actions_0() static final int JSON_value_en_main = 1; -// line 469 "Parser.rl" +// line 471 "Parser.rl" void parseValue(ParserResult res, int p, int pe) { @@ -463,14 +465,14 @@ void parseValue(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 467 "Parser.java" +// line 469 "Parser.java" { cs = JSON_value_start; } -// line 476 "Parser.rl" +// line 478 "Parser.rl" -// line 474 "Parser.java" +// line 476 "Parser.java" { int _klen; int _trans = 0; @@ -496,13 +498,13 @@ void parseValue(ParserResult res, int p, int pe) { while ( _nacts-- > 0 ) { switch ( _JSON_value_actions[_acts++] ) { case 9: -// line 454 "Parser.rl" +// line 456 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 506 "Parser.java" +// line 508 "Parser.java" } } @@ -565,25 +567,25 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) switch ( _JSON_value_actions[_acts++] ) { case 0: -// line 371 "Parser.rl" +// line 373 "Parser.rl" { result = getRuntime().getNil(); } break; case 1: -// line 374 "Parser.rl" +// line 376 "Parser.rl" { result = getRuntime().getFalse(); } break; case 2: -// line 377 "Parser.rl" +// line 379 "Parser.rl" { result = getRuntime().getTrue(); } break; case 3: -// line 380 "Parser.rl" +// line 382 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_NAN); @@ -593,7 +595,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 4: -// line 387 "Parser.rl" +// line 389 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_INFINITY); @@ -603,7 +605,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 5: -// line 394 "Parser.rl" +// line 396 "Parser.rl" { if (pe > p + 9 - (parser.quirksMode ? 1 : 0) && absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) { @@ -632,7 +634,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 6: -// line 420 "Parser.rl" +// line 422 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -645,7 +647,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 7: -// line 430 "Parser.rl" +// line 432 "Parser.rl" { currentNesting++; parseArray(res, p, pe); @@ -660,7 +662,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 8: -// line 442 "Parser.rl" +// line 444 "Parser.rl" { currentNesting++; parseObject(res, p, pe); @@ -674,7 +676,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } } break; -// line 678 "Parser.java" +// line 680 "Parser.java" } } } @@ -694,7 +696,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) break; } } -// line 477 "Parser.rl" +// line 479 "Parser.rl" if (cs >= JSON_value_first_final && result != null) { res.update(result, p); @@ -704,7 +706,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } -// line 708 "Parser.java" +// line 710 "Parser.java" private static byte[] init__JSON_integer_actions_0() { return new byte [] { @@ -803,7 +805,7 @@ private static byte[] init__JSON_integer_trans_actions_0() static final int JSON_integer_en_main = 1; -// line 496 "Parser.rl" +// line 498 "Parser.rl" void parseInteger(ParserResult res, int p, int pe) { @@ -821,15 +823,15 @@ int parseIntegerInternal(int p, int pe) { int cs = EVIL; -// line 825 "Parser.java" +// line 827 "Parser.java" { cs = JSON_integer_start; } -// line 513 "Parser.rl" +// line 515 "Parser.rl" int memo = p; -// line 833 "Parser.java" +// line 835 "Parser.java" { int _klen; int _trans = 0; @@ -910,13 +912,13 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) switch ( _JSON_integer_actions[_acts++] ) { case 0: -// line 490 "Parser.rl" +// line 492 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 920 "Parser.java" +// line 922 "Parser.java" } } } @@ -936,7 +938,7 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) break; } } -// line 515 "Parser.rl" +// line 517 "Parser.rl" if (cs < JSON_integer_first_final) { return -1; @@ -958,7 +960,7 @@ RubyInteger bytesToInum(Ruby runtime, ByteList num) { } -// line 962 "Parser.java" +// line 964 "Parser.java" private static byte[] init__JSON_float_actions_0() { return new byte [] { @@ -1060,7 +1062,7 @@ private static byte[] init__JSON_float_trans_actions_0() static final int JSON_float_en_main = 1; -// line 550 "Parser.rl" +// line 552 "Parser.rl" void parseFloat(ParserResult res, int p, int pe) { @@ -1078,15 +1080,15 @@ int parseFloatInternal(int p, int pe) { int cs = EVIL; -// line 1082 "Parser.java" +// line 1084 "Parser.java" { cs = JSON_float_start; } -// line 567 "Parser.rl" +// line 569 "Parser.rl" int memo = p; -// line 1090 "Parser.java" +// line 1092 "Parser.java" { int _klen; int _trans = 0; @@ -1167,13 +1169,13 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) switch ( _JSON_float_actions[_acts++] ) { case 0: -// line 541 "Parser.rl" +// line 543 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1177 "Parser.java" +// line 1179 "Parser.java" } } } @@ -1193,7 +1195,7 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) break; } } -// line 569 "Parser.rl" +// line 571 "Parser.rl" if (cs < JSON_float_first_final) { return -1; @@ -1209,7 +1211,7 @@ RubyFloat createFloat(int p, int new_p) { } -// line 1213 "Parser.java" +// line 1215 "Parser.java" private static byte[] init__JSON_string_actions_0() { return new byte [] { @@ -1311,7 +1313,7 @@ private static byte[] init__JSON_string_trans_actions_0() static final int JSON_string_en_main = 1; -// line 614 "Parser.rl" +// line 616 "Parser.rl" void parseString(ParserResult res, int p, int pe) { @@ -1319,15 +1321,15 @@ void parseString(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 1323 "Parser.java" +// line 1325 "Parser.java" { cs = JSON_string_start; } -// line 621 "Parser.rl" +// line 623 "Parser.rl" int memo = p; -// line 1331 "Parser.java" +// line 1333 "Parser.java" { int _klen; int _trans = 0; @@ -1408,7 +1410,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) switch ( _JSON_string_actions[_acts++] ) { case 0: -// line 589 "Parser.rl" +// line 591 "Parser.rl" { int offset = byteList.begin(); ByteList decoded = decoder.decode(byteList, memo + 1 - offset, @@ -1423,13 +1425,13 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) } break; case 1: -// line 602 "Parser.rl" +// line 604 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1433 "Parser.java" +// line 1435 "Parser.java" } } } @@ -1449,7 +1451,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) break; } } -// line 623 "Parser.rl" +// line 625 "Parser.rl" if (parser.createAdditions) { RubyHash match_string = parser.match_string; @@ -1476,8 +1478,7 @@ public void visit(IRubyObject pattern, IRubyObject klass) { } } - if (cs >= JSON_string_first_final && result != null) { - RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + if (cs >= JSON_string_first_final && result != null) { if (info.encodingsSupported() && result instanceof RubyString) { ((RubyString)result).force_encoding(context, info.utf8.get()); } @@ -1488,7 +1489,7 @@ public void visit(IRubyObject pattern, IRubyObject klass) { } -// line 1492 "Parser.java" +// line 1493 "Parser.java" private static byte[] init__JSON_array_actions_0() { return new byte [] { @@ -1601,7 +1602,7 @@ private static byte[] init__JSON_array_trans_actions_0() static final int JSON_array_en_main = 1; -// line 697 "Parser.rl" +// line 698 "Parser.rl" void parseArray(ParserResult res, int p, int pe) { @@ -1621,14 +1622,14 @@ void parseArray(ParserResult res, int p, int pe) { } -// line 1625 "Parser.java" +// line 1626 "Parser.java" { cs = JSON_array_start; } -// line 716 "Parser.rl" +// line 717 "Parser.rl" -// line 1632 "Parser.java" +// line 1633 "Parser.java" { int _klen; int _trans = 0; @@ -1709,7 +1710,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) switch ( _JSON_array_actions[_acts++] ) { case 0: -// line 666 "Parser.rl" +// line 667 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1726,13 +1727,13 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } break; case 1: -// line 681 "Parser.rl" +// line 682 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1736 "Parser.java" +// line 1737 "Parser.java" } } } @@ -1752,7 +1753,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) break; } } -// line 717 "Parser.rl" +// line 718 "Parser.rl" if (cs >= JSON_array_first_final) { res.update(result, p + 1); @@ -1762,7 +1763,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } -// line 1766 "Parser.java" +// line 1767 "Parser.java" private static byte[] init__JSON_object_actions_0() { return new byte [] { @@ -1885,7 +1886,7 @@ private static byte[] init__JSON_object_trans_actions_0() static final int JSON_object_en_main = 1; -// line 776 "Parser.rl" +// line 777 "Parser.rl" void parseObject(ParserResult res, int p, int pe) { @@ -1910,14 +1911,14 @@ void parseObject(ParserResult res, int p, int pe) { } -// line 1914 "Parser.java" +// line 1915 "Parser.java" { cs = JSON_object_start; } -// line 800 "Parser.rl" +// line 801 "Parser.rl" -// line 1921 "Parser.java" +// line 1922 "Parser.java" { int _klen; int _trans = 0; @@ -1998,7 +1999,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) switch ( _JSON_object_actions[_acts++] ) { case 0: -// line 731 "Parser.rl" +// line 732 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2015,7 +2016,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 1: -// line 746 "Parser.rl" +// line 747 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -2035,13 +2036,13 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 2: -// line 764 "Parser.rl" +// line 765 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 2045 "Parser.java" +// line 2046 "Parser.java" } } } @@ -2061,7 +2062,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) break; } } -// line 801 "Parser.rl" +// line 802 "Parser.rl" if (cs < JSON_object_first_final) { res.update(null, p + 1); @@ -2094,7 +2095,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } -// line 2098 "Parser.java" +// line 2099 "Parser.java" private static byte[] init__JSON_actions_0() { return new byte [] { @@ -2198,7 +2199,7 @@ private static byte[] init__JSON_trans_actions_0() static final int JSON_en_main = 1; -// line 866 "Parser.rl" +// line 867 "Parser.rl" public IRubyObject parseStrict() { @@ -2208,16 +2209,16 @@ public IRubyObject parseStrict() { ParserResult res = new ParserResult(); -// line 2212 "Parser.java" +// line 2213 "Parser.java" { cs = JSON_start; } -// line 875 "Parser.rl" +// line 876 "Parser.rl" p = byteList.begin(); pe = p + byteList.length(); -// line 2221 "Parser.java" +// line 2222 "Parser.java" { int _klen; int _trans = 0; @@ -2298,7 +2299,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) switch ( _JSON_actions[_acts++] ) { case 0: -// line 838 "Parser.rl" +// line 839 "Parser.rl" { currentNesting = 1; parseObject(res, p, pe); @@ -2312,7 +2313,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) } break; case 1: -// line 850 "Parser.rl" +// line 851 "Parser.rl" { currentNesting = 1; parseArray(res, p, pe); @@ -2325,7 +2326,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) } } break; -// line 2329 "Parser.java" +// line 2330 "Parser.java" } } } @@ -2345,7 +2346,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) break; } } -// line 878 "Parser.rl" +// line 879 "Parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -2355,7 +2356,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) } -// line 2359 "Parser.java" +// line 2360 "Parser.java" private static byte[] init__JSON_quirks_mode_actions_0() { return new byte [] { @@ -2458,7 +2459,7 @@ private static byte[] init__JSON_quirks_mode_trans_actions_0() static final int JSON_quirks_mode_en_main = 1; -// line 906 "Parser.rl" +// line 907 "Parser.rl" public IRubyObject parseQuirksMode() { @@ -2468,16 +2469,16 @@ public IRubyObject parseQuirksMode() { ParserResult res = new ParserResult(); -// line 2472 "Parser.java" +// line 2473 "Parser.java" { cs = JSON_quirks_mode_start; } -// line 915 "Parser.rl" +// line 916 "Parser.rl" p = byteList.begin(); pe = p + byteList.length(); -// line 2481 "Parser.java" +// line 2482 "Parser.java" { int _klen; int _trans = 0; @@ -2558,7 +2559,7 @@ else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] ) switch ( _JSON_quirks_mode_actions[_acts++] ) { case 0: -// line 892 "Parser.rl" +// line 893 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2570,7 +2571,7 @@ else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] ) } } break; -// line 2574 "Parser.java" +// line 2575 "Parser.java" } } } @@ -2590,7 +2591,7 @@ else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] ) break; } } -// line 918 "Parser.rl" +// line 919 "Parser.rl" if (cs >= JSON_quirks_mode_first_final && p == pe) { return result; diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 7dcdd2ecb..6d6596314 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -246,7 +246,7 @@ public class Parser extends RubyObject { */ @JRubyMethod public IRubyObject parse(ThreadContext context) { - return new ParserSession(this, context).parse(); + return new ParserSession(this, context, info).parse(); } /** @@ -302,6 +302,7 @@ public class Parser extends RubyObject { private static class ParserSession { private final Parser parser; private final ThreadContext context; + private final RuntimeInfo info; private final ByteList byteList; private final ByteList view; private final byte[] data; @@ -313,9 +314,10 @@ public class Parser extends RubyObject { // no idea about the origins of this value, ask Flori ;) private static final int EVIL = 0x666; - private ParserSession(Parser parser, ThreadContext context) { + private ParserSession(Parser parser, ThreadContext context, RuntimeInfo info) { this.parser = parser; this.context = context; + this.info = info; this.byteList = parser.checkAndGetSource().getByteList(); this.data = byteList.unsafeBytes(); this.view = new ByteList(data, false); @@ -646,8 +648,7 @@ public class Parser extends RubyObject { } } - if (cs >= JSON_string_first_final && result != null) { - RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + if (cs >= JSON_string_first_final && result != null) { if (info.encodingsSupported() && result instanceof RubyString) { ((RubyString)result).force_encoding(context, info.utf8.get()); } From 153fbab807989d5bf8456b334b0c7b8e870a8907 Mon Sep 17 00:00:00 2001 From: Juanito Fatas Date: Fri, 19 Dec 2014 00:47:47 +0800 Subject: [PATCH 042/312] Use the new build env on Travis. --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5907de769..cef5c53f9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ # Passes arguments to bundle install (http://gembundler.com/man/bundle-install.1.html) #bundler_args: --binstubs +language: ruby # Specify which ruby versions you wish to run your tests on, each version will be used rvm: @@ -20,3 +21,5 @@ matrix: - rvm: rbx-19mode - rvm: ruby-head script: "bundle exec rake" + +sudo: false From 18b3000090d1044425d369a58ebe52f5342b9699 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Thu, 25 Dec 2014 15:43:37 -0500 Subject: [PATCH 043/312] Sync with trunk --- ext/json/ext/fbuffer/fbuffer.h | 11 +++- ext/json/ext/generator/depend | 20 +++++++ ext/json/ext/generator/extconf.rb | 10 ---- ext/json/ext/generator/generator.c | 63 +++++++++++++------- ext/json/ext/generator/generator.h | 14 +++-- ext/json/ext/parser/depend | 19 ++++++ ext/json/ext/parser/extconf.rb | 10 ---- ext/json/ext/parser/parser.c | 93 +++++++++++++++++------------- ext/json/ext/parser/parser.h | 9 +-- ext/json/ext/parser/parser.rl | 25 ++++++-- ext/json/ext/parser/prereq.mk | 10 ++++ lib/json/add/complex.rb | 8 +-- lib/json/add/rational.rb | 5 -- lib/json/add/time.rb | 2 +- lib/json/common.rb | 10 ++-- 15 files changed, 197 insertions(+), 112 deletions(-) create mode 100644 ext/json/ext/parser/prereq.mk diff --git a/ext/json/ext/fbuffer/fbuffer.h b/ext/json/ext/fbuffer/fbuffer.h index af7418756..5a0a27cda 100644 --- a/ext/json/ext/fbuffer/fbuffer.h +++ b/ext/json/ext/fbuffer/fbuffer.h @@ -25,6 +25,15 @@ #define RSTRING_LEN(string) RSTRING(string)->len #endif +#ifdef PRIsVALUE +# define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj) +# define RB_OBJ_STRING(obj) (obj) +#else +# define PRIsVALUE "s" +# define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj) +# define RB_OBJ_STRING(obj) StringValueCStr(obj) +#endif + #ifdef HAVE_RUBY_ENCODING_H #include "ruby/encoding.h" #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding()) @@ -172,7 +181,7 @@ static FBuffer *fbuffer_dup(FBuffer *fb) static VALUE fbuffer_to_s(FBuffer *fb) { - VALUE result = rb_str_new(FBUFFER_PAIR(fb)); + VALUE result = rb_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb)); fbuffer_free(fb); FORCE_UTF8(result); return result; diff --git a/ext/json/ext/generator/depend b/ext/json/ext/generator/depend index 1a042a250..b7373cde1 100644 --- a/ext/json/ext/generator/depend +++ b/ext/json/ext/generator/depend @@ -1 +1,21 @@ +$(OBJS): $(ruby_headers) generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h + +# AUTOGENERATED DEPENDENCIES START +generator.o: $(RUBY_EXTCONF_H) +generator.o: $(arch_hdrdir)/ruby/config.h +generator.o: $(hdrdir)/ruby/defines.h +generator.o: $(hdrdir)/ruby/encoding.h +generator.o: $(hdrdir)/ruby/intern.h +generator.o: $(hdrdir)/ruby/missing.h +generator.o: $(hdrdir)/ruby/oniguruma.h +generator.o: $(hdrdir)/ruby/re.h +generator.o: $(hdrdir)/ruby/regex.h +generator.o: $(hdrdir)/ruby/ruby.h +generator.o: $(hdrdir)/ruby/st.h +generator.o: $(hdrdir)/ruby/subst.h +generator.o: $(top_srcdir)/ext/json/fbuffer/fbuffer.h +generator.o: $(top_srcdir)/include/ruby.h +generator.o: generator.c +generator.o: generator.h +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/json/ext/generator/extconf.rb b/ext/json/ext/generator/extconf.rb index c9475019d..8627c5f4b 100644 --- a/ext/json/ext/generator/extconf.rb +++ b/ext/json/ext/generator/extconf.rb @@ -1,14 +1,4 @@ require 'mkmf' -unless $CFLAGS.gsub!(/ -O[\dsz]?/, ' -O3') - $CFLAGS << ' -O3' -end -if CONFIG['CC'] =~ /gcc/ - $CFLAGS << ' -Wall' - unless $DEBUG && !$CFLAGS.gsub!(/ -O[\dsz]?/, ' -O0 -ggdb') - $CFLAGS << ' -O0 -ggdb' - end -end - $defs << "-DJSON_GENERATOR" create_makefile 'json/ext/generator' diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 976afc54b..f56ac09cd 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -486,8 +486,9 @@ static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self) return cState_partial_generate(state, string); } -static void State_free(JSON_Generator_State *state) +static void State_free(void *ptr) { + JSON_Generator_State *state = ptr; if (state->indent) ruby_xfree(state->indent); if (state->space) ruby_xfree(state->space); if (state->space_before) ruby_xfree(state->space_before); @@ -499,17 +500,38 @@ static void State_free(JSON_Generator_State *state) ruby_xfree(state); } -static JSON_Generator_State *State_allocate() +static size_t State_memsize(const void *ptr) { - JSON_Generator_State *state = ALLOC(JSON_Generator_State); - MEMZERO(state, JSON_Generator_State, 1); + const JSON_Generator_State *state = ptr; + size_t size = sizeof(*state); + if (state->indent) size += state->indent_len + 1; + if (state->space) size += state->space_len + 1; + if (state->space_before) size += state->space_before_len + 1; + if (state->object_nl) size += state->object_nl_len + 1; + if (state->array_nl) size += state->array_nl_len + 1; + if (state->array_delim) size += FBUFFER_CAPA(state->array_delim); + if (state->object_delim) size += FBUFFER_CAPA(state->object_delim); + if (state->object_delim2) size += FBUFFER_CAPA(state->object_delim2); + return size; +} + +static const rb_data_type_t JSON_Generator_State_type = { + "JSON/Generator/State", + {NULL, State_free, State_memsize,}, + 0, 0, + RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static JSON_Generator_State *State_allocate(void) +{ + JSON_Generator_State *state = ZALLOC(JSON_Generator_State); return state; } static VALUE cState_s_allocate(VALUE klass) { JSON_Generator_State *state = State_allocate(); - return Data_Wrap_Struct(klass, NULL, State_free, state); + return TypedData_Wrap_Struct(klass, &JSON_Generator_State_type, state); } /* @@ -646,7 +668,7 @@ static VALUE cState_to_h(VALUE self) /* * call-seq: [](name) * -* Returns the value returned by method +name+. +* Return the value returned by method +name+. */ static VALUE cState_aref(VALUE self, VALUE name) { @@ -661,7 +683,7 @@ static VALUE cState_aref(VALUE self, VALUE name) /* * call-seq: []=(name, value) * -* Sets the attribute name to value. +* Set the attribute name to value. */ static VALUE cState_aset(VALUE self, VALUE name, VALUE value) { @@ -812,10 +834,10 @@ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_St if (!allow_nan) { if (isinf(value)) { fbuffer_free(buffer); - rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp)); + rb_raise(eGeneratorError, "%u: %"PRIsVALUE" not allowed in JSON", __LINE__, RB_OBJ_STRING(tmp)); } else if (isnan(value)) { fbuffer_free(buffer); - rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp)); + rb_raise(eGeneratorError, "%u: %"PRIsVALUE" not allowed in JSON", __LINE__, RB_OBJ_STRING(tmp)); } } fbuffer_append_str(buffer, tmp); @@ -958,15 +980,16 @@ static VALUE cState_initialize(int argc, VALUE *argv, VALUE self) /* * call-seq: initialize_copy(orig) * - * Initializes this object from orig if it can be duplicated/cloned and returns + * Initializes this object from orig if it to be duplicated/cloned and returns * it. */ static VALUE cState_init_copy(VALUE obj, VALUE orig) { JSON_Generator_State *objState, *origState; - Data_Get_Struct(obj, JSON_Generator_State, objState); - Data_Get_Struct(orig, JSON_Generator_State, origState); + if (obj == orig) return obj; + GET_STATE_TO(obj, objState); + GET_STATE_TO(orig, origState); if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State"); MEMCPY(objState, origState, JSON_Generator_State, 1); @@ -1005,7 +1028,7 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts) /* * call-seq: indent() * - * Returns the string that is used to indent levels in the JSON text. + * This string is used to indent levels in the JSON text. */ static VALUE cState_indent(VALUE self) { @@ -1016,7 +1039,7 @@ static VALUE cState_indent(VALUE self) /* * call-seq: indent=(indent) * - * Sets the string that is used to indent levels in the JSON text. + * This string is used to indent levels in the JSON text. */ static VALUE cState_indent_set(VALUE self, VALUE indent) { @@ -1041,7 +1064,7 @@ static VALUE cState_indent_set(VALUE self, VALUE indent) /* * call-seq: space() * - * Returns the string that is used to insert a space between the tokens in a JSON + * This string is used to insert a space between the tokens in a JSON * string. */ static VALUE cState_space(VALUE self) @@ -1053,7 +1076,7 @@ static VALUE cState_space(VALUE self) /* * call-seq: space=(space) * - * Sets _space_ to the string that is used to insert a space between the tokens in a JSON + * This string is used to insert a space between the tokens in a JSON * string. */ static VALUE cState_space_set(VALUE self, VALUE space) @@ -1079,7 +1102,7 @@ static VALUE cState_space_set(VALUE self, VALUE space) /* * call-seq: space_before() * - * Returns the string that is used to insert a space before the ':' in JSON objects. + * This string is used to insert a space before the ':' in JSON objects. */ static VALUE cState_space_before(VALUE self) { @@ -1090,7 +1113,7 @@ static VALUE cState_space_before(VALUE self) /* * call-seq: space_before=(space_before) * - * Sets the string that is used to insert a space before the ':' in JSON objects. + * This string is used to insert a space before the ':' in JSON objects. */ static VALUE cState_space_before_set(VALUE self, VALUE space_before) { @@ -1297,7 +1320,7 @@ static VALUE cState_depth_set(VALUE self, VALUE depth) /* * call-seq: buffer_initial_length * - * This integer returns the current initial length of the buffer. + * This integer returns the current inital length of the buffer. */ static VALUE cState_buffer_initial_length(VALUE self) { @@ -1326,7 +1349,7 @@ static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_l /* * */ -void Init_generator() +void Init_generator(void) { rb_require("json/common"); diff --git a/ext/json/ext/generator/generator.h b/ext/json/ext/generator/generator.h index e2fbf1277..ddd1aa8a3 100644 --- a/ext/json/ext/generator/generator.h +++ b/ext/json/ext/generator/generator.h @@ -23,7 +23,7 @@ #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key)) -/* unicode definitions */ +/* unicode defintions */ #define UNI_STRICT_CONVERSION 1 @@ -78,9 +78,12 @@ typedef struct JSON_Generator_StateStruct { long buffer_initial_length; } JSON_Generator_State; +#define GET_STATE_TO(self, state) \ + TypedData_Get_Struct(self, JSON_Generator_State, &JSON_Generator_State_type, state) + #define GET_STATE(self) \ JSON_Generator_State *state; \ - Data_Get_Struct(self, JSON_Generator_State, state) + GET_STATE_TO(self, state) #define GENERATE_JSON(type) \ FBuffer *buffer; \ @@ -89,7 +92,7 @@ typedef struct JSON_Generator_StateStruct { \ rb_scan_args(argc, argv, "01", &Vstate); \ Vstate = cState_from_state_s(cState, Vstate); \ - Data_Get_Struct(Vstate, JSON_Generator_State, state); \ + TypedData_Get_Struct(Vstate, JSON_Generator_State, &JSON_Generator_State_type, state); \ buffer = cState_prepare_buffer(Vstate); \ generate_json_##type(buffer, Vstate, state, self); \ return fbuffer_to_s(buffer) @@ -108,8 +111,8 @@ static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self); static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self); static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self); static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self); -static void State_free(JSON_Generator_State *state); -static JSON_Generator_State *State_allocate(); +static void State_free(void *state); +static JSON_Generator_State *State_allocate(void); static VALUE cState_s_allocate(VALUE klass); static VALUE cState_configure(VALUE self, VALUE opts); static VALUE cState_to_h(VALUE self); @@ -144,5 +147,6 @@ static VALUE cState_ascii_only_p(VALUE self); static VALUE cState_depth(VALUE self); static VALUE cState_depth_set(VALUE self, VALUE depth); static FBuffer *cState_prepare_buffer(VALUE self); +static const rb_data_type_t JSON_Generator_State_type; #endif diff --git a/ext/json/ext/parser/depend b/ext/json/ext/parser/depend index 498ffa964..bc5db0640 100644 --- a/ext/json/ext/parser/depend +++ b/ext/json/ext/parser/depend @@ -1 +1,20 @@ +$(OBJS): $(ruby_headers) parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h + +# AUTOGENERATED DEPENDENCIES START +parser.o: $(RUBY_EXTCONF_H) +parser.o: $(arch_hdrdir)/ruby/config.h +parser.o: $(hdrdir)/ruby/defines.h +parser.o: $(hdrdir)/ruby/encoding.h +parser.o: $(hdrdir)/ruby/intern.h +parser.o: $(hdrdir)/ruby/missing.h +parser.o: $(hdrdir)/ruby/oniguruma.h +parser.o: $(hdrdir)/ruby/ruby.h +parser.o: $(hdrdir)/ruby/st.h +parser.o: $(hdrdir)/ruby/subst.h +parser.o: $(top_srcdir)/ext/json/fbuffer/fbuffer.h +parser.o: $(top_srcdir)/include/ruby.h +parser.o: parser.c +parser.o: parser.h +parser.o: parser.rl +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/json/ext/parser/extconf.rb b/ext/json/ext/parser/extconf.rb index 4791829df..ae4f861c7 100644 --- a/ext/json/ext/parser/extconf.rb +++ b/ext/json/ext/parser/extconf.rb @@ -1,13 +1,3 @@ require 'mkmf' -unless $CFLAGS.gsub!(/ -O[\dsz]?/, ' -O3') - $CFLAGS << ' -O3' -end -if CONFIG['CC'] =~ /gcc/ - $CFLAGS << ' -Wall' - if $DEBUG && !$CFLAGS.gsub!(/ -O[\dsz]?/, ' -O0 -ggdb') - $CFLAGS << ' -O0 -ggdb' - end -end - create_makefile 'json/ext/parser' diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index e91e1611c..560aa8977 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -89,11 +89,11 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, #line 92 "parser.c" -static const int JSON_object_start = 1; -static const int JSON_object_first_final = 27; -static const int JSON_object_error = 0; +enum {JSON_object_start = 1}; +enum {JSON_object_first_final = 27}; +enum {JSON_object_error = 0}; -static const int JSON_object_en_main = 1; +enum {JSON_object_en_main = 1}; #line 151 "parser.rl" @@ -467,11 +467,11 @@ case 26: #line 470 "parser.c" -static const int JSON_value_start = 1; -static const int JSON_value_first_final = 21; -static const int JSON_value_error = 0; +enum {JSON_value_start = 1}; +enum {JSON_value_first_final = 21}; +enum {JSON_value_error = 0}; -static const int JSON_value_en_main = 1; +enum {JSON_value_en_main = 1}; #line 271 "parser.rl" @@ -776,11 +776,11 @@ case 20: #line 779 "parser.c" -static const int JSON_integer_start = 1; -static const int JSON_integer_first_final = 3; -static const int JSON_integer_error = 0; +enum {JSON_integer_start = 1}; +enum {JSON_integer_first_final = 3}; +enum {JSON_integer_error = 0}; -static const int JSON_integer_en_main = 1; +enum {JSON_integer_en_main = 1}; #line 295 "parser.rl" @@ -875,11 +875,11 @@ case 5: #line 878 "parser.c" -static const int JSON_float_start = 1; -static const int JSON_float_first_final = 8; -static const int JSON_float_error = 0; +enum {JSON_float_start = 1}; +enum {JSON_float_first_final = 8}; +enum {JSON_float_error = 0}; -static const int JSON_float_en_main = 1; +enum {JSON_float_en_main = 1}; #line 329 "parser.rl" @@ -1041,11 +1041,11 @@ case 7: #line 1044 "parser.c" -static const int JSON_array_start = 1; -static const int JSON_array_first_final = 17; -static const int JSON_array_error = 0; +enum {JSON_array_start = 1}; +enum {JSON_array_first_final = 17}; +enum {JSON_array_error = 0}; -static const int JSON_array_en_main = 1; +enum {JSON_array_en_main = 1}; #line 381 "parser.rl" @@ -1373,11 +1373,11 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) #line 1376 "parser.c" -static const int JSON_string_start = 1; -static const int JSON_string_first_final = 8; -static const int JSON_string_error = 0; +enum {JSON_string_start = 1}; +enum {JSON_string_first_final = 8}; +enum {JSON_string_error = 0}; -static const int JSON_string_en_main = 1; +enum {JSON_string_en_main = 1}; #line 494 "parser.rl" @@ -1626,8 +1626,8 @@ static VALUE convert_encoding(VALUE source) * (keys) in a JSON object. Otherwise strings are returned, which is also * the default. * * *create_additions*: If set to false, the Parser doesn't create - * additions even if a matching class and create_id was found. This option - * defaults to false. + * additions even if a matchin class and create_id was found. This option + * defaults to true. * * *object_class*: Defaults to Hash * * *array_class*: Defaults to Array */ @@ -1730,11 +1730,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) #line 1733 "parser.c" -static const int JSON_start = 1; -static const int JSON_first_final = 10; -static const int JSON_error = 0; +enum {JSON_start = 1}; +enum {JSON_first_final = 10}; +enum {JSON_error = 0}; -static const int JSON_en_main = 1; +enum {JSON_en_main = 1}; #line 740 "parser.rl" @@ -1904,11 +1904,11 @@ case 9: #line 1907 "parser.c" -static const int JSON_quirks_mode_start = 1; -static const int JSON_quirks_mode_first_final = 10; -static const int JSON_quirks_mode_error = 0; +enum {JSON_quirks_mode_start = 1}; +enum {JSON_quirks_mode_first_final = 10}; +enum {JSON_quirks_mode_error = 0}; -static const int JSON_quirks_mode_en_main = 1; +enum {JSON_quirks_mode_en_main = 1}; #line 778 "parser.rl" @@ -2092,7 +2092,7 @@ static VALUE cParser_parse(VALUE self) } -static JSON_Parser *JSON_allocate() +static JSON_Parser *JSON_allocate(void) { JSON_Parser *json = ALLOC(JSON_Parser); MEMZERO(json, JSON_Parser, 1); @@ -2100,8 +2100,9 @@ static JSON_Parser *JSON_allocate() return json; } -static void JSON_mark(JSON_Parser *json) +static void JSON_mark(void *ptr) { + JSON_Parser *json = ptr; rb_gc_mark_maybe(json->Vsource); rb_gc_mark_maybe(json->create_id); rb_gc_mark_maybe(json->object_class); @@ -2109,16 +2110,30 @@ static void JSON_mark(JSON_Parser *json) rb_gc_mark_maybe(json->match_string); } -static void JSON_free(JSON_Parser *json) +static void JSON_free(void *ptr) { + JSON_Parser *json = ptr; fbuffer_free(json->fbuffer); ruby_xfree(json); } +static size_t JSON_memsize(const void *ptr) +{ + const JSON_Parser *json = ptr; + return sizeof(*json) + FBUFFER_CAPA(json->fbuffer); +} + +static const rb_data_type_t JSON_Parser_type = { + "JSON/Parser", + {JSON_mark, JSON_free, JSON_memsize,}, + 0, 0, + RUBY_TYPED_FREE_IMMEDIATELY, +}; + static VALUE cJSON_parser_s_allocate(VALUE klass) { JSON_Parser *json = JSON_allocate(); - return Data_Wrap_Struct(klass, JSON_mark, JSON_free, json); + return TypedData_Wrap_Struct(klass, &JSON_Parser_type, json); } /* @@ -2145,7 +2160,7 @@ static VALUE cParser_quirks_mode_p(VALUE self) } -void Init_parser() +void Init_parser(void) { rb_require("json/common"); mJSON = rb_define_module("JSON"); diff --git a/ext/json/ext/parser/parser.h b/ext/json/ext/parser/parser.h index b192064c0..45afbc273 100644 --- a/ext/json/ext/parser/parser.h +++ b/ext/json/ext/parser/parser.h @@ -51,7 +51,7 @@ typedef struct JSON_ParserStruct { if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance") #define GET_PARSER_INIT \ JSON_Parser *json; \ - Data_Get_Struct(self, JSON_Parser, json) + TypedData_Get_Struct(self, JSON_Parser, &JSON_Parser_type, json) #define MinusInfinity "-Infinity" #define EVIL 0x666 @@ -68,10 +68,11 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu static VALUE convert_encoding(VALUE source); static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self); static VALUE cParser_parse(VALUE self); -static JSON_Parser *JSON_allocate(); -static void JSON_mark(JSON_Parser *json); -static void JSON_free(JSON_Parser *json); +static JSON_Parser *JSON_allocate(void); +static void JSON_mark(void *json); +static void JSON_free(void *json); static VALUE cJSON_parser_s_allocate(VALUE klass); static VALUE cParser_source(VALUE self); +static const rb_data_type_t JSON_Parser_type; #endif diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index c60e35cf8..34e30f486 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -610,7 +610,7 @@ static VALUE convert_encoding(VALUE source) * (keys) in a JSON object. Otherwise strings are returned, which is also * the default. * * *create_additions*: If set to false, the Parser doesn't create - * additions even if a matching class and create_id was found. This option + * additions even if a matchin class and create_id was found. This option * defaults to true. * * *object_class*: Defaults to Hash * * *array_class*: Defaults to Array @@ -815,7 +815,7 @@ static VALUE cParser_parse(VALUE self) } -static JSON_Parser *JSON_allocate() +static JSON_Parser *JSON_allocate(void) { JSON_Parser *json = ALLOC(JSON_Parser); MEMZERO(json, JSON_Parser, 1); @@ -823,8 +823,9 @@ static JSON_Parser *JSON_allocate() return json; } -static void JSON_mark(JSON_Parser *json) +static void JSON_mark(void *ptr) { + JSON_Parser *json = ptr; rb_gc_mark_maybe(json->Vsource); rb_gc_mark_maybe(json->create_id); rb_gc_mark_maybe(json->object_class); @@ -832,16 +833,30 @@ static void JSON_mark(JSON_Parser *json) rb_gc_mark_maybe(json->match_string); } -static void JSON_free(JSON_Parser *json) +static void JSON_free(void *ptr) { + JSON_Parser *json = ptr; fbuffer_free(json->fbuffer); ruby_xfree(json); } +static size_t JSON_memsize(const void *ptr) +{ + const JSON_Parser *json = ptr; + return sizeof(*json) + FBUFFER_CAPA(json->fbuffer); +} + +static const rb_data_type_t JSON_Parser_type = { + "JSON/Parser", + {JSON_mark, JSON_free, JSON_memsize,}, + 0, 0, + RUBY_TYPED_FREE_IMMEDIATELY, +}; + static VALUE cJSON_parser_s_allocate(VALUE klass) { JSON_Parser *json = JSON_allocate(); - return Data_Wrap_Struct(klass, JSON_mark, JSON_free, json); + return TypedData_Wrap_Struct(klass, &JSON_Parser_type, json); } /* diff --git a/ext/json/ext/parser/prereq.mk b/ext/json/ext/parser/prereq.mk new file mode 100644 index 000000000..be7bcb431 --- /dev/null +++ b/ext/json/ext/parser/prereq.mk @@ -0,0 +1,10 @@ +RAGEL = ragel + +.SUFFIXES: .rl + +.rl.c: + $(RAGEL) -G2 $< + $(BASERUBY) -pli -e '$$_.sub!(/[ \t]+$$/, "")' \ + -e '$$_.sub!(/^static const int (JSON_.*=.*);$$/, "enum {\\1};")' $@ + +parser.c: diff --git a/lib/json/add/complex.rb b/lib/json/add/complex.rb index 2723f6010..d7ebebf5f 100644 --- a/lib/json/add/complex.rb +++ b/lib/json/add/complex.rb @@ -4,15 +4,10 @@ defined?(::Complex) or require 'complex' class Complex - - # Deserializes JSON string by converting Real value r, imaginary - # value i, to a Complex object. def self.json_create(object) Complex(object['r'], object['i']) end - # Returns a hash, that will be turned into a JSON object and represent this - # object. def as_json(*) { JSON.create_id => self.class.name, @@ -21,8 +16,7 @@ def as_json(*) } end - # Stores class name (Complex) along with real value r and imaginary value i as JSON string def to_json(*) as_json.to_json end -end \ No newline at end of file +end diff --git a/lib/json/add/rational.rb b/lib/json/add/rational.rb index ee39c20e8..867cd92f0 100644 --- a/lib/json/add/rational.rb +++ b/lib/json/add/rational.rb @@ -4,14 +4,10 @@ defined?(::Rational) or require 'rational' class Rational - # Deserializes JSON string by converting numerator value n, - # denominator value d, to a Rational object. def self.json_create(object) Rational(object['n'], object['d']) end - # Returns a hash, that will be turned into a JSON object and represent this - # object. def as_json(*) { JSON.create_id => self.class.name, @@ -20,7 +16,6 @@ def as_json(*) } end - # Stores class name (Rational) along with numerator value n and denominator value d as JSON string def to_json(*) as_json.to_json end diff --git a/lib/json/add/time.rb b/lib/json/add/time.rb index d9834677a..338209d89 100644 --- a/lib/json/add/time.rb +++ b/lib/json/add/time.rb @@ -10,7 +10,7 @@ def self.json_create(object) if usec = object.delete('u') # used to be tv_usec -> tv_nsec object['n'] = usec * 1000 end - if method_defined?(:tv_nsec) + if instance_methods.include?(:tv_nsec) at(object['s'], Rational(object['n'], 1000)) else at(object['s'], object['n'] / 1000) diff --git a/lib/json/common.rb b/lib/json/common.rb index 32d989258..8fbaa2baa 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -148,7 +148,7 @@ class MissingUnicodeSupport < JSONError; end # the default. # * *create_additions*: If set to false, the Parser doesn't create # additions even if a matching class and create_id was found. This option - # defaults to false. + # defaults to true. # * *object_class*: Defaults to Hash # * *array_class*: Defaults to Array def parse(source, opts = {}) @@ -169,7 +169,7 @@ def parse(source, opts = {}) # to true. # * *create_additions*: If set to false, the Parser doesn't create # additions even if a matching class and create_id was found. This option - # defaults to false. + # defaults to true. def parse!(source, opts = {}) opts = { :max_nesting => false, @@ -390,7 +390,7 @@ def dump(obj, anIO = nil, limit = nil) end end opts = JSON.dump_default_options - opts = opts.merge(:max_nesting => limit) if limit + limit and opts.update(:max_nesting => limit) result = generate(obj, opts) if anIO anIO.write result @@ -411,7 +411,7 @@ def self.swap!(string) # :nodoc: string end - # Shortcut for iconv. + # Shortuct for iconv. if ::String.method_defined?(:encode) # Encodes string using Ruby's _String.encode_ def self.iconv(to, from, string) @@ -448,7 +448,7 @@ def j(*objs) nil end - # Ouputs _objs_ to STDOUT as JSON strings in a pretty format, with + # Outputs _objs_ to STDOUT as JSON strings in a pretty format, with # indentation and over many lines. def jj(*objs) objs.each do |obj| From 7f4cda91bb9f19f67628cf18cddf1174a3ed67d8 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Thu, 25 Dec 2014 15:45:54 -0500 Subject: [PATCH 044/312] This value has changed somehow --- tests/test_json.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_json.rb b/tests/test_json.rb index f4e6696c3..e9a125db4 100755 --- a/tests/test_json.rb +++ b/tests/test_json.rb @@ -517,7 +517,7 @@ def test_dump def test_dump_should_modify_defaults max_nesting = JSON.dump_default_options[:max_nesting] - JSON.dump([], StringIO.new, 10) + JSON.dump([], StringIO.new, 101) assert_equal max_nesting, JSON.dump_default_options[:max_nesting] end From 319a00d24d584d80946b2f6309e09b91b1d5906f Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Thu, 25 Dec 2014 15:48:54 -0500 Subject: [PATCH 045/312] Build on 2.2.0 too --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 5907de769..c0d1d3407 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ rvm: - 1.9.3 - 2.0.0 - 2.1 + - 2.2 - ree - rbx-18mode - rbx-19mode From 9122e59df6e97dcd03fccfa0e9b9f2be9127f081 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Thu, 25 Dec 2014 16:02:14 -0500 Subject: [PATCH 046/312] bundle exec rake generates new specs and makefile for compiling the CEXT --- ext/json/ext/parser/Makefile | 280 +++++++++++++++++++++++++++++++++++ json.gemspec | Bin 4942 -> 5007 bytes json_pure.gemspec | 6 +- 3 files changed, 283 insertions(+), 3 deletions(-) create mode 100644 ext/json/ext/parser/Makefile diff --git a/ext/json/ext/parser/Makefile b/ext/json/ext/parser/Makefile new file mode 100644 index 000000000..e2349c720 --- /dev/null +++ b/ext/json/ext/parser/Makefile @@ -0,0 +1,280 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@:) +ECHO = $(ECHO1:0=@echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /Users/zzak/.rubies/ruby-dev/include/ruby-2.2.0 +hdrdir = $(topdir) +arch_hdrdir = /Users/zzak/.rubies/ruby-dev/include/ruby-2.2.0/x86_64-darwin14 +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/Users/zzak/.rubies/ruby-dev +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC = clang +CXX = g++ +LIBRUBY = $(LIBRUBY_A) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = +LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static -framework CoreFoundation +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) + +RUBY_EXTCONF_H = +cflags = $(optflags) $(debugflags) $(warnflags) +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens +CCDLFLAGS = -fno-common +CFLAGS = $(CCDLFLAGS) $(cflags) -pipe $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(cxxflags) $(ARCH_FLAG) +ldflags = -L. -fstack-protector -L/usr/local/lib +dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -dynamic -bundle +LDSHAREDXX = $(CXX) -dynamic -bundle +AR = ar +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-darwin14 +sitearch = $(arch) +ruby_version = 2.2.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = $(RUBY) -run -e rm -- -rf +RMDIRS = rmdir -p +MAKEDIRS = mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = + +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /json/ext +LOCAL_LIBS = +LIBS = -lpthread -ldl -lobjc +ORIG_SRCS = parser.c +SRCS = $(ORIG_SRCS) +OBJS = parser.o +HDRS = $(srcdir)/parser.h +TARGET = parser +TARGET_NAME = parser +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).bundle +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(rubyhdrdir)/ruby$(target_prefix) +ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix) + +TARGET_SO = $(DLLIB) +CLEANLIBS = $(TARGET).bundle +CLEANOBJS = *.o *.bak + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TIMESTAMP_DIR)/.RUBYARCHDIR.-.json.-.ext.time + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb install-rb-default +install-rb-default: pre-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +pre-install-rb-default: + @$(NULLCMD) +$(TIMESTAMP_DIR)/.RUBYARCHDIR.-.json.-.ext.time: + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $< + +$(DLLIB): $(OBJS) Makefile + $(ECHO) linking shared-object json/ext/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +### +$(OBJS): $(ruby_headers) +parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h + +# AUTOGENERATED DEPENDENCIES START +parser.o: $(RUBY_EXTCONF_H) +parser.o: $(arch_hdrdir)/ruby/config.h +parser.o: $(hdrdir)/ruby/defines.h +parser.o: $(hdrdir)/ruby/encoding.h +parser.o: $(hdrdir)/ruby/intern.h +parser.o: $(hdrdir)/ruby/missing.h +parser.o: $(hdrdir)/ruby/oniguruma.h +parser.o: $(hdrdir)/ruby/ruby.h +parser.o: $(hdrdir)/ruby/st.h +parser.o: $(hdrdir)/ruby/subst.h +parser.o: $(top_srcdir)/ext/json/fbuffer/fbuffer.h +parser.o: $(top_srcdir)/include/ruby.h +parser.o: parser.c +parser.o: parser.h +parser.o: parser.rl +# AUTOGENERATED DEPENDENCIES END diff --git a/json.gemspec b/json.gemspec index 259b2362f7b07f897a0b9b404ea1c2873f4e1d8a..3b84ebd6a41a59923673b92ff003df17d23fc987 100644 GIT binary patch delta 63 zcmX@7)~~*yj*->SNY}`8b2H;XW)9!P?9{Z(oYcvROcIk_SbHa{GKp{&6r~oW7V70@ TZ$8WVo|D-`&vf&C{(fcvj?xsw delta 35 rcmeBIKc}{#j*->CT-U&Ob2H;X=E*6ny_<#DUUM=V=^1Sj=w}81(HIK? diff --git a/json_pure.gemspec b/json_pure.gemspec index 40f590271..a17a87608 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,15 +8,15 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2014-07-03" + s.date = "2014-12-25" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] - s.files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] + s.files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/Makefile", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/ext/parser/prereq.mk", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] - s.rubygems_version = "2.2.2" + s.rubygems_version = "2.4.5" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] From f4f0ab8e0794322edaf923cd5814472f45a9450c Mon Sep 17 00:00:00 2001 From: Jesse Cooke Date: Thu, 25 Dec 2014 13:22:10 -0800 Subject: [PATCH 047/312] CI with current rbx-2 --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5907de769..3dff5341e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,14 +9,12 @@ rvm: - 2.0.0 - 2.1 - ree - - rbx-18mode - - rbx-19mode + - rbx-2 - jruby-18mode - jruby-19mode - ruby-head matrix: allow_failures: - - rvm: rbx-18mode - - rvm: rbx-19mode + - rvm: rbx-2 - rvm: ruby-head script: "bundle exec rake" From c3d3f7fce748a6930938d8422acd719596ae57f1 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Thu, 25 Dec 2014 16:44:23 -0500 Subject: [PATCH 048/312] This file shouldn't be committed --- ext/json/ext/parser/Makefile | 280 ----------------------------------- json.gemspec | Bin 5007 -> 4975 bytes json_pure.gemspec | 2 +- 3 files changed, 1 insertion(+), 281 deletions(-) delete mode 100644 ext/json/ext/parser/Makefile diff --git a/ext/json/ext/parser/Makefile b/ext/json/ext/parser/Makefile deleted file mode 100644 index e2349c720..000000000 --- a/ext/json/ext/parser/Makefile +++ /dev/null @@ -1,280 +0,0 @@ - -SHELL = /bin/sh - -# V=0 quiet, V=1 verbose. other values don't work. -V = 0 -Q1 = $(V:1=) -Q = $(Q1:0=@) -ECHO1 = $(V:1=@:) -ECHO = $(ECHO1:0=@echo) -NULLCMD = : - -#### Start of system configuration section. #### - -srcdir = . -topdir = /Users/zzak/.rubies/ruby-dev/include/ruby-2.2.0 -hdrdir = $(topdir) -arch_hdrdir = /Users/zzak/.rubies/ruby-dev/include/ruby-2.2.0/x86_64-darwin14 -PATH_SEPARATOR = : -VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby -prefix = $(DESTDIR)/Users/zzak/.rubies/ruby-dev -rubysitearchprefix = $(rubylibprefix)/$(sitearch) -rubyarchprefix = $(rubylibprefix)/$(arch) -rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) -exec_prefix = $(prefix) -vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) -sitearchhdrdir = $(sitehdrdir)/$(sitearch) -rubyarchhdrdir = $(rubyhdrdir)/$(arch) -vendorhdrdir = $(rubyhdrdir)/vendor_ruby -sitehdrdir = $(rubyhdrdir)/site_ruby -rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) -vendorarchdir = $(vendorlibdir)/$(sitearch) -vendorlibdir = $(vendordir)/$(ruby_version) -vendordir = $(rubylibprefix)/vendor_ruby -sitearchdir = $(sitelibdir)/$(sitearch) -sitelibdir = $(sitedir)/$(ruby_version) -sitedir = $(rubylibprefix)/site_ruby -rubyarchdir = $(rubylibdir)/$(arch) -rubylibdir = $(rubylibprefix)/$(ruby_version) -sitearchincludedir = $(includedir)/$(sitearch) -archincludedir = $(includedir)/$(arch) -sitearchlibdir = $(libdir)/$(sitearch) -archlibdir = $(libdir)/$(arch) -ridir = $(datarootdir)/$(RI_BASE_NAME) -mandir = $(datarootdir)/man -localedir = $(datarootdir)/locale -libdir = $(exec_prefix)/lib -psdir = $(docdir) -pdfdir = $(docdir) -dvidir = $(docdir) -htmldir = $(docdir) -infodir = $(datarootdir)/info -docdir = $(datarootdir)/doc/$(PACKAGE) -oldincludedir = $(DESTDIR)/usr/include -includedir = $(prefix)/include -localstatedir = $(prefix)/var -sharedstatedir = $(prefix)/com -sysconfdir = $(prefix)/etc -datadir = $(datarootdir) -datarootdir = $(prefix)/share -libexecdir = $(exec_prefix)/libexec -sbindir = $(exec_prefix)/sbin -bindir = $(exec_prefix)/bin -archdir = $(rubyarchdir) - - -CC = clang -CXX = g++ -LIBRUBY = $(LIBRUBY_A) -LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a -LIBRUBYARG_SHARED = -LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static -framework CoreFoundation -empty = -OUTFLAG = -o $(empty) -COUTFLAG = -o $(empty) - -RUBY_EXTCONF_H = -cflags = $(optflags) $(debugflags) $(warnflags) -optflags = -O3 -fno-fast-math -debugflags = -ggdb3 -warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens -CCDLFLAGS = -fno-common -CFLAGS = $(CCDLFLAGS) $(cflags) -pipe $(ARCH_FLAG) -INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) -DEFS = -CPPFLAGS = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags) -CXXFLAGS = $(CCDLFLAGS) $(cxxflags) $(ARCH_FLAG) -ldflags = -L. -fstack-protector -L/usr/local/lib -dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -ARCH_FLAG = -DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) -LDSHARED = $(CC) -dynamic -bundle -LDSHAREDXX = $(CXX) -dynamic -bundle -AR = ar -EXEEXT = - -RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) -RUBY_SO_NAME = ruby -RUBYW_INSTALL_NAME = -RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) -RUBYW_BASE_NAME = rubyw -RUBY_BASE_NAME = ruby - -arch = x86_64-darwin14 -sitearch = $(arch) -ruby_version = 2.2.0 -ruby = $(bindir)/$(RUBY_BASE_NAME) -RUBY = $(ruby) -ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h - -RM = rm -f -RM_RF = $(RUBY) -run -e rm -- -rf -RMDIRS = rmdir -p -MAKEDIRS = mkdir -p -INSTALL = /usr/bin/install -c -INSTALL_PROG = $(INSTALL) -m 0755 -INSTALL_DATA = $(INSTALL) -m 644 -COPY = cp -TOUCH = exit > - -#### End of system configuration section. #### - -preload = - -libpath = . $(libdir) -LIBPATH = -L. -L$(libdir) -DEFFILE = - -CLEANFILES = mkmf.log -DISTCLEANFILES = -DISTCLEANDIRS = - -extout = -extout_prefix = -target_prefix = /json/ext -LOCAL_LIBS = -LIBS = -lpthread -ldl -lobjc -ORIG_SRCS = parser.c -SRCS = $(ORIG_SRCS) -OBJS = parser.o -HDRS = $(srcdir)/parser.h -TARGET = parser -TARGET_NAME = parser -TARGET_ENTRY = Init_$(TARGET_NAME) -DLLIB = $(TARGET).bundle -EXTSTATIC = -STATIC_LIB = - -TIMESTAMP_DIR = . -BINDIR = $(bindir) -RUBYCOMMONDIR = $(sitedir)$(target_prefix) -RUBYLIBDIR = $(sitelibdir)$(target_prefix) -RUBYARCHDIR = $(sitearchdir)$(target_prefix) -HDRDIR = $(rubyhdrdir)/ruby$(target_prefix) -ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix) - -TARGET_SO = $(DLLIB) -CLEANLIBS = $(TARGET).bundle -CLEANOBJS = *.o *.bak - -all: $(DLLIB) -static: $(STATIC_LIB) -.PHONY: all install static install-so install-rb -.PHONY: clean clean-so clean-static clean-rb - -clean-static:: -clean-rb-default:: -clean-rb:: -clean-so:: -clean: clean-so clean-static clean-rb-default clean-rb - -$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time - -distclean-rb-default:: -distclean-rb:: -distclean-so:: -distclean-static:: -distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb - -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log - -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) - -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true - -realclean: distclean -install: install-so install-rb - -install-so: $(DLLIB) $(TIMESTAMP_DIR)/.RUBYARCHDIR.-.json.-.ext.time - $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) -clean-static:: - -$(Q)$(RM) $(STATIC_LIB) -install-rb: pre-install-rb install-rb-default -install-rb-default: pre-install-rb-default -pre-install-rb: Makefile -pre-install-rb-default: Makefile -pre-install-rb-default: - @$(NULLCMD) -$(TIMESTAMP_DIR)/.RUBYARCHDIR.-.json.-.ext.time: - $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) - $(Q) $(TOUCH) $@ - -site-install: site-install-so site-install-rb -site-install-so: install-so -site-install-rb: install-rb - -.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S - -.cc.o: - $(ECHO) compiling $(<) - $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< - -.cc.S: - $(ECHO) translating $(<) - $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $< - -.mm.o: - $(ECHO) compiling $(<) - $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< - -.mm.S: - $(ECHO) translating $(<) - $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $< - -.cxx.o: - $(ECHO) compiling $(<) - $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< - -.cxx.S: - $(ECHO) translating $(<) - $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $< - -.cpp.o: - $(ECHO) compiling $(<) - $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< - -.cpp.S: - $(ECHO) translating $(<) - $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $< - -.c.o: - $(ECHO) compiling $(<) - $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $< - -.c.S: - $(ECHO) translating $(<) - $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $< - -.m.o: - $(ECHO) compiling $(<) - $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $< - -.m.S: - $(ECHO) translating $(<) - $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $< - -$(DLLIB): $(OBJS) Makefile - $(ECHO) linking shared-object json/ext/$(DLLIB) - -$(Q)$(RM) $(@) - $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) - $(Q) $(POSTLINK) - - - -### -$(OBJS): $(ruby_headers) -parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h - -# AUTOGENERATED DEPENDENCIES START -parser.o: $(RUBY_EXTCONF_H) -parser.o: $(arch_hdrdir)/ruby/config.h -parser.o: $(hdrdir)/ruby/defines.h -parser.o: $(hdrdir)/ruby/encoding.h -parser.o: $(hdrdir)/ruby/intern.h -parser.o: $(hdrdir)/ruby/missing.h -parser.o: $(hdrdir)/ruby/oniguruma.h -parser.o: $(hdrdir)/ruby/ruby.h -parser.o: $(hdrdir)/ruby/st.h -parser.o: $(hdrdir)/ruby/subst.h -parser.o: $(top_srcdir)/ext/json/fbuffer/fbuffer.h -parser.o: $(top_srcdir)/include/ruby.h -parser.o: parser.c -parser.o: parser.h -parser.o: parser.rl -# AUTOGENERATED DEPENDENCIES END diff --git a/json.gemspec b/json.gemspec index 3b84ebd6a41a59923673b92ff003df17d23fc987..86a327a8b68c0651d3f68f32ec12f7281fac6c58 100644 GIT binary patch delta 12 TcmeBIf3LQ|g>`cZt2Q41AQc1} delta 25 gcmaE_)~~+7g_XlMF*`LaGbeSjB9p{s7glXP0Ciml?f?J) diff --git a/json_pure.gemspec b/json_pure.gemspec index a17a87608..1fb02e78b 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] - s.files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/Makefile", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/ext/parser/prereq.mk", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] + s.files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/ext/parser/prereq.mk", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] From 9bb068957df56987c4d86f090fc08d3d062d1cdc Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Thu, 25 Dec 2014 17:15:44 -0500 Subject: [PATCH 049/312] Sync tests with trunk --- tests/test_json.rb | 8 ++------ tests/test_json_generate.rb | 18 +++++++++--------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/tests/test_json.rb b/tests/test_json.rb index e9a125db4..462650e86 100755 --- a/tests/test_json.rb +++ b/tests/test_json.rb @@ -491,6 +491,8 @@ def test_load assert_equal @hash, JSON.load(stringio) assert_equal nil, JSON.load(nil) assert_equal nil, JSON.load('') + ensure + tempfile.close! end def test_load_with_options @@ -515,12 +517,6 @@ def test_dump assert_equal too_deep, output.string end - def test_dump_should_modify_defaults - max_nesting = JSON.dump_default_options[:max_nesting] - JSON.dump([], StringIO.new, 101) - assert_equal max_nesting, JSON.dump_default_options[:max_nesting] - end - def test_big_integers json1 = JSON([orig = (1 << 31) - 1]) assert_equal orig, JSON[json1][0] diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index 117a1553f..2d4e1eea5 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -215,16 +215,16 @@ def test_buffer_initial_length end def test_gc - bignum_too_long_to_embed_as_string = 1234567890123456789012345 - expect = bignum_too_long_to_embed_as_string.to_s - stress, GC.stress = GC.stress, true + assert_in_out_err(%w[-rjson --disable-gems], <<-EOS, [], []) + bignum_too_long_to_embed_as_string = 1234567890123456789012345 + expect = bignum_too_long_to_embed_as_string.to_s + GC.stress = true - 10.times do |i| - tmp = bignum_too_long_to_embed_as_string.to_json - assert_equal expect, tmp - end - ensure - GC.stress = stress + 10.times do |i| + tmp = bignum_too_long_to_embed_as_string.to_json + raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect + end + EOS end if GC.respond_to?(:stress=) def test_configure_using_configure_and_merge From f7b5dd35defcd8ad4ef6c2d0461c332ddd728025 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Thu, 25 Dec 2014 23:25:29 -0500 Subject: [PATCH 050/312] Only use gc stress assert if available --- tests/test_json_generate.rb | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index 2d4e1eea5..ea6a9a3ee 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -215,16 +215,18 @@ def test_buffer_initial_length end def test_gc - assert_in_out_err(%w[-rjson --disable-gems], <<-EOS, [], []) - bignum_too_long_to_embed_as_string = 1234567890123456789012345 - expect = bignum_too_long_to_embed_as_string.to_s - GC.stress = true + if respond_to?(:assert_in_out_err) + assert_in_out_err(%w[-rjson --disable-gems], <<-EOS, [], []) + bignum_too_long_to_embed_as_string = 1234567890123456789012345 + expect = bignum_too_long_to_embed_as_string.to_s + GC.stress = true - 10.times do |i| - tmp = bignum_too_long_to_embed_as_string.to_json - raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect - end - EOS + 10.times do |i| + tmp = bignum_too_long_to_embed_as_string.to_json + raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect + end + EOS + end end if GC.respond_to?(:stress=) def test_configure_using_configure_and_merge From 089c03c345fd8094258638510add3fc53d6168e3 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Thu, 25 Dec 2014 23:30:00 -0500 Subject: [PATCH 051/312] Add extconf from trunk --- ext/json/extconf.rb | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ext/json/extconf.rb diff --git a/ext/json/extconf.rb b/ext/json/extconf.rb new file mode 100644 index 000000000..850798c64 --- /dev/null +++ b/ext/json/extconf.rb @@ -0,0 +1,3 @@ +require 'mkmf' +create_makefile('json') + From 6e0ed2447f24f87a21ffa3fb1db276c0a1c3a3f1 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Fri, 26 Dec 2014 10:38:34 -0500 Subject: [PATCH 052/312] Ignore .bundle generated files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 297633e64..9cd6017bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .*.sw[pon] +*.bundle coverage tags pkg From a86e95465e6466d589600b3aecac005fbf7a5370 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Fri, 26 Dec 2014 12:20:06 -0500 Subject: [PATCH 053/312] Revert part of "Sync with trunk" This partially reverts commit 18b3000. --- ext/json/ext/generator/depend | 20 -------------------- ext/json/ext/parser/depend | 19 ------------------- ext/json/ext/parser/prereq.mk | 10 ---------- 3 files changed, 49 deletions(-) delete mode 100644 ext/json/ext/parser/prereq.mk diff --git a/ext/json/ext/generator/depend b/ext/json/ext/generator/depend index b7373cde1..1a042a250 100644 --- a/ext/json/ext/generator/depend +++ b/ext/json/ext/generator/depend @@ -1,21 +1 @@ -$(OBJS): $(ruby_headers) generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h - -# AUTOGENERATED DEPENDENCIES START -generator.o: $(RUBY_EXTCONF_H) -generator.o: $(arch_hdrdir)/ruby/config.h -generator.o: $(hdrdir)/ruby/defines.h -generator.o: $(hdrdir)/ruby/encoding.h -generator.o: $(hdrdir)/ruby/intern.h -generator.o: $(hdrdir)/ruby/missing.h -generator.o: $(hdrdir)/ruby/oniguruma.h -generator.o: $(hdrdir)/ruby/re.h -generator.o: $(hdrdir)/ruby/regex.h -generator.o: $(hdrdir)/ruby/ruby.h -generator.o: $(hdrdir)/ruby/st.h -generator.o: $(hdrdir)/ruby/subst.h -generator.o: $(top_srcdir)/ext/json/fbuffer/fbuffer.h -generator.o: $(top_srcdir)/include/ruby.h -generator.o: generator.c -generator.o: generator.h -# AUTOGENERATED DEPENDENCIES END diff --git a/ext/json/ext/parser/depend b/ext/json/ext/parser/depend index bc5db0640..498ffa964 100644 --- a/ext/json/ext/parser/depend +++ b/ext/json/ext/parser/depend @@ -1,20 +1 @@ -$(OBJS): $(ruby_headers) parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h - -# AUTOGENERATED DEPENDENCIES START -parser.o: $(RUBY_EXTCONF_H) -parser.o: $(arch_hdrdir)/ruby/config.h -parser.o: $(hdrdir)/ruby/defines.h -parser.o: $(hdrdir)/ruby/encoding.h -parser.o: $(hdrdir)/ruby/intern.h -parser.o: $(hdrdir)/ruby/missing.h -parser.o: $(hdrdir)/ruby/oniguruma.h -parser.o: $(hdrdir)/ruby/ruby.h -parser.o: $(hdrdir)/ruby/st.h -parser.o: $(hdrdir)/ruby/subst.h -parser.o: $(top_srcdir)/ext/json/fbuffer/fbuffer.h -parser.o: $(top_srcdir)/include/ruby.h -parser.o: parser.c -parser.o: parser.h -parser.o: parser.rl -# AUTOGENERATED DEPENDENCIES END diff --git a/ext/json/ext/parser/prereq.mk b/ext/json/ext/parser/prereq.mk deleted file mode 100644 index be7bcb431..000000000 --- a/ext/json/ext/parser/prereq.mk +++ /dev/null @@ -1,10 +0,0 @@ -RAGEL = ragel - -.SUFFIXES: .rl - -.rl.c: - $(RAGEL) -G2 $< - $(BASERUBY) -pli -e '$$_.sub!(/[ \t]+$$/, "")' \ - -e '$$_.sub!(/^static const int (JSON_.*=.*);$$/, "enum {\\1};")' $@ - -parser.c: From 55748d36d927443fdb5fbd2497cadf367753df38 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Fri, 26 Dec 2014 23:57:34 -0800 Subject: [PATCH 054/312] Use ALLOC and MEMZERO instead of ZALLOC --- ext/json/ext/generator/generator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index f56ac09cd..9f510f5c2 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -524,7 +524,8 @@ static const rb_data_type_t JSON_Generator_State_type = { static JSON_Generator_State *State_allocate(void) { - JSON_Generator_State *state = ZALLOC(JSON_Generator_State); + JSON_Generator_State *state = ALLOC(JSON_Generator_State); + MEMZERO(state, JSON_Generator_State, 1); return state; } From e447a80d873efef022a7aec0d74c6b531fe1ec8e Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Sat, 27 Dec 2014 00:14:43 -0800 Subject: [PATCH 055/312] RUBY_TYPED_FREE_IMMEDIATELY isn't always available --- ext/json/ext/generator/generator.c | 2 + ext/json/ext/parser/parser.c | 68 +++++++++++++++--------------- ext/json/ext/parser/parser.rl | 2 + 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 9f510f5c2..9a0b38317 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -518,8 +518,10 @@ static size_t State_memsize(const void *ptr) static const rb_data_type_t JSON_Generator_State_type = { "JSON/Generator/State", {NULL, State_free, State_memsize,}, +#ifdef RUBY_TYPED_FREE_IMMEDIATELY 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +#endif }; static JSON_Generator_State *State_allocate(void) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 560aa8977..509d1fc2d 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -89,11 +89,11 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, #line 92 "parser.c" -enum {JSON_object_start = 1}; -enum {JSON_object_first_final = 27}; -enum {JSON_object_error = 0}; +static const int JSON_object_start = 1; +static const int JSON_object_first_final = 27; +static const int JSON_object_error = 0; -enum {JSON_object_en_main = 1}; +static const int JSON_object_en_main = 1; #line 151 "parser.rl" @@ -467,11 +467,11 @@ case 26: #line 470 "parser.c" -enum {JSON_value_start = 1}; -enum {JSON_value_first_final = 21}; -enum {JSON_value_error = 0}; +static const int JSON_value_start = 1; +static const int JSON_value_first_final = 21; +static const int JSON_value_error = 0; -enum {JSON_value_en_main = 1}; +static const int JSON_value_en_main = 1; #line 271 "parser.rl" @@ -776,11 +776,11 @@ case 20: #line 779 "parser.c" -enum {JSON_integer_start = 1}; -enum {JSON_integer_first_final = 3}; -enum {JSON_integer_error = 0}; +static const int JSON_integer_start = 1; +static const int JSON_integer_first_final = 3; +static const int JSON_integer_error = 0; -enum {JSON_integer_en_main = 1}; +static const int JSON_integer_en_main = 1; #line 295 "parser.rl" @@ -875,11 +875,11 @@ case 5: #line 878 "parser.c" -enum {JSON_float_start = 1}; -enum {JSON_float_first_final = 8}; -enum {JSON_float_error = 0}; +static const int JSON_float_start = 1; +static const int JSON_float_first_final = 8; +static const int JSON_float_error = 0; -enum {JSON_float_en_main = 1}; +static const int JSON_float_en_main = 1; #line 329 "parser.rl" @@ -1041,11 +1041,11 @@ case 7: #line 1044 "parser.c" -enum {JSON_array_start = 1}; -enum {JSON_array_first_final = 17}; -enum {JSON_array_error = 0}; +static const int JSON_array_start = 1; +static const int JSON_array_first_final = 17; +static const int JSON_array_error = 0; -enum {JSON_array_en_main = 1}; +static const int JSON_array_en_main = 1; #line 381 "parser.rl" @@ -1373,11 +1373,11 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) #line 1376 "parser.c" -enum {JSON_string_start = 1}; -enum {JSON_string_first_final = 8}; -enum {JSON_string_error = 0}; +static const int JSON_string_start = 1; +static const int JSON_string_first_final = 8; +static const int JSON_string_error = 0; -enum {JSON_string_en_main = 1}; +static const int JSON_string_en_main = 1; #line 494 "parser.rl" @@ -1730,11 +1730,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) #line 1733 "parser.c" -enum {JSON_start = 1}; -enum {JSON_first_final = 10}; -enum {JSON_error = 0}; +static const int JSON_start = 1; +static const int JSON_first_final = 10; +static const int JSON_error = 0; -enum {JSON_en_main = 1}; +static const int JSON_en_main = 1; #line 740 "parser.rl" @@ -1904,11 +1904,11 @@ case 9: #line 1907 "parser.c" -enum {JSON_quirks_mode_start = 1}; -enum {JSON_quirks_mode_first_final = 10}; -enum {JSON_quirks_mode_error = 0}; +static const int JSON_quirks_mode_start = 1; +static const int JSON_quirks_mode_first_final = 10; +static const int JSON_quirks_mode_error = 0; -enum {JSON_quirks_mode_en_main = 1}; +static const int JSON_quirks_mode_en_main = 1; #line 778 "parser.rl" @@ -2126,8 +2126,10 @@ static size_t JSON_memsize(const void *ptr) static const rb_data_type_t JSON_Parser_type = { "JSON/Parser", {JSON_mark, JSON_free, JSON_memsize,}, +#ifdef RUBY_TYPED_FREE_IMMEDIATELY 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +#endif }; static VALUE cJSON_parser_s_allocate(VALUE klass) @@ -2160,7 +2162,7 @@ static VALUE cParser_quirks_mode_p(VALUE self) } -void Init_parser(void) +void Init_parser() { rb_require("json/common"); mJSON = rb_define_module("JSON"); diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index 34e30f486..391d6fbe9 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -849,8 +849,10 @@ static size_t JSON_memsize(const void *ptr) static const rb_data_type_t JSON_Parser_type = { "JSON/Parser", {JSON_mark, JSON_free, JSON_memsize,}, +#ifdef RUBY_TYPED_FREE_IMMEDIATELY 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +#endif }; static VALUE cJSON_parser_s_allocate(VALUE klass) From b798187c278beea246b0f709754ebd34eaae074e Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Sat, 27 Dec 2014 10:22:15 -0800 Subject: [PATCH 056/312] Ignore generated files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9cd6017bc..5ef62afbd 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ Gemfile.lock .rbx .AppleDouble .DS_Store +*/**/Makefile +*/**/*.o From 4dd360f7454b3da3288b94500fb95cd51fe9aec8 Mon Sep 17 00:00:00 2001 From: SHIBATA Hiroshi Date: Sun, 28 Dec 2014 12:32:18 +0900 Subject: [PATCH 057/312] fix to build fail with rb_str_new macro usage --- ext/json/ext/fbuffer/fbuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/json/ext/fbuffer/fbuffer.h b/ext/json/ext/fbuffer/fbuffer.h index af7418756..9524fb1e0 100644 --- a/ext/json/ext/fbuffer/fbuffer.h +++ b/ext/json/ext/fbuffer/fbuffer.h @@ -172,7 +172,7 @@ static FBuffer *fbuffer_dup(FBuffer *fb) static VALUE fbuffer_to_s(FBuffer *fb) { - VALUE result = rb_str_new(FBUFFER_PAIR(fb)); + VALUE result = rb_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb)); fbuffer_free(fb); FORCE_UTF8(result); return result; From 0a7c982b38b65b7b23c0bccbc056ec9213132e4e Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 2 Jan 2015 22:45:22 +0100 Subject: [PATCH 058/312] Fix typo --- java/src/json/ext/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index 6cb5886a7..1664240af 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -130,7 +130,7 @@ public Parser(Ruby runtime, RubyClass metaClass) { * *
:create_additions *
If set to false, the Parser doesn't create additions - * even if a matchin class and create_id was found. This option + * even if a matching class and create_id was found. This option * defaults to true. * *
:object_class From 05ba45c2d46c8ff4807613b60b204f85a7720997 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 2 Jan 2015 23:22:09 +0100 Subject: [PATCH 059/312] Fall back to Data_* wrappers on ancient rubies --- ext/json/ext/generator/generator.c | 2 ++ ext/json/ext/generator/generator.h | 6 ++++++ ext/json/ext/parser/parser.c | 2 ++ ext/json/ext/parser/parser.h | 6 ++++++ ext/json/ext/parser/parser.rl | 4 +++- 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index f789a8998..a474fbbc8 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -515,6 +515,7 @@ static size_t State_memsize(const void *ptr) return size; } +#ifdef NEW_TYPEDDATA_WRAPPER static const rb_data_type_t JSON_Generator_State_type = { "JSON/Generator/State", {NULL, State_free, State_memsize,}, @@ -523,6 +524,7 @@ static const rb_data_type_t JSON_Generator_State_type = { RUBY_TYPED_FREE_IMMEDIATELY, #endif }; +#endif static JSON_Generator_State *State_allocate(void) { diff --git a/ext/json/ext/generator/generator.h b/ext/json/ext/generator/generator.h index 7bf840816..02193f094 100644 --- a/ext/json/ext/generator/generator.h +++ b/ext/json/ext/generator/generator.h @@ -147,6 +147,12 @@ static VALUE cState_ascii_only_p(VALUE self); static VALUE cState_depth(VALUE self); static VALUE cState_depth_set(VALUE self, VALUE depth); static FBuffer *cState_prepare_buffer(VALUE self); +#ifdef TypedData_Wrap_Struct static const rb_data_type_t JSON_Generator_State_type; +#define NEW_TYPEDDATA_WRAPPER 1 +#else +#define TypedData_Wrap_Struct(klass, ignore, json) Data_Wrap_Struct(klass, NULL, State_free, json) +#define TypedData_Get_Struct(self, JSON_Generator_State, ignore, json) Data_Get_Struct(self, JSON_Generator_State, json) +#endif #endif diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index efb4dacef..8824b3035 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -2123,6 +2123,7 @@ static size_t JSON_memsize(const void *ptr) return sizeof(*json) + FBUFFER_CAPA(json->fbuffer); } +#ifdef NEW_TYPEDDATA_WRAPPER static const rb_data_type_t JSON_Parser_type = { "JSON/Parser", {JSON_mark, JSON_free, JSON_memsize,}, @@ -2131,6 +2132,7 @@ static const rb_data_type_t JSON_Parser_type = { RUBY_TYPED_FREE_IMMEDIATELY, #endif }; +#endif static VALUE cJSON_parser_s_allocate(VALUE klass) { diff --git a/ext/json/ext/parser/parser.h b/ext/json/ext/parser/parser.h index 45afbc273..418637f82 100644 --- a/ext/json/ext/parser/parser.h +++ b/ext/json/ext/parser/parser.h @@ -73,6 +73,12 @@ static void JSON_mark(void *json); static void JSON_free(void *json); static VALUE cJSON_parser_s_allocate(VALUE klass); static VALUE cParser_source(VALUE self); +#ifdef TypedData_Wrap_Struct static const rb_data_type_t JSON_Parser_type; +#define NEW_TYPEDDATA_WRAPPER 1 +#else +#define TypedData_Wrap_Struct(klass, ignore, json) Data_Wrap_Struct(klass, JSON_mark, JSON_free, json) +#define TypedData_Get_Struct(self, JSON_Parser, ignore, json) Data_Get_Struct(self, JSON_Parser, json) +#endif #endif diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index d3ba554d8..2af1cc678 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -611,7 +611,7 @@ static VALUE convert_encoding(VALUE source) * the default. * * *create_additions*: If set to false, the Parser doesn't create * additions even if a matching class and create_id was found. This option - * defaults to true. + * defaults to false. * * *object_class*: Defaults to Hash * * *array_class*: Defaults to Array */ @@ -846,6 +846,7 @@ static size_t JSON_memsize(const void *ptr) return sizeof(*json) + FBUFFER_CAPA(json->fbuffer); } +#ifdef NEW_TYPEDDATA_WRAPPER static const rb_data_type_t JSON_Parser_type = { "JSON/Parser", {JSON_mark, JSON_free, JSON_memsize,}, @@ -854,6 +855,7 @@ static const rb_data_type_t JSON_Parser_type = { RUBY_TYPED_FREE_IMMEDIATELY, #endif }; +#endif static VALUE cJSON_parser_s_allocate(VALUE klass) { From 3c6e9c32d4a1496dfa2b8f4266148cdecbe14731 Mon Sep 17 00:00:00 2001 From: Ignacio Galindo Date: Thu, 31 Oct 2013 18:06:09 -0600 Subject: [PATCH 060/312] Fix typo in comment --- lib/json/common.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/common.rb b/lib/json/common.rb index e24f637f6..c01590b7b 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -411,7 +411,7 @@ def self.swap!(string) # :nodoc: string end - # Shortuct for iconv. + # Shortcut for iconv. if ::String.method_defined?(:encode) # Encodes string using Ruby's _String.encode_ def self.iconv(to, from, string) From 7aa0f55cf61479eb578d22d5174f65f1910d1a06 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 1 Apr 2014 12:17:15 +0200 Subject: [PATCH 061/312] Change documentation to reflect new default value --- lib/json/common.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/json/common.rb b/lib/json/common.rb index c01590b7b..426d933b4 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -148,7 +148,7 @@ class MissingUnicodeSupport < JSONError; end # the default. # * *create_additions*: If set to false, the Parser doesn't create # additions even if a matching class and create_id was found. This option - # defaults to true. + # defaults to false. # * *object_class*: Defaults to Hash # * *array_class*: Defaults to Array def parse(source, opts = {}) @@ -169,7 +169,7 @@ def parse(source, opts = {}) # to true. # * *create_additions*: If set to false, the Parser doesn't create # additions even if a matching class and create_id was found. This option - # defaults to true. + # defaults to false. def parse!(source, opts = {}) opts = { :max_nesting => false, From 14b31e5b1c2631de360b8ae0a218c3fcd1adc5f1 Mon Sep 17 00:00:00 2001 From: Daniel Grippi Date: Wed, 2 Apr 2014 11:11:25 -0400 Subject: [PATCH 062/312] Update json-java.gemspec Pluralize "license" to match other gemspecs. --- json-java.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json-java.gemspec b/json-java.gemspec index 79d8e3ad0..14864f8c4 100644 --- a/json-java.gemspec +++ b/json-java.gemspec @@ -11,7 +11,7 @@ spec = Gem::Specification.new do |s| s.homepage = "http://json-jruby.rubyforge.org/" s.platform = 'java' s.rubyforge_project = "json-jruby" - s.license = "Ruby" + s.licenses = ["Ruby"] s.files = Dir["{docs,lib,tests}/**/*"] end From df7e878fc98c75edef04891559cec9caf8a0a484 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Thu, 3 Jul 2014 10:41:16 +0530 Subject: [PATCH 063/312] Use method_defined? to check if method exists instead of slower check on instance_methods --- lib/json/add/time.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/add/time.rb b/lib/json/add/time.rb index 338209d89..d9834677a 100644 --- a/lib/json/add/time.rb +++ b/lib/json/add/time.rb @@ -10,7 +10,7 @@ def self.json_create(object) if usec = object.delete('u') # used to be tv_usec -> tv_nsec object['n'] = usec * 1000 end - if instance_methods.include?(:tv_nsec) + if method_defined?(:tv_nsec) at(object['s'], Rational(object['n'], 1000)) else at(object['s'], object['n'] / 1000) From 435c25866d7a90d2eea53ca599f27482ea7ec2c4 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Thu, 3 Jul 2014 10:49:29 +0530 Subject: [PATCH 064/312] Document `Complex` json generation methods. --- lib/json/add/complex.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/json/add/complex.rb b/lib/json/add/complex.rb index d7ebebf5f..2723f6010 100644 --- a/lib/json/add/complex.rb +++ b/lib/json/add/complex.rb @@ -4,10 +4,15 @@ defined?(::Complex) or require 'complex' class Complex + + # Deserializes JSON string by converting Real value r, imaginary + # value i, to a Complex object. def self.json_create(object) Complex(object['r'], object['i']) end + # Returns a hash, that will be turned into a JSON object and represent this + # object. def as_json(*) { JSON.create_id => self.class.name, @@ -16,7 +21,8 @@ def as_json(*) } end + # Stores class name (Complex) along with real value r and imaginary value i as JSON string def to_json(*) as_json.to_json end -end +end \ No newline at end of file From 1f339fe8d3fd015886d09c06806ddcd128ecf810 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Thu, 3 Jul 2014 10:46:53 +0530 Subject: [PATCH 065/312] Document `Rational` json generation methods. --- lib/json/add/rational.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/json/add/rational.rb b/lib/json/add/rational.rb index 867cd92f0..c100d1386 100644 --- a/lib/json/add/rational.rb +++ b/lib/json/add/rational.rb @@ -4,19 +4,25 @@ defined?(::Rational) or require 'rational' class Rational + + # Deserializes JSON string by converting numerator value n, denominator + # value d, to a Rational object. def self.json_create(object) Rational(object['n'], object['d']) end + # Returns a hash, that will be turned into a JSON object and represent this + # object. def as_json(*) { - JSON.create_id => self.class.name, - 'n' => numerator, - 'd' => denominator, + JSON.create_id => self.class.name, + 'n' => numerator, + 'd' => denominator, } end + # Stores class name (Rational) along with numerator value n and denominator value d as JSON string def to_json(*) as_json.to_json end -end +end \ No newline at end of file From 3869d77136f039bba2e11e35949cafc5dc662db3 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 3 Jul 2014 10:47:44 +0200 Subject: [PATCH 066/312] Reindented --- lib/json/add/rational.rb | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/json/add/rational.rb b/lib/json/add/rational.rb index c100d1386..ee39c20e8 100644 --- a/lib/json/add/rational.rb +++ b/lib/json/add/rational.rb @@ -4,9 +4,8 @@ defined?(::Rational) or require 'rational' class Rational - - # Deserializes JSON string by converting numerator value n, denominator - # value d, to a Rational object. + # Deserializes JSON string by converting numerator value n, + # denominator value d, to a Rational object. def self.json_create(object) Rational(object['n'], object['d']) end @@ -15,9 +14,9 @@ def self.json_create(object) # object. def as_json(*) { - JSON.create_id => self.class.name, - 'n' => numerator, - 'd' => denominator, + JSON.create_id => self.class.name, + 'n' => numerator, + 'd' => denominator, } end @@ -25,4 +24,4 @@ def as_json(*) def to_json(*) as_json.to_json end -end \ No newline at end of file +end From a97cbd03c5e1d4d486a8dfb28b005ff4eabeaca0 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 3 Jul 2014 10:57:42 +0200 Subject: [PATCH 067/312] No binstubs --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 93916a0fd..d4f8f7abc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ # Passes arguments to bundle install (http://gembundler.com/man/bundle-install.1.html) -bundler_args: --binstubs +#bundler_args: --binstubs # Specify which ruby versions you wish to run your tests on, each version will be used rvm: From 0f6a75a554a7524a7a009f992ac50f9fad395bec Mon Sep 17 00:00:00 2001 From: "Jason R. Clark" Date: Fri, 19 Sep 2014 15:43:45 -0700 Subject: [PATCH 068/312] Don't mutate JSON.dump_default_options from dump The use of Hash#update from the JSON.dump method was mutating the dump_default_options hash on any call to dump with a limit provided. An individual method call with an overriding value shouldn't update the defaults in this way. --- lib/json/common.rb | 2 +- tests/test_json.rb | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/json/common.rb b/lib/json/common.rb index 426d933b4..32d989258 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -390,7 +390,7 @@ def dump(obj, anIO = nil, limit = nil) end end opts = JSON.dump_default_options - limit and opts.update(:max_nesting => limit) + opts = opts.merge(:max_nesting => limit) if limit result = generate(obj, opts) if anIO anIO.write result diff --git a/tests/test_json.rb b/tests/test_json.rb index 6af6b3220..f4e6696c3 100755 --- a/tests/test_json.rb +++ b/tests/test_json.rb @@ -515,6 +515,12 @@ def test_dump assert_equal too_deep, output.string end + def test_dump_should_modify_defaults + max_nesting = JSON.dump_default_options[:max_nesting] + JSON.dump([], StringIO.new, 10) + assert_equal max_nesting, JSON.dump_default_options[:max_nesting] + end + def test_big_integers json1 = JSON([orig = (1 << 31) - 1]) assert_equal orig, JSON[json1][0] From f1b745e4ef8b9b7bef6a240d92d045922e642cc2 Mon Sep 17 00:00:00 2001 From: Iain Beeston Date: Tue, 4 Nov 2014 08:48:41 +0000 Subject: [PATCH 069/312] Added ruby-head to travis allowed-failures This is probably a contraversial idea. ruby-head can be fairly unstable but then json is a core gem. At least if it's an allowed-failure then builds will always be run against ruby-head, but pull requests (and master) won't report build failures if something is broken in ruby-head --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d4f8f7abc..5907de769 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,4 +18,5 @@ matrix: allow_failures: - rvm: rbx-18mode - rvm: rbx-19mode + - rvm: ruby-head script: "bundle exec rake" From 737bb637c7accfb1a704bc15560ab8bb83fccfa4 Mon Sep 17 00:00:00 2001 From: Ben Browning Date: Tue, 16 Dec 2014 10:12:10 -0500 Subject: [PATCH 070/312] Improve JRuby perf. by removing source of multithreaded contention The RuntimeInfo.forRuntime method synchronizes all invocations and ParserSession#parseString was calling this many times when parsing large JSON strings. Thus, when running in a heavily multithreaded environment, threads were spending a large portion of their time waiting on that synchronization instead of doing work parsing the JSON. This fix simply passes in the RuntimeInfo object to the ParserSession when it's instantiated, since the RuntimeInfo is already known and we've already incurred the synchronization cost at that time. Using the test script at https://gist.github.com/bbrowning/0b89580b03a5f19e7a9f, I get the following results before and after this fix on my machine: Before: $ jruby ~/tmp/json_contention.rb 337.920000 0.570000 338.490000 ( 57.955000) After: $ jruby ~/tmp/json_contention.rb 326.400000 0.580000 326.980000 ( 43.084000) That's a 25% reduction in processing time for parsing the same JSON on my quad core machine. I'd expect an even higher percentage improvement on a machine with more CPUs. --- java/src/json/ext/Parser.java | 171 +++++++++++++++++----------------- java/src/json/ext/Parser.rl | 9 +- 2 files changed, 91 insertions(+), 89 deletions(-) diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index 6cb5886a7..37423f540 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -130,7 +130,7 @@ public Parser(Ruby runtime, RubyClass metaClass) { * *
:create_additions *
If set to false, the Parser doesn't create additions - * even if a matchin class and create_id was found. This option + * even if a matching class and create_id was found. This option * defaults to true. * *
:object_class @@ -248,7 +248,7 @@ private RubyString reinterpretEncoding(ThreadContext context, */ @JRubyMethod public IRubyObject parse(ThreadContext context) { - return new ParserSession(this, context).parse(); + return new ParserSession(this, context, info).parse(); } /** @@ -304,6 +304,7 @@ private RubyString getCreateId(ThreadContext context) { private static class ParserSession { private final Parser parser; private final ThreadContext context; + private final RuntimeInfo info; private final ByteList byteList; private final ByteList view; private final byte[] data; @@ -315,9 +316,10 @@ private static class ParserSession { // no idea about the origins of this value, ask Flori ;) private static final int EVIL = 0x666; - private ParserSession(Parser parser, ThreadContext context) { + private ParserSession(Parser parser, ThreadContext context, RuntimeInfo info) { this.parser = parser; this.context = context; + this.info = info; this.byteList = parser.checkAndGetSource().getByteList(); this.data = byteList.unsafeBytes(); this.view = new ByteList(data, false); @@ -337,11 +339,11 @@ private Ruby getRuntime() { } -// line 363 "Parser.rl" +// line 365 "Parser.rl" -// line 345 "Parser.java" +// line 347 "Parser.java" private static byte[] init__JSON_value_actions_0() { return new byte [] { @@ -455,7 +457,7 @@ private static byte[] init__JSON_value_from_state_actions_0() static final int JSON_value_en_main = 1; -// line 469 "Parser.rl" +// line 471 "Parser.rl" void parseValue(ParserResult res, int p, int pe) { @@ -463,14 +465,14 @@ void parseValue(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 467 "Parser.java" +// line 469 "Parser.java" { cs = JSON_value_start; } -// line 476 "Parser.rl" +// line 478 "Parser.rl" -// line 474 "Parser.java" +// line 476 "Parser.java" { int _klen; int _trans = 0; @@ -496,13 +498,13 @@ void parseValue(ParserResult res, int p, int pe) { while ( _nacts-- > 0 ) { switch ( _JSON_value_actions[_acts++] ) { case 9: -// line 454 "Parser.rl" +// line 456 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 506 "Parser.java" +// line 508 "Parser.java" } } @@ -565,25 +567,25 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) switch ( _JSON_value_actions[_acts++] ) { case 0: -// line 371 "Parser.rl" +// line 373 "Parser.rl" { result = getRuntime().getNil(); } break; case 1: -// line 374 "Parser.rl" +// line 376 "Parser.rl" { result = getRuntime().getFalse(); } break; case 2: -// line 377 "Parser.rl" +// line 379 "Parser.rl" { result = getRuntime().getTrue(); } break; case 3: -// line 380 "Parser.rl" +// line 382 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_NAN); @@ -593,7 +595,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 4: -// line 387 "Parser.rl" +// line 389 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_INFINITY); @@ -603,7 +605,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 5: -// line 394 "Parser.rl" +// line 396 "Parser.rl" { if (pe > p + 9 - (parser.quirksMode ? 1 : 0) && absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) { @@ -632,7 +634,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 6: -// line 420 "Parser.rl" +// line 422 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -645,7 +647,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 7: -// line 430 "Parser.rl" +// line 432 "Parser.rl" { currentNesting++; parseArray(res, p, pe); @@ -660,7 +662,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 8: -// line 442 "Parser.rl" +// line 444 "Parser.rl" { currentNesting++; parseObject(res, p, pe); @@ -674,7 +676,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } } break; -// line 678 "Parser.java" +// line 680 "Parser.java" } } } @@ -694,7 +696,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) break; } } -// line 477 "Parser.rl" +// line 479 "Parser.rl" if (cs >= JSON_value_first_final && result != null) { res.update(result, p); @@ -704,7 +706,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } -// line 708 "Parser.java" +// line 710 "Parser.java" private static byte[] init__JSON_integer_actions_0() { return new byte [] { @@ -803,7 +805,7 @@ private static byte[] init__JSON_integer_trans_actions_0() static final int JSON_integer_en_main = 1; -// line 496 "Parser.rl" +// line 498 "Parser.rl" void parseInteger(ParserResult res, int p, int pe) { @@ -821,15 +823,15 @@ int parseIntegerInternal(int p, int pe) { int cs = EVIL; -// line 825 "Parser.java" +// line 827 "Parser.java" { cs = JSON_integer_start; } -// line 513 "Parser.rl" +// line 515 "Parser.rl" int memo = p; -// line 833 "Parser.java" +// line 835 "Parser.java" { int _klen; int _trans = 0; @@ -910,13 +912,13 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) switch ( _JSON_integer_actions[_acts++] ) { case 0: -// line 490 "Parser.rl" +// line 492 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 920 "Parser.java" +// line 922 "Parser.java" } } } @@ -936,7 +938,7 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) break; } } -// line 515 "Parser.rl" +// line 517 "Parser.rl" if (cs < JSON_integer_first_final) { return -1; @@ -958,7 +960,7 @@ RubyInteger bytesToInum(Ruby runtime, ByteList num) { } -// line 962 "Parser.java" +// line 964 "Parser.java" private static byte[] init__JSON_float_actions_0() { return new byte [] { @@ -1060,7 +1062,7 @@ private static byte[] init__JSON_float_trans_actions_0() static final int JSON_float_en_main = 1; -// line 550 "Parser.rl" +// line 552 "Parser.rl" void parseFloat(ParserResult res, int p, int pe) { @@ -1078,15 +1080,15 @@ int parseFloatInternal(int p, int pe) { int cs = EVIL; -// line 1082 "Parser.java" +// line 1084 "Parser.java" { cs = JSON_float_start; } -// line 567 "Parser.rl" +// line 569 "Parser.rl" int memo = p; -// line 1090 "Parser.java" +// line 1092 "Parser.java" { int _klen; int _trans = 0; @@ -1167,13 +1169,13 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) switch ( _JSON_float_actions[_acts++] ) { case 0: -// line 541 "Parser.rl" +// line 543 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1177 "Parser.java" +// line 1179 "Parser.java" } } } @@ -1193,7 +1195,7 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) break; } } -// line 569 "Parser.rl" +// line 571 "Parser.rl" if (cs < JSON_float_first_final) { return -1; @@ -1209,7 +1211,7 @@ RubyFloat createFloat(int p, int new_p) { } -// line 1213 "Parser.java" +// line 1215 "Parser.java" private static byte[] init__JSON_string_actions_0() { return new byte [] { @@ -1311,7 +1313,7 @@ private static byte[] init__JSON_string_trans_actions_0() static final int JSON_string_en_main = 1; -// line 614 "Parser.rl" +// line 616 "Parser.rl" void parseString(ParserResult res, int p, int pe) { @@ -1319,15 +1321,15 @@ void parseString(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 1323 "Parser.java" +// line 1325 "Parser.java" { cs = JSON_string_start; } -// line 621 "Parser.rl" +// line 623 "Parser.rl" int memo = p; -// line 1331 "Parser.java" +// line 1333 "Parser.java" { int _klen; int _trans = 0; @@ -1408,7 +1410,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) switch ( _JSON_string_actions[_acts++] ) { case 0: -// line 589 "Parser.rl" +// line 591 "Parser.rl" { int offset = byteList.begin(); ByteList decoded = decoder.decode(byteList, memo + 1 - offset, @@ -1423,13 +1425,13 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) } break; case 1: -// line 602 "Parser.rl" +// line 604 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1433 "Parser.java" +// line 1435 "Parser.java" } } } @@ -1449,7 +1451,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) break; } } -// line 623 "Parser.rl" +// line 625 "Parser.rl" if (parser.createAdditions) { RubyHash match_string = parser.match_string; @@ -1476,8 +1478,7 @@ public void visit(IRubyObject pattern, IRubyObject klass) { } } - if (cs >= JSON_string_first_final && result != null) { - RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + if (cs >= JSON_string_first_final && result != null) { if (info.encodingsSupported() && result instanceof RubyString) { ((RubyString)result).force_encoding(context, info.utf8.get()); } @@ -1488,7 +1489,7 @@ public void visit(IRubyObject pattern, IRubyObject klass) { } -// line 1492 "Parser.java" +// line 1493 "Parser.java" private static byte[] init__JSON_array_actions_0() { return new byte [] { @@ -1601,7 +1602,7 @@ private static byte[] init__JSON_array_trans_actions_0() static final int JSON_array_en_main = 1; -// line 697 "Parser.rl" +// line 698 "Parser.rl" void parseArray(ParserResult res, int p, int pe) { @@ -1621,14 +1622,14 @@ void parseArray(ParserResult res, int p, int pe) { } -// line 1625 "Parser.java" +// line 1626 "Parser.java" { cs = JSON_array_start; } -// line 716 "Parser.rl" +// line 717 "Parser.rl" -// line 1632 "Parser.java" +// line 1633 "Parser.java" { int _klen; int _trans = 0; @@ -1709,7 +1710,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) switch ( _JSON_array_actions[_acts++] ) { case 0: -// line 666 "Parser.rl" +// line 667 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1726,13 +1727,13 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } break; case 1: -// line 681 "Parser.rl" +// line 682 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1736 "Parser.java" +// line 1737 "Parser.java" } } } @@ -1752,7 +1753,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) break; } } -// line 717 "Parser.rl" +// line 718 "Parser.rl" if (cs >= JSON_array_first_final) { res.update(result, p + 1); @@ -1762,7 +1763,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } -// line 1766 "Parser.java" +// line 1767 "Parser.java" private static byte[] init__JSON_object_actions_0() { return new byte [] { @@ -1885,7 +1886,7 @@ private static byte[] init__JSON_object_trans_actions_0() static final int JSON_object_en_main = 1; -// line 776 "Parser.rl" +// line 777 "Parser.rl" void parseObject(ParserResult res, int p, int pe) { @@ -1910,14 +1911,14 @@ void parseObject(ParserResult res, int p, int pe) { } -// line 1914 "Parser.java" +// line 1915 "Parser.java" { cs = JSON_object_start; } -// line 800 "Parser.rl" +// line 801 "Parser.rl" -// line 1921 "Parser.java" +// line 1922 "Parser.java" { int _klen; int _trans = 0; @@ -1998,7 +1999,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) switch ( _JSON_object_actions[_acts++] ) { case 0: -// line 731 "Parser.rl" +// line 732 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2015,7 +2016,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 1: -// line 746 "Parser.rl" +// line 747 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -2035,13 +2036,13 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 2: -// line 764 "Parser.rl" +// line 765 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 2045 "Parser.java" +// line 2046 "Parser.java" } } } @@ -2061,7 +2062,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) break; } } -// line 801 "Parser.rl" +// line 802 "Parser.rl" if (cs < JSON_object_first_final) { res.update(null, p + 1); @@ -2094,7 +2095,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } -// line 2098 "Parser.java" +// line 2099 "Parser.java" private static byte[] init__JSON_actions_0() { return new byte [] { @@ -2198,7 +2199,7 @@ private static byte[] init__JSON_trans_actions_0() static final int JSON_en_main = 1; -// line 866 "Parser.rl" +// line 867 "Parser.rl" public IRubyObject parseStrict() { @@ -2208,16 +2209,16 @@ public IRubyObject parseStrict() { ParserResult res = new ParserResult(); -// line 2212 "Parser.java" +// line 2213 "Parser.java" { cs = JSON_start; } -// line 875 "Parser.rl" +// line 876 "Parser.rl" p = byteList.begin(); pe = p + byteList.length(); -// line 2221 "Parser.java" +// line 2222 "Parser.java" { int _klen; int _trans = 0; @@ -2298,7 +2299,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) switch ( _JSON_actions[_acts++] ) { case 0: -// line 838 "Parser.rl" +// line 839 "Parser.rl" { currentNesting = 1; parseObject(res, p, pe); @@ -2312,7 +2313,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) } break; case 1: -// line 850 "Parser.rl" +// line 851 "Parser.rl" { currentNesting = 1; parseArray(res, p, pe); @@ -2325,7 +2326,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) } } break; -// line 2329 "Parser.java" +// line 2330 "Parser.java" } } } @@ -2345,7 +2346,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) break; } } -// line 878 "Parser.rl" +// line 879 "Parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -2355,7 +2356,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) } -// line 2359 "Parser.java" +// line 2360 "Parser.java" private static byte[] init__JSON_quirks_mode_actions_0() { return new byte [] { @@ -2458,7 +2459,7 @@ private static byte[] init__JSON_quirks_mode_trans_actions_0() static final int JSON_quirks_mode_en_main = 1; -// line 906 "Parser.rl" +// line 907 "Parser.rl" public IRubyObject parseQuirksMode() { @@ -2468,16 +2469,16 @@ public IRubyObject parseQuirksMode() { ParserResult res = new ParserResult(); -// line 2472 "Parser.java" +// line 2473 "Parser.java" { cs = JSON_quirks_mode_start; } -// line 915 "Parser.rl" +// line 916 "Parser.rl" p = byteList.begin(); pe = p + byteList.length(); -// line 2481 "Parser.java" +// line 2482 "Parser.java" { int _klen; int _trans = 0; @@ -2558,7 +2559,7 @@ else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] ) switch ( _JSON_quirks_mode_actions[_acts++] ) { case 0: -// line 892 "Parser.rl" +// line 893 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2570,7 +2571,7 @@ else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] ) } } break; -// line 2574 "Parser.java" +// line 2575 "Parser.java" } } } @@ -2590,7 +2591,7 @@ else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] ) break; } } -// line 918 "Parser.rl" +// line 919 "Parser.rl" if (cs >= JSON_quirks_mode_first_final && p == pe) { return result; diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 7dcdd2ecb..6d6596314 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -246,7 +246,7 @@ public class Parser extends RubyObject { */ @JRubyMethod public IRubyObject parse(ThreadContext context) { - return new ParserSession(this, context).parse(); + return new ParserSession(this, context, info).parse(); } /** @@ -302,6 +302,7 @@ public class Parser extends RubyObject { private static class ParserSession { private final Parser parser; private final ThreadContext context; + private final RuntimeInfo info; private final ByteList byteList; private final ByteList view; private final byte[] data; @@ -313,9 +314,10 @@ public class Parser extends RubyObject { // no idea about the origins of this value, ask Flori ;) private static final int EVIL = 0x666; - private ParserSession(Parser parser, ThreadContext context) { + private ParserSession(Parser parser, ThreadContext context, RuntimeInfo info) { this.parser = parser; this.context = context; + this.info = info; this.byteList = parser.checkAndGetSource().getByteList(); this.data = byteList.unsafeBytes(); this.view = new ByteList(data, false); @@ -646,8 +648,7 @@ public class Parser extends RubyObject { } } - if (cs >= JSON_string_first_final && result != null) { - RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + if (cs >= JSON_string_first_final && result != null) { if (info.encodingsSupported() && result instanceof RubyString) { ((RubyString)result).force_encoding(context, info.utf8.get()); } From c37bb5cd494d75e348acf666ecd70b4eb628bffe Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 8 Jan 2015 22:41:25 +0100 Subject: [PATCH 071/312] Bump version number to 1.8.2 --- VERSION | 2 +- json.gemspec | Bin 5008 -> 5008 bytes json_pure.gemspec | 6 +++--- lib/json/version.rb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index a8fdfda1c..53adb84c8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8.1 +1.8.2 diff --git a/json.gemspec b/json.gemspec index 9fbc284eeeea6d140f570ed9fa7d081555695567..61f1c54826b62e7d94a8ba82ada6fcfb670c73f8 100644 GIT binary patch delta 23 ecmbQBK0$qgHlxu*oz+0%#y&=i&C?lw3IYIPRtT*C delta 23 ecmbQBK0$qgHlyK0oz+0%#y&=)&C?lw3IYIP7YL;Q diff --git a/json_pure.gemspec b/json_pure.gemspec index 9847e5e64..f66bde518 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -1,14 +1,14 @@ # -*- encoding: utf-8 -*- -# stub: json_pure 1.8.1 ruby lib +# stub: json_pure 1.8.2 ruby lib Gem::Specification.new do |s| s.name = "json_pure" - s.version = "1.8.1" + s.version = "1.8.2" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2015-01-02" + s.date = "2015-01-08" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] diff --git a/lib/json/version.rb b/lib/json/version.rb index 47cdcd607..4549f5f21 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.8.1' + VERSION = '1.8.2' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: From eddd9ba87c7bace8d2dc40eb58626f00d9996424 Mon Sep 17 00:00:00 2001 From: Jesse Cooke Date: Thu, 25 Dec 2014 13:22:10 -0800 Subject: [PATCH 072/312] CI with current rbx-2 --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c0d1d3407..3b594b741 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,14 +10,12 @@ rvm: - 2.1 - 2.2 - ree - - rbx-18mode - - rbx-19mode + - rbx-2 - jruby-18mode - jruby-19mode - ruby-head matrix: allow_failures: - - rvm: rbx-18mode - - rvm: rbx-19mode + - rvm: rbx-2 - rvm: ruby-head script: "bundle exec rake" From cfa8b00be6c4d41a701f0a1912a5c8fd3d08abc9 Mon Sep 17 00:00:00 2001 From: Juanito Fatas Date: Fri, 19 Dec 2014 00:47:47 +0800 Subject: [PATCH 073/312] Use the new build env on Travis. --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3b594b741..f1795f717 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ # Passes arguments to bundle install (http://gembundler.com/man/bundle-install.1.html) #bundler_args: --binstubs +language: ruby # Specify which ruby versions you wish to run your tests on, each version will be used rvm: @@ -19,3 +20,5 @@ matrix: - rvm: rbx-2 - rvm: ruby-head script: "bundle exec rake" + +sudo: false From 82babeccc5e155782586deef81b1a1d79851b1ed Mon Sep 17 00:00:00 2001 From: Michael Mac-Vicar Date: Sun, 7 Dec 2014 15:17:17 -0200 Subject: [PATCH 074/312] Add test for format options used by the generator The space_before, space, indent, object_nl and array_nl options of the space were not covered. --- tests/test_json_generate.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index ea6a9a3ee..ba05eeb67 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -73,6 +73,19 @@ def test_generate_pretty assert_equal '666', pretty_generate(666, :quirks_mode => true) end + def test_generate_custom + state = State.new(space_before: " ", space: " ", indent:"", object_nl: "\n", array_nl: "") + json = generate({1=>{2=>3,4=>[5,6]}}, state) + assert_equal(<<'EOT'.chomp, json) +{ +"1" : { +"2" : 3, +"4" : [5,6] +} +} +EOT + end + def test_fast_generate json = fast_generate(@hash) assert_equal(JSON.parse(@json2), JSON.parse(json)) From 1ed3666c6800d31b2fac2837b4a42cedfab373fe Mon Sep 17 00:00:00 2001 From: Michael Mac-Vicar Date: Sun, 7 Dec 2014 15:18:39 -0200 Subject: [PATCH 075/312] Use space_before as documented in the generator This option was already documented but not implemented, allows setting the separator used before the ":" during generation. --- ext/json/ext/generator/generator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index a474fbbc8..592b95a4f 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -898,6 +898,7 @@ static FBuffer *cState_prepare_buffer(VALUE self) } else { state->object_delim2 = fbuffer_alloc(16); } + if (state->space_before) fbuffer_append(state->object_delim2, state->space_before, state->space_before_len); fbuffer_append_char(state->object_delim2, ':'); if (state->space) fbuffer_append(state->object_delim2, state->space, state->space_len); From 598b7c6c3f42c5074a630a05a4070139e29f57ce Mon Sep 17 00:00:00 2001 From: Michael Mac-Vicar Date: Sun, 7 Dec 2014 15:48:40 -0200 Subject: [PATCH 076/312] Make generator format test backwards compatible --- tests/test_json_generate.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index ba05eeb67..8db0b7890 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -74,7 +74,7 @@ def test_generate_pretty end def test_generate_custom - state = State.new(space_before: " ", space: " ", indent:"", object_nl: "\n", array_nl: "") + state = State.new(:space_before => " ", :space => " ", :indent => "", :object_nl => "\n", :array_nl => "") json = generate({1=>{2=>3,4=>[5,6]}}, state) assert_equal(<<'EOT'.chomp, json) { From 2cf11d66f28b0e981eb24a9fc143edcbdce59e85 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 9 Jan 2015 01:50:44 +0100 Subject: [PATCH 077/312] Add to CHANGES --- CHANGES | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGES b/CHANGES index 6a67cfc54..00b692ed8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +2015-01-08 (1.8.2) + * Some performance improvements by Vipul A M . + * Fix by Jason R. Clark to avoid mutation of + JSON.dump_default_options. + * More tests by Michael Mac-Vicar and fixing + space_before accessor in generator. + * Performance on Jruby improvemed by Ben Browning . + * Some fixes to be compatible with the new Ruby 2.2 by Zachary Scott + and SHIBATA Hiroshi . 2013-05-13 (1.8.1) * Remove Rubinius exception since transcoding should be working now. 2013-05-13 (1.8.0) From f14ae4a1708d135b9a8ac2534ab4db546a32d3da Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 8 Jan 2015 22:41:25 +0100 Subject: [PATCH 078/312] Bump version number to 1.8.2 --- VERSION | 2 +- json.gemspec | Bin 5008 -> 5008 bytes json_pure.gemspec | 6 +++--- lib/json/version.rb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index a8fdfda1c..53adb84c8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8.1 +1.8.2 diff --git a/json.gemspec b/json.gemspec index 9fbc284eeeea6d140f570ed9fa7d081555695567..61f1c54826b62e7d94a8ba82ada6fcfb670c73f8 100644 GIT binary patch delta 23 ecmbQBK0$qgHlxu*oz+0%#y&=i&C?lw3IYIPRtT*C delta 23 ecmbQBK0$qgHlyK0oz+0%#y&=)&C?lw3IYIP7YL;Q diff --git a/json_pure.gemspec b/json_pure.gemspec index 9847e5e64..f66bde518 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -1,14 +1,14 @@ # -*- encoding: utf-8 -*- -# stub: json_pure 1.8.1 ruby lib +# stub: json_pure 1.8.2 ruby lib Gem::Specification.new do |s| s.name = "json_pure" - s.version = "1.8.1" + s.version = "1.8.2" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2015-01-02" + s.date = "2015-01-08" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] diff --git a/lib/json/version.rb b/lib/json/version.rb index 47cdcd607..4549f5f21 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.8.1' + VERSION = '1.8.2' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: From fcf3a8b799955581c92055a4398d12ae0279338a Mon Sep 17 00:00:00 2001 From: SHIBATA Hiroshi Date: Tue, 13 Jan 2015 12:14:11 +0900 Subject: [PATCH 079/312] sync trunk again: fixed regression of r49027 --- ext/json/ext/parser/parser.c | 8 ++++---- ext/json/ext/parser/parser.rl | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 8824b3035..20531b35d 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -28,16 +28,16 @@ static UTF32 unescape_unicode(const unsigned char *p) UTF32 result = 0; b = digit_values[p[0]]; if (b < 0) return UNI_REPLACEMENT_CHAR; - result = (result << 4) | b; + result = (result << 4) | (unsigned char)b; b = digit_values[p[1]]; - result = (result << 4) | b; if (b < 0) return UNI_REPLACEMENT_CHAR; + result = (result << 4) | (unsigned char)b; b = digit_values[p[2]]; - result = (result << 4) | b; if (b < 0) return UNI_REPLACEMENT_CHAR; + result = (result << 4) | (unsigned char)b; b = digit_values[p[3]]; - result = (result << 4) | b; if (b < 0) return UNI_REPLACEMENT_CHAR; + result = (result << 4) | (unsigned char)b; return result; } diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index 2af1cc678..70f3f9a19 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -26,16 +26,16 @@ static UTF32 unescape_unicode(const unsigned char *p) UTF32 result = 0; b = digit_values[p[0]]; if (b < 0) return UNI_REPLACEMENT_CHAR; - result = (result << 4) | b; + result = (result << 4) | (unsigned char)b; b = digit_values[p[1]]; - result = (result << 4) | b; if (b < 0) return UNI_REPLACEMENT_CHAR; + result = (result << 4) | (unsigned char)b; b = digit_values[p[2]]; - result = (result << 4) | b; if (b < 0) return UNI_REPLACEMENT_CHAR; + result = (result << 4) | (unsigned char)b; b = digit_values[p[3]]; - result = (result << 4) | b; if (b < 0) return UNI_REPLACEMENT_CHAR; + result = (result << 4) | (unsigned char)b; return result; } @@ -887,7 +887,7 @@ static VALUE cParser_quirks_mode_p(VALUE self) } -void Init_parser() +void Init_parser(void) { rb_require("json/common"); mJSON = rb_define_module("JSON"); From 7f60191b6151958e98aae19f37d9602ef3d8a773 Mon Sep 17 00:00:00 2001 From: SHIBATA Hiroshi Date: Tue, 13 Jan 2015 12:24:09 +0900 Subject: [PATCH 080/312] use ZALLOC if it can be used, and defined ZALLOC macro. --- ext/json/ext/generator/generator.c | 3 +- ext/json/ext/generator/generator.h | 9 ++++ ext/json/ext/parser/parser.c | 69 +++++++++++++++--------------- ext/json/ext/parser/parser.h | 9 ++++ ext/json/ext/parser/parser.rl | 3 +- 5 files changed, 54 insertions(+), 39 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 592b95a4f..90285be2e 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -528,8 +528,7 @@ static const rb_data_type_t JSON_Generator_State_type = { static JSON_Generator_State *State_allocate(void) { - JSON_Generator_State *state = ALLOC(JSON_Generator_State); - MEMZERO(state, JSON_Generator_State, 1); + JSON_Generator_State *state = ZALLOC(JSON_Generator_State); return state; } diff --git a/ext/json/ext/generator/generator.h b/ext/json/ext/generator/generator.h index 02193f094..416159a9c 100644 --- a/ext/json/ext/generator/generator.h +++ b/ext/json/ext/generator/generator.h @@ -147,6 +147,15 @@ static VALUE cState_ascii_only_p(VALUE self); static VALUE cState_depth(VALUE self); static VALUE cState_depth_set(VALUE self, VALUE depth); static FBuffer *cState_prepare_buffer(VALUE self); +#ifndef ZALLOC +#define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type))) +static inline void *ruby_zalloc(size_t n) +{ + void *p = ruby_xmalloc(n); + memset(p, 0, n); + return p; +} +#endif #ifdef TypedData_Wrap_Struct static const rb_data_type_t JSON_Generator_State_type; #define NEW_TYPEDDATA_WRAPPER 1 diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 20531b35d..eed58e5d3 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -89,11 +89,11 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, #line 92 "parser.c" -static const int JSON_object_start = 1; -static const int JSON_object_first_final = 27; -static const int JSON_object_error = 0; +enum {JSON_object_start = 1}; +enum {JSON_object_first_final = 27}; +enum {JSON_object_error = 0}; -static const int JSON_object_en_main = 1; +enum {JSON_object_en_main = 1}; #line 151 "parser.rl" @@ -467,11 +467,11 @@ case 26: #line 470 "parser.c" -static const int JSON_value_start = 1; -static const int JSON_value_first_final = 21; -static const int JSON_value_error = 0; +enum {JSON_value_start = 1}; +enum {JSON_value_first_final = 21}; +enum {JSON_value_error = 0}; -static const int JSON_value_en_main = 1; +enum {JSON_value_en_main = 1}; #line 271 "parser.rl" @@ -776,11 +776,11 @@ case 20: #line 779 "parser.c" -static const int JSON_integer_start = 1; -static const int JSON_integer_first_final = 3; -static const int JSON_integer_error = 0; +enum {JSON_integer_start = 1}; +enum {JSON_integer_first_final = 3}; +enum {JSON_integer_error = 0}; -static const int JSON_integer_en_main = 1; +enum {JSON_integer_en_main = 1}; #line 295 "parser.rl" @@ -875,11 +875,11 @@ case 5: #line 878 "parser.c" -static const int JSON_float_start = 1; -static const int JSON_float_first_final = 8; -static const int JSON_float_error = 0; +enum {JSON_float_start = 1}; +enum {JSON_float_first_final = 8}; +enum {JSON_float_error = 0}; -static const int JSON_float_en_main = 1; +enum {JSON_float_en_main = 1}; #line 329 "parser.rl" @@ -1041,11 +1041,11 @@ case 7: #line 1044 "parser.c" -static const int JSON_array_start = 1; -static const int JSON_array_first_final = 17; -static const int JSON_array_error = 0; +enum {JSON_array_start = 1}; +enum {JSON_array_first_final = 17}; +enum {JSON_array_error = 0}; -static const int JSON_array_en_main = 1; +enum {JSON_array_en_main = 1}; #line 381 "parser.rl" @@ -1373,11 +1373,11 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) #line 1376 "parser.c" -static const int JSON_string_start = 1; -static const int JSON_string_first_final = 8; -static const int JSON_string_error = 0; +enum {JSON_string_start = 1}; +enum {JSON_string_first_final = 8}; +enum {JSON_string_error = 0}; -static const int JSON_string_en_main = 1; +enum {JSON_string_en_main = 1}; #line 494 "parser.rl" @@ -1730,11 +1730,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) #line 1733 "parser.c" -static const int JSON_start = 1; -static const int JSON_first_final = 10; -static const int JSON_error = 0; +enum {JSON_start = 1}; +enum {JSON_first_final = 10}; +enum {JSON_error = 0}; -static const int JSON_en_main = 1; +enum {JSON_en_main = 1}; #line 740 "parser.rl" @@ -1904,11 +1904,11 @@ case 9: #line 1907 "parser.c" -static const int JSON_quirks_mode_start = 1; -static const int JSON_quirks_mode_first_final = 10; -static const int JSON_quirks_mode_error = 0; +enum {JSON_quirks_mode_start = 1}; +enum {JSON_quirks_mode_first_final = 10}; +enum {JSON_quirks_mode_error = 0}; -static const int JSON_quirks_mode_en_main = 1; +enum {JSON_quirks_mode_en_main = 1}; #line 778 "parser.rl" @@ -2094,8 +2094,7 @@ static VALUE cParser_parse(VALUE self) static JSON_Parser *JSON_allocate(void) { - JSON_Parser *json = ALLOC(JSON_Parser); - MEMZERO(json, JSON_Parser, 1); + JSON_Parser *json = ZALLOC(JSON_Parser); json->fbuffer = fbuffer_alloc(0); return json; } @@ -2164,7 +2163,7 @@ static VALUE cParser_quirks_mode_p(VALUE self) } -void Init_parser() +void Init_parser(void) { rb_require("json/common"); mJSON = rb_define_module("JSON"); diff --git a/ext/json/ext/parser/parser.h b/ext/json/ext/parser/parser.h index 418637f82..e98f26a29 100644 --- a/ext/json/ext/parser/parser.h +++ b/ext/json/ext/parser/parser.h @@ -73,6 +73,15 @@ static void JSON_mark(void *json); static void JSON_free(void *json); static VALUE cJSON_parser_s_allocate(VALUE klass); static VALUE cParser_source(VALUE self); +#ifndef ZALLOC +#define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type))) +static inline void *ruby_zalloc(size_t n) +{ + void *p = ruby_xmalloc(n); + memset(p, 0, n); + return p; +} +#endif #ifdef TypedData_Wrap_Struct static const rb_data_type_t JSON_Parser_type; #define NEW_TYPEDDATA_WRAPPER 1 diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index 70f3f9a19..b9b51aaa4 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -817,8 +817,7 @@ static VALUE cParser_parse(VALUE self) static JSON_Parser *JSON_allocate(void) { - JSON_Parser *json = ALLOC(JSON_Parser); - MEMZERO(json, JSON_Parser, 1); + JSON_Parser *json = ZALLOC(JSON_Parser); json->fbuffer = fbuffer_alloc(0); return json; } From 704a7cfc9a6dfcfefd8ce0ca16146cc740ee55a7 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Tue, 21 Apr 2015 08:45:47 -0500 Subject: [PATCH 081/312] Fix mention of C extensions in README JRuby's extension is part of json now and is written in Java. --- README.rdoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.rdoc b/README.rdoc index eda896f84..ebb8b82d1 100644 --- a/README.rdoc +++ b/README.rdoc @@ -8,9 +8,9 @@ will be two variants available: * A pure ruby variant, that relies on the iconv and the stringscan extensions, which are both part of the ruby standard library. -* The quite a bit faster C extension variant, which is in parts implemented - in C and comes with its own unicode conversion functions and a parser - generated by the ragel state machine compiler +* The quite a bit faster native extension variant, which is in parts + implemented in C or Java and comes with its own unicode conversion + functions and a parser generated by the ragel state machine compiler http://www.cs.queensu.ca/~thurston/ragel . Both variants of the JSON generator generate UTF-8 character sequences by From 6020ec8585cb0ee9d5b0166b27fa53ca1170653e Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 28 May 2015 07:17:42 +0000 Subject: [PATCH 082/312] parser.rl: allocate structs with wrapper * ext/json/ext/parser/parser.rl (cJSON_parser_s_allocate): allocate structs with making new wrapper objects and get rid of potential memory leak. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50660 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/json/ext/parser/parser.c | 14 ++++---------- ext/json/ext/parser/parser.h | 5 ++--- ext/json/ext/parser/parser.rl | 14 ++++---------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index eed58e5d3..9c9d76ac3 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -2091,14 +2091,6 @@ static VALUE cParser_parse(VALUE self) } } - -static JSON_Parser *JSON_allocate(void) -{ - JSON_Parser *json = ZALLOC(JSON_Parser); - json->fbuffer = fbuffer_alloc(0); - return json; -} - static void JSON_mark(void *ptr) { JSON_Parser *json = ptr; @@ -2135,8 +2127,10 @@ static const rb_data_type_t JSON_Parser_type = { static VALUE cJSON_parser_s_allocate(VALUE klass) { - JSON_Parser *json = JSON_allocate(); - return TypedData_Wrap_Struct(klass, &JSON_Parser_type, json); + JSON_Parser *json; + VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json); + json->fbuffer = fbuffer_alloc(0); + return obj; } /* diff --git a/ext/json/ext/parser/parser.h b/ext/json/ext/parser/parser.h index e98f26a29..abcc2571f 100644 --- a/ext/json/ext/parser/parser.h +++ b/ext/json/ext/parser/parser.h @@ -68,7 +68,6 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu static VALUE convert_encoding(VALUE source); static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self); static VALUE cParser_parse(VALUE self); -static JSON_Parser *JSON_allocate(void); static void JSON_mark(void *json); static void JSON_free(void *json); static VALUE cJSON_parser_s_allocate(VALUE klass); @@ -82,11 +81,11 @@ static inline void *ruby_zalloc(size_t n) return p; } #endif -#ifdef TypedData_Wrap_Struct +#ifdef TypedData_Make_Struct static const rb_data_type_t JSON_Parser_type; #define NEW_TYPEDDATA_WRAPPER 1 #else -#define TypedData_Wrap_Struct(klass, ignore, json) Data_Wrap_Struct(klass, JSON_mark, JSON_free, json) +#define TypedData_Make_Struct(klass, type, ignore, json) Data_Make_Struct(klass, type, NULL, JSON_free, json) #define TypedData_Get_Struct(self, JSON_Parser, ignore, json) Data_Get_Struct(self, JSON_Parser, json) #endif diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index b9b51aaa4..216ad26b2 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -814,14 +814,6 @@ static VALUE cParser_parse(VALUE self) } } - -static JSON_Parser *JSON_allocate(void) -{ - JSON_Parser *json = ZALLOC(JSON_Parser); - json->fbuffer = fbuffer_alloc(0); - return json; -} - static void JSON_mark(void *ptr) { JSON_Parser *json = ptr; @@ -858,8 +850,10 @@ static const rb_data_type_t JSON_Parser_type = { static VALUE cJSON_parser_s_allocate(VALUE klass) { - JSON_Parser *json = JSON_allocate(); - return TypedData_Wrap_Struct(klass, &JSON_Parser_type, json); + JSON_Parser *json; + VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json); + json->fbuffer = fbuffer_alloc(0); + return obj; } /* From fae344f2f12a73baf0d4afa663eee3d942aeec8e Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 28 May 2015 07:17:55 +0000 Subject: [PATCH 083/312] generator.c: allocate structs with wrapper * ext/json/ext/generator/generator.c (cState_s_allocate): allocate structs with making new wrapper objects and get rid of potential memory leak. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50661 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/json/ext/generator/generator.c | 11 +++-------- ext/json/ext/generator/generator.h | 5 ++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 90285be2e..6300c64f3 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -526,16 +526,11 @@ static const rb_data_type_t JSON_Generator_State_type = { }; #endif -static JSON_Generator_State *State_allocate(void) -{ - JSON_Generator_State *state = ZALLOC(JSON_Generator_State); - return state; -} - static VALUE cState_s_allocate(VALUE klass) { - JSON_Generator_State *state = State_allocate(); - return TypedData_Wrap_Struct(klass, &JSON_Generator_State_type, state); + JSON_Generator_State *state; + return TypedData_Make_Struct(klass, JSON_Generator_State, + &JSON_Generator_State_type, state); } /* diff --git a/ext/json/ext/generator/generator.h b/ext/json/ext/generator/generator.h index 416159a9c..298c0a496 100644 --- a/ext/json/ext/generator/generator.h +++ b/ext/json/ext/generator/generator.h @@ -112,7 +112,6 @@ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self); static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self); static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self); static void State_free(void *state); -static JSON_Generator_State *State_allocate(void); static VALUE cState_s_allocate(VALUE klass); static VALUE cState_configure(VALUE self, VALUE opts); static VALUE cState_to_h(VALUE self); @@ -156,11 +155,11 @@ static inline void *ruby_zalloc(size_t n) return p; } #endif -#ifdef TypedData_Wrap_Struct +#ifdef TypedData_Make_Struct static const rb_data_type_t JSON_Generator_State_type; #define NEW_TYPEDDATA_WRAPPER 1 #else -#define TypedData_Wrap_Struct(klass, ignore, json) Data_Wrap_Struct(klass, NULL, State_free, json) +#define TypedData_Make_Struct(klass, type, ignore, json) Data_Make_Struct(klass, type, NULL, State_free, json) #define TypedData_Get_Struct(self, JSON_Generator_State, ignore, json) Data_Get_Struct(self, JSON_Generator_State, json) #endif From f4455bd69db73312a9ee304a99ec85f233cfa199 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 1 Jun 2015 11:00:21 +0200 Subject: [PATCH 084/312] Check 2.2.1 and 2.2.2 explicitely --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index f1795f717..22cb59f39 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,8 @@ rvm: - 1.9.3 - 2.0.0 - 2.1 + - 2.2.1 + - 2.2.2 - 2.2 - ree - rbx-2 From ec0b0a771a47ba61485a211a50aee867677e536f Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 1 Jun 2015 11:00:52 +0200 Subject: [PATCH 085/312] use newest rubygems --- json.gemspec | Bin 5008 -> 5008 bytes json_pure.gemspec | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/json.gemspec b/json.gemspec index 61f1c54826b62e7d94a8ba82ada6fcfb670c73f8..3f7772a22f4e80866bf04a5376fb1ebc3f7a5526 100644 GIT binary patch delta 24 gcmbQBK0$rMWJVS`b3iLAr0A2eA%K!iX diff --git a/json_pure.gemspec b/json_pure.gemspec index f66bde518..99288e7d4 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2015-01-08" + s.date = "2015-06-01" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] @@ -16,7 +16,7 @@ Gem::Specification.new do |s| s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] - s.rubygems_version = "2.4.5" + s.rubygems_version = "2.4.6" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] From db4c71a7701b95c30f945ee1536240920dcfdc17 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 1 Jun 2015 18:00:52 +0200 Subject: [PATCH 086/312] Bump version to 1.8.3 --- CHANGES | 2 ++ VERSION | 2 +- json.gemspec | Bin 5008 -> 5008 bytes json_pure.gemspec | 4 ++-- lib/json/version.rb | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 00b692ed8..8ffecf7c5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +2015-06-01 (1.8.3) + * Fix potential memory leak, thx to nobu. 2015-01-08 (1.8.2) * Some performance improvements by Vipul A M . * Fix by Jason R. Clark to avoid mutation of diff --git a/VERSION b/VERSION index 53adb84c8..a7ee35a3e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8.2 +1.8.3 diff --git a/json.gemspec b/json.gemspec index 3f7772a22f4e80866bf04a5376fb1ebc3f7a5526..0b40989f84b991ea34a62dadbee4c3319c9adeb9 100644 GIT binary patch delta 17 ZcmbQBK0$qgHly)Goz;xS8*l6o0su7m22B6} delta 17 ZcmbQBK0$qgHlxu*oz;v+8*l6o0su7X21@_{ diff --git a/json_pure.gemspec b/json_pure.gemspec index 99288e7d4..3631d3c5d 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -1,9 +1,9 @@ # -*- encoding: utf-8 -*- -# stub: json_pure 1.8.2 ruby lib +# stub: json_pure 1.8.3 ruby lib Gem::Specification.new do |s| s.name = "json_pure" - s.version = "1.8.2" + s.version = "1.8.3" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] diff --git a/lib/json/version.rb b/lib/json/version.rb index 4549f5f21..5a4013dbf 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.8.2' + VERSION = '1.8.3' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: From a4d6f51b75ac00ac4f4960b96fae3dbcff173875 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Sat, 13 Jun 2015 12:22:44 +0200 Subject: [PATCH 087/312] Move common setup into test_helper.rb --- Gemfile | 1 + Rakefile | 6 +++--- json.gemspec | Bin 5008 -> 5060 bytes json_pure.gemspec | 6 +++--- lib/json/pure/generator.rb | 5 +++-- tests/{setup_variant.rb => test_helper.rb} | 9 +++++++++ tests/test_json.rb | 3 +-- tests/test_json_addition.rb | 3 +-- tests/test_json_encoding.rb | 3 +-- tests/test_json_fixtures.rb | 3 +-- tests/test_json_generate.rb | 3 +-- tests/test_json_generic_object.rb | 4 ++-- tests/test_json_string_matching.rb | 3 +-- tests/test_json_unicode.rb | 3 +-- 14 files changed, 28 insertions(+), 24 deletions(-) rename tests/{setup_variant.rb => test_helper.rb} (62%) diff --git a/Gemfile b/Gemfile index ef9ce01fc..c2a30299d 100644 --- a/Gemfile +++ b/Gemfile @@ -8,3 +8,4 @@ gemspec :name => 'json-java' gem 'utils' gem 'test-unit' +gem 'byebug', :platform => :mri diff --git a/Rakefile b/Rakefile index 1d13c2cab..98b749db0 100644 --- a/Rakefile +++ b/Rakefile @@ -178,7 +178,7 @@ task :test_pure => [ :clean, :do_test_pure ] UndocumentedTestTask.new do |t| t.name = 'do_test_pure' - t.libs << 'lib' + t.libs << 'lib' << 'tests' t.test_files = FileList['tests/test_*.rb'] t.verbose = true t.options = '-v' @@ -261,7 +261,7 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby' UndocumentedTestTask.new do |t| t.name = 'do_test_ext' - t.libs << 'lib' + t.libs << 'lib' << 'tests' t.test_files = FileList['tests/test_*.rb'] t.verbose = true t.options = '-v' @@ -335,7 +335,7 @@ else UndocumentedTestTask.new do |t| t.name = 'do_test_ext' - t.libs << 'ext' << 'lib' + t.libs << 'ext' << 'lib' << 'tests' t.test_files = FileList['tests/test_*.rb'] t.verbose = true t.options = '-v' diff --git a/json.gemspec b/json.gemspec index 0b40989f84b991ea34a62dadbee4c3319c9adeb9..6add5d927f98e2a3e4320e59b35c12583a4e45d7 100644 GIT binary patch delta 51 ycmbQBenfr4R7NI4= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2015-06-01" + s.date = "2015-06-13" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] - s.files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] + s.files = ["./tests/test_helper.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] s.rubygems_version = "2.4.6" s.summary = "JSON Implementation for Ruby" - s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] + s.test_files = ["./tests/test_helper.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] if s.respond_to? :specification_version then s.specification_version = 4 diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index 9056a5d7f..225081fb3 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -286,8 +286,9 @@ def to_h alias to_hash to_h - # Generates a valid JSON document from object +obj+ and returns the - # result. If no valid JSON document can be created this method raises a + # Generates a valid JSON document from object +obj+ and + # returns the result. If no valid JSON document can be + # created this method raises a # GeneratorError exception. def generate(obj) result = obj.to_json(self) diff --git a/tests/setup_variant.rb b/tests/test_helper.rb similarity index 62% rename from tests/setup_variant.rb rename to tests/test_helper.rb index 2dab184bc..abc911231 100644 --- a/tests/setup_variant.rb +++ b/tests/test_helper.rb @@ -1,3 +1,6 @@ + +gem 'json', File.read('VERSION').chomp + case ENV['JSON'] when 'pure' $:.unshift 'lib' @@ -9,3 +12,9 @@ $:.unshift 'ext', 'lib' require 'json' end + +require 'test/unit' +begin + require 'byebug' +rescue LoadError +end diff --git a/tests/test_json.rb b/tests/test_json.rb index 7957773f2..b666dfaf7 100755 --- a/tests/test_json.rb +++ b/tests/test_json.rb @@ -1,8 +1,7 @@ #!/usr/bin/env ruby # encoding: utf-8 -require 'test/unit' -require File.join(File.dirname(__FILE__), 'setup_variant') +require 'test_helper' require 'stringio' require 'tempfile' require 'ostruct' diff --git a/tests/test_json_addition.rb b/tests/test_json_addition.rb index a30f06add..110570541 100755 --- a/tests/test_json_addition.rb +++ b/tests/test_json_addition.rb @@ -1,8 +1,7 @@ #!/usr/bin/env ruby # -*- coding:utf-8 -*- -require 'test/unit' -require File.join(File.dirname(__FILE__), 'setup_variant') +require 'test_helper' require 'json/add/core' require 'json/add/complex' require 'json/add/rational' diff --git a/tests/test_json_encoding.rb b/tests/test_json_encoding.rb index fa7d87892..3536c56c9 100644 --- a/tests/test_json_encoding.rb +++ b/tests/test_json_encoding.rb @@ -1,8 +1,7 @@ #!/usr/bin/env ruby # encoding: utf-8 -require 'test/unit' -require File.join(File.dirname(__FILE__), 'setup_variant') +require 'test_helper' class TestJSONEncoding < Test::Unit::TestCase include JSON diff --git a/tests/test_json_fixtures.rb b/tests/test_json_fixtures.rb index 584dffdfd..d580522ad 100755 --- a/tests/test_json_fixtures.rb +++ b/tests/test_json_fixtures.rb @@ -1,8 +1,7 @@ #!/usr/bin/env ruby # encoding: utf-8 -require 'test/unit' -require File.join(File.dirname(__FILE__), 'setup_variant') +require 'test_helper' class TestJSONFixtures < Test::Unit::TestCase def setup diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index 8db0b7890..2fe47601f 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -1,8 +1,7 @@ #!/usr/bin/env ruby # encoding: utf-8 -require 'test/unit' -require File.join(File.dirname(__FILE__), 'setup_variant') +require 'test_helper' class TestJSONGenerate < Test::Unit::TestCase include JSON diff --git a/tests/test_json_generic_object.rb b/tests/test_json_generic_object.rb index c43c7762b..66fc18d3a 100644 --- a/tests/test_json_generic_object.rb +++ b/tests/test_json_generic_object.rb @@ -1,8 +1,8 @@ #!/usr/bin/env ruby # encoding: utf-8 -require 'test/unit' -require File.join(File.dirname(__FILE__), 'setup_variant') +require 'test_helper' + class TestJSONGenericObject < Test::Unit::TestCase include JSON diff --git a/tests/test_json_string_matching.rb b/tests/test_json_string_matching.rb index c233df8c2..2b89588d9 100644 --- a/tests/test_json_string_matching.rb +++ b/tests/test_json_string_matching.rb @@ -1,8 +1,7 @@ #!/usr/bin/env ruby # encoding: utf-8 -require 'test/unit' -require File.join(File.dirname(__FILE__), 'setup_variant') +require 'test_helper' require 'stringio' require 'time' diff --git a/tests/test_json_unicode.rb b/tests/test_json_unicode.rb index 8352d5c6c..f59c36a11 100755 --- a/tests/test_json_unicode.rb +++ b/tests/test_json_unicode.rb @@ -1,8 +1,7 @@ #!/usr/bin/env ruby # encoding: utf-8 -require 'test/unit' -require File.join(File.dirname(__FILE__), 'setup_variant') +require 'test_helper' class TestJSONUnicode < Test::Unit::TestCase include JSON From 7ebd90f611841c7ee94471f3287ff7d79223be45 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Sat, 13 Jun 2015 12:43:32 +0200 Subject: [PATCH 088/312] Remove dependency on permutation Ruby can do this by now on her own. --- Rakefile | 12 +++++++----- json.gemspec | Bin 5060 -> 4898 bytes json_pure.gemspec | 5 +---- tests/test_json.rb | 14 -------------- 4 files changed, 8 insertions(+), 23 deletions(-) diff --git a/Rakefile b/Rakefile index 98b749db0..32e486c82 100644 --- a/Rakefile +++ b/Rakefile @@ -87,7 +87,6 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.files = PKG_FILES s.require_path = 'lib' - s.add_development_dependency 'permutation' s.add_development_dependency 'sdoc', '~>0.3.16' s.add_development_dependency 'rake', '~>0.9.2' @@ -125,7 +124,6 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.extensions = FileList['ext/**/extconf.rb'] s.require_path = 'lib' - s.add_development_dependency 'permutation' s.add_development_dependency 'sdoc', '~>0.3.16' s.extra_rdoc_files << 'README.rdoc' @@ -173,8 +171,12 @@ EOT end end +task :check_env do + ENV.key?('JSON') or fail "JSON env var is required" +end + desc "Testing library (pure ruby)" -task :test_pure => [ :clean, :do_test_pure ] +task :test_pure => [ :clean, :check_env, :do_test_pure ] UndocumentedTestTask.new do |t| t.name = 'do_test_pure' @@ -257,7 +259,7 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby' end desc "Testing library (jruby)" - task :test_ext => [ :create_jar, :do_test_ext ] + task :test_ext => [ :create_jar, :check_env, :do_test_ext ] UndocumentedTestTask.new do |t| t.name = 'do_test_ext' @@ -331,7 +333,7 @@ else end desc "Testing library (extension)" - task :test_ext => [ :compile, :do_test_ext ] + task :test_ext => [ :compile, :check_env, :do_test_ext ] UndocumentedTestTask.new do |t| t.name = 'do_test_ext' diff --git a/json.gemspec b/json.gemspec index 6add5d927f98e2a3e4320e59b35c12583a4e45d7..47678e70ae3bf4c6715ad49c2dce37da22b8a90d 100644 GIT binary patch delta 40 tcmX@2zDR9@0pH|Q0inq=`1m&m^Sx!BTqhI^#HN!igq47_(d0eC8~`J{4V3@@ delta 120 zcmZ3ac0_%H0Uu9sYDsB9d|6^qW@6stk9^{r1Nq)Eix;F8<(8HtmSpDV+36@mE7{p9 h7%0VRP8JuclENX!rJykRf{@qb!$PV!wVxLX1_0h(C))r3 diff --git a/json_pure.gemspec b/json_pure.gemspec index 180208d4d..eaa76a73b 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] - s.files = ["./tests/test_helper.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] + s.files = ["./tests/test_helper.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/test_helper.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] @@ -24,16 +24,13 @@ Gem::Specification.new do |s| s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, ["~> 0.3.16"]) if RUBY_VERSION > "1.8.6" s.add_development_dependency(%q, ["~> 0.9.2"]) else - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, ["~> 0.3.16"]) if RUBY_VERSION > "1.8.6" s.add_dependency(%q, ["~> 0.9.2"]) end else - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, ["~> 0.3.16"]) if RUBY_VERSION > "1.8.6" s.add_dependency(%q, ["~> 0.9.2"]) end diff --git a/tests/test_json.rb b/tests/test_json.rb index b666dfaf7..31624a350 100755 --- a/tests/test_json.rb +++ b/tests/test_json.rb @@ -6,20 +6,6 @@ require 'tempfile' require 'ostruct' -unless Array.method_defined?(:permutation) - begin - require 'enumerator' - require 'permutation' - class Array - def permutation - Permutation.for(self).to_enum.map { |x| x.project } - end - end - rescue LoadError - warn "Skipping permutation tests." - end -end - class TestJSON < Test::Unit::TestCase include JSON From 280005f5bc5e8e120f7ed717f7a86eaad2dae6b4 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Sat, 13 Jun 2015 12:45:28 +0200 Subject: [PATCH 089/312] Remove byte sniffing from Pure::Parser --- lib/json/pure/parser.rb | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index a41d1eeb1..9e40eb710 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -152,40 +152,8 @@ def convert_encoding(source) raise TypeError, "#{source.inspect} is not like a string" end if defined?(::Encoding) - if source.encoding == ::Encoding::ASCII_8BIT - b = source[0, 4].bytes.to_a - source = - case - when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0 - source.dup.force_encoding(::Encoding::UTF_32BE).encode!(::Encoding::UTF_8) - when b.size >= 4 && b[0] == 0 && b[2] == 0 - source.dup.force_encoding(::Encoding::UTF_16BE).encode!(::Encoding::UTF_8) - when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0 - source.dup.force_encoding(::Encoding::UTF_32LE).encode!(::Encoding::UTF_8) - when b.size >= 4 && b[1] == 0 && b[3] == 0 - source.dup.force_encoding(::Encoding::UTF_16LE).encode!(::Encoding::UTF_8) - else - source.dup - end - else - source = source.encode(::Encoding::UTF_8) - end + source = source.encode(::Encoding::UTF_8) source.force_encoding(::Encoding::ASCII_8BIT) - else - b = source - source = - case - when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0 - JSON.iconv('utf-8', 'utf-32be', b) - when b.size >= 4 && b[0] == 0 && b[2] == 0 - JSON.iconv('utf-8', 'utf-16be', b) - when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0 - JSON.iconv('utf-8', 'utf-32le', b) - when b.size >= 4 && b[1] == 0 && b[3] == 0 - JSON.iconv('utf-8', 'utf-16le', b) - else - b - end end source end From 4b843b585060212e8c396073f79627bf081491db Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Sat, 13 Jun 2015 12:55:29 +0200 Subject: [PATCH 090/312] =?UTF-8?q?Remove=20generate=20restriction=20for?= =?UTF-8?q?=20[=E2=80=A6]/{=E2=80=A6}?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ext/json/ext/generator/generator.c | 18 --------------- java/src/json/ext/GeneratorState.java | 32 --------------------------- lib/json/pure/generator.rb | 7 ------ tests/test_json_generate.rb | 12 +++------- 4 files changed, 3 insertions(+), 66 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 6300c64f3..0a3e92053 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -914,21 +914,6 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj) return fbuffer_to_s(buffer); } -/* - * This function returns true if string is either a JSON array or JSON object. - * It might suffer from false positives, e. g. syntactically incorrect JSON in - * the string or certain UTF-8 characters on the right hand side. - */ -static int isArrayOrObject(VALUE string) -{ - long string_len = RSTRING_LEN(string); - char *p = RSTRING_PTR(string), *q = p + string_len - 1; - if (string_len < 2) return 0; - for (; p < q && isspace((unsigned char)*p); p++); - for (; q > p && isspace((unsigned char)*q); q--); - return (*p == '[' && *q == ']') || (*p == '{' && *q == '}'); -} - /* * call-seq: generate(obj) * @@ -940,9 +925,6 @@ static VALUE cState_generate(VALUE self, VALUE obj) { VALUE result = cState_partial_generate(self, obj); GET_STATE(self); - if (!state->quirks_mode && !isArrayOrObject(result)) { - rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed"); - } return result; } diff --git a/java/src/json/ext/GeneratorState.java b/java/src/json/ext/GeneratorState.java index 30653074c..db4f3f5d3 100644 --- a/java/src/json/ext/GeneratorState.java +++ b/java/src/json/ext/GeneratorState.java @@ -208,10 +208,6 @@ public IRubyObject initialize_copy(ThreadContext context, IRubyObject vOrig) { @JRubyMethod public IRubyObject generate(ThreadContext context, IRubyObject obj) { RubyString result = Generator.generateJson(context, obj, this); - if (!quirksMode && !objectOrArrayLiteral(result)) { - throw Utils.newException(context, Utils.M_GENERATOR_ERROR, - "only generation of JSON objects or arrays allowed"); - } RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); if (info.encodingsSupported()) { result.force_encoding(context, info.utf8.get()); @@ -219,34 +215,6 @@ public IRubyObject generate(ThreadContext context, IRubyObject obj) { return result; } - /** - * Ensures the given string is in the form "[...]" or "{...}", being - * possibly surrounded by white space. - * The string's encoding must be ASCII-compatible. - * @param value - * @return - */ - private static boolean objectOrArrayLiteral(RubyString value) { - ByteList bl = value.getByteList(); - int len = bl.length(); - - for (int pos = 0; pos < len - 1; pos++) { - int b = bl.get(pos); - if (Character.isWhitespace(b)) continue; - - // match the opening brace - switch (b) { - case '[': - return matchClosingBrace(bl, pos, len, ']'); - case '{': - return matchClosingBrace(bl, pos, len, '}'); - default: - return false; - } - } - return false; - } - private static boolean matchClosingBrace(ByteList bl, int pos, int len, int brace) { for (int endPos = len - 1; endPos > pos; endPos--) { diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index 225081fb3..cb27e04cc 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -294,13 +294,6 @@ def generate(obj) result = obj.to_json(self) JSON.valid_utf8?(result) or raise GeneratorError, "source sequence #{result.inspect} is illegal/malformed utf-8" - unless @quirks_mode - unless result =~ /\A\s*\[/ && result =~ /\]\s*\Z/ || - result =~ /\A\s*\{/ && result =~ /\}\s*\Z/ - then - raise GeneratorError, "only generation of JSON objects or arrays allowed" - end - end result end diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index 2fe47601f..79c00af8d 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -50,8 +50,7 @@ def test_generate assert_equal('{"1":2}', json) parsed_json = parse(json) assert_equal({"1"=>2}, parsed_json) - assert_raise(GeneratorError) { generate(666) } - assert_equal '666', generate(666, :quirks_mode => true) + assert_equal '666', generate(666) end def test_generate_pretty @@ -68,8 +67,7 @@ def test_generate_pretty EOT parsed_json = parse(json) assert_equal({"1"=>2}, parsed_json) - assert_raise(GeneratorError) { pretty_generate(666) } - assert_equal '666', pretty_generate(666, :quirks_mode => true) + assert_equal '666', pretty_generate(666) end def test_generate_custom @@ -94,8 +92,7 @@ def test_fast_generate assert_equal('{"1":2}', json) parsed_json = parse(json) assert_equal({"1"=>2}, parsed_json) - assert_raise(GeneratorError) { fast_generate(666) } - assert_equal '666', fast_generate(666, :quirks_mode => true) + assert_equal '666', fast_generate(666) end def test_own_state @@ -108,9 +105,6 @@ def test_own_state assert_equal('{"1":2}', json) parsed_json = parse(json) assert_equal({"1"=>2}, parsed_json) - assert_raise(GeneratorError) { generate(666, state) } - state.quirks_mode = true - assert state.quirks_mode? assert_equal '666', generate(666, state) end From 0ece7a0404cebb8fb2ce4e6110e70fd05fb48d6b Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Sat, 13 Jun 2015 13:01:58 +0200 Subject: [PATCH 091/312] Remove byte sniffing from Ext::Parser --- ext/json/ext/parser/parser.c | 141 +++++++++++++--------------------- ext/json/ext/parser/parser.rl | 43 +---------- 2 files changed, 57 insertions(+), 127 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 9c9d76ac3..fb7ca455b 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -68,9 +68,9 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) } #ifdef HAVE_RUBY_ENCODING_H -static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE, - CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE; -static ID i_encoding, i_encode; +static VALUE CEncoding_UTF_8; + +static ID i_encode; #else static ID i_iconv; #endif @@ -89,11 +89,11 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, #line 92 "parser.c" -enum {JSON_object_start = 1}; -enum {JSON_object_first_final = 27}; -enum {JSON_object_error = 0}; +static const int JSON_object_start = 1; +static const int JSON_object_first_final = 27; +static const int JSON_object_error = 0; -enum {JSON_object_en_main = 1}; +static const int JSON_object_en_main = 1; #line 151 "parser.rl" @@ -467,11 +467,11 @@ case 26: #line 470 "parser.c" -enum {JSON_value_start = 1}; -enum {JSON_value_first_final = 21}; -enum {JSON_value_error = 0}; +static const int JSON_value_start = 1; +static const int JSON_value_first_final = 21; +static const int JSON_value_error = 0; -enum {JSON_value_en_main = 1}; +static const int JSON_value_en_main = 1; #line 271 "parser.rl" @@ -776,11 +776,11 @@ case 20: #line 779 "parser.c" -enum {JSON_integer_start = 1}; -enum {JSON_integer_first_final = 3}; -enum {JSON_integer_error = 0}; +static const int JSON_integer_start = 1; +static const int JSON_integer_first_final = 3; +static const int JSON_integer_error = 0; -enum {JSON_integer_en_main = 1}; +static const int JSON_integer_en_main = 1; #line 295 "parser.rl" @@ -875,11 +875,11 @@ case 5: #line 878 "parser.c" -enum {JSON_float_start = 1}; -enum {JSON_float_first_final = 8}; -enum {JSON_float_error = 0}; +static const int JSON_float_start = 1; +static const int JSON_float_first_final = 8; +static const int JSON_float_error = 0; -enum {JSON_float_en_main = 1}; +static const int JSON_float_en_main = 1; #line 329 "parser.rl" @@ -1041,11 +1041,11 @@ case 7: #line 1044 "parser.c" -enum {JSON_array_start = 1}; -enum {JSON_array_first_final = 17}; -enum {JSON_array_error = 0}; +static const int JSON_array_start = 1; +static const int JSON_array_first_final = 17; +static const int JSON_array_error = 0; -enum {JSON_array_en_main = 1}; +static const int JSON_array_en_main = 1; #line 381 "parser.rl" @@ -1373,11 +1373,11 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) #line 1376 "parser.c" -enum {JSON_string_start = 1}; -enum {JSON_string_first_final = 8}; -enum {JSON_string_error = 0}; +static const int JSON_string_start = 1; +static const int JSON_string_first_final = 8; +static const int JSON_string_error = 0; -enum {JSON_string_en_main = 1}; +static const int JSON_string_en_main = 1; #line 494 "parser.rl" @@ -1568,38 +1568,9 @@ static VALUE convert_encoding(VALUE source) { char *ptr = RSTRING_PTR(source); long len = RSTRING_LEN(source); - if (len < 2) { - rb_raise(eParserError, "A JSON text must at least contain two octets!"); - } #ifdef HAVE_RUBY_ENCODING_H { - VALUE encoding = rb_funcall(source, i_encoding, 0); - if (encoding == CEncoding_ASCII_8BIT) { - if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) { - source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32BE); - } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) { - source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE); - } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) { - source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32LE); - } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) { - source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE); - } else { - source = rb_str_dup(source); - FORCE_UTF8(source); - } - } else { - source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); - } - } -#else - if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) { - source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source); - } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) { - source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source); - } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) { - source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source); - } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) { - source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source); + source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); } #endif return source; @@ -1729,15 +1700,15 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1733 "parser.c" -enum {JSON_start = 1}; -enum {JSON_first_final = 10}; -enum {JSON_error = 0}; +#line 1704 "parser.c" +static const int JSON_start = 1; +static const int JSON_first_final = 10; +static const int JSON_error = 0; -enum {JSON_en_main = 1}; +static const int JSON_en_main = 1; -#line 740 "parser.rl" +#line 711 "parser.rl" static VALUE cParser_parse_strict(VALUE self) @@ -1748,16 +1719,16 @@ static VALUE cParser_parse_strict(VALUE self) GET_PARSER; -#line 1752 "parser.c" +#line 1723 "parser.c" { cs = JSON_start; } -#line 750 "parser.rl" +#line 721 "parser.rl" p = json->source; pe = p + json->len; -#line 1761 "parser.c" +#line 1732 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1813,7 +1784,7 @@ case 5: goto st1; goto st5; tr3: -#line 729 "parser.rl" +#line 700 "parser.rl" { char *np; json->current_nesting = 1; @@ -1822,7 +1793,7 @@ case 5: } goto st10; tr4: -#line 722 "parser.rl" +#line 693 "parser.rl" { char *np; json->current_nesting = 1; @@ -1834,7 +1805,7 @@ case 5: if ( ++p == pe ) goto _test_eof10; case 10: -#line 1838 "parser.c" +#line 1809 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1891,7 +1862,7 @@ case 9: _out: {} } -#line 753 "parser.rl" +#line 724 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -1903,15 +1874,15 @@ case 9: -#line 1907 "parser.c" -enum {JSON_quirks_mode_start = 1}; -enum {JSON_quirks_mode_first_final = 10}; -enum {JSON_quirks_mode_error = 0}; +#line 1878 "parser.c" +static const int JSON_quirks_mode_start = 1; +static const int JSON_quirks_mode_first_final = 10; +static const int JSON_quirks_mode_error = 0; -enum {JSON_quirks_mode_en_main = 1}; +static const int JSON_quirks_mode_en_main = 1; -#line 778 "parser.rl" +#line 749 "parser.rl" static VALUE cParser_parse_quirks_mode(VALUE self) @@ -1922,16 +1893,16 @@ static VALUE cParser_parse_quirks_mode(VALUE self) GET_PARSER; -#line 1926 "parser.c" +#line 1897 "parser.c" { cs = JSON_quirks_mode_start; } -#line 788 "parser.rl" +#line 759 "parser.rl" p = json->source; pe = p + json->len; -#line 1935 "parser.c" +#line 1906 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1965,7 +1936,7 @@ case 1: cs = 0; goto _out; tr2: -#line 770 "parser.rl" +#line 741 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1975,7 +1946,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1979 "parser.c" +#line 1950 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2064,7 +2035,7 @@ case 9: _out: {} } -#line 791 "parser.rl" +#line 762 "parser.rl" if (cs >= JSON_quirks_mode_first_final && p == pe) { return result; @@ -2195,12 +2166,6 @@ void Init_parser(void) i_leftshift = rb_intern("<<"); #ifdef HAVE_RUBY_ENCODING_H CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8")); - CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be")); - CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le")); - CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be")); - CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le")); - CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit")); - i_encoding = rb_intern("encoding"); i_encode = rb_intern("encode"); #else i_iconv = rb_intern("iconv"); diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index 216ad26b2..a34245eb9 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -66,9 +66,9 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) } #ifdef HAVE_RUBY_ENCODING_H -static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE, - CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE; -static ID i_encoding, i_encode; +static VALUE CEncoding_UTF_8; + +static ID i_encode; #else static ID i_iconv; #endif @@ -552,38 +552,9 @@ static VALUE convert_encoding(VALUE source) { char *ptr = RSTRING_PTR(source); long len = RSTRING_LEN(source); - if (len < 2) { - rb_raise(eParserError, "A JSON text must at least contain two octets!"); - } #ifdef HAVE_RUBY_ENCODING_H { - VALUE encoding = rb_funcall(source, i_encoding, 0); - if (encoding == CEncoding_ASCII_8BIT) { - if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) { - source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32BE); - } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) { - source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE); - } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) { - source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32LE); - } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) { - source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE); - } else { - source = rb_str_dup(source); - FORCE_UTF8(source); - } - } else { - source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); - } - } -#else - if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) { - source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source); - } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) { - source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source); - } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) { - source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source); - } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) { - source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source); + source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); } #endif return source; @@ -918,12 +889,6 @@ void Init_parser(void) i_leftshift = rb_intern("<<"); #ifdef HAVE_RUBY_ENCODING_H CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8")); - CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be")); - CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le")); - CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be")); - CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le")); - CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit")); - i_encoding = rb_intern("encoding"); i_encode = rb_intern("encode"); #else i_iconv = rb_intern("iconv"); From 6f907a9142e83141a2e01fdddfd18b2013244cd6 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 15 Jun 2015 10:06:27 +0200 Subject: [PATCH 092/312] Refactor tests and make pure parser green --- VERSION | 2 +- json.gemspec | Bin 4898 -> 4423 bytes json_pure.gemspec | 10 +- lib/json/common.rb | 20 +- lib/json/pure/parser.rb | 51 +- lib/json/version.rb | 2 +- tests/fixtures/fail1.json | 1 - tests/fixtures/obsolete_fail1.json | 1 + ...json_addition.rb => json_addition_test.rb} | 41 +- tests/json_common_interface_test.rb | 101 ++++ tests/json_encoding_test.rb | 109 ++++ tests/json_ext_parser_test.rb | 17 + ...json_fixtures.rb => json_fixtures_test.rb} | 7 +- ...son_generate.rb => json_generator_test.rb} | 59 +- ..._object.rb => json_generic_object_test.rb} | 20 +- tests/json_parser_test.rb | 433 ++++++++++++++ tests/json_string_matching_test.rb | 37 ++ tests/test_helper.rb | 1 - tests/test_json.rb | 538 ------------------ tests/test_json_encoding.rb | 64 --- tests/test_json_string_matching.rb | 38 -- tests/test_json_unicode.rb | 71 --- 22 files changed, 813 insertions(+), 810 deletions(-) delete mode 100644 tests/fixtures/fail1.json create mode 100644 tests/fixtures/obsolete_fail1.json rename tests/{test_json_addition.rb => json_addition_test.rb} (79%) mode change 100755 => 100644 create mode 100644 tests/json_common_interface_test.rb create mode 100644 tests/json_encoding_test.rb create mode 100644 tests/json_ext_parser_test.rb rename tests/{test_json_fixtures.rb => json_fixtures_test.rb} (84%) mode change 100755 => 100644 rename tests/{test_json_generate.rb => json_generator_test.rb} (85%) mode change 100755 => 100644 rename tests/{test_json_generic_object.rb => json_generic_object_test.rb} (81%) create mode 100644 tests/json_parser_test.rb create mode 100644 tests/json_string_matching_test.rb delete mode 100755 tests/test_json.rb delete mode 100644 tests/test_json_encoding.rb delete mode 100644 tests/test_json_string_matching.rb delete mode 100755 tests/test_json_unicode.rb diff --git a/VERSION b/VERSION index a7ee35a3e..227cea215 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8.3 +2.0.0 diff --git a/json.gemspec b/json.gemspec index 47678e70ae3bf4c6715ad49c2dce37da22b8a90d..75f1ae960a2da154e81c697ff88c8b066106b2b0 100644 GIT binary patch delta 357 zcmZ3ac3f$KI;)YMfu6xco#jx*jeU%!o2N5sF>XG?e1~oGQLd#-eECVm`8la2sqtxv znK_1&KXOY<&f+~*pH-Zn7oV7tl39`oWR#>9m*^EGDd{LEftbbmVCm%i++3h!W?o5Z zQCebhDh_3-dCB=HnR)5Bq$^6|3lfWpQ;U!k)Fa!ImRV6!T9jIhB#$heo|>0hlvt9F ztRF)@GdVs#DJwO(1cxDLF5rawbn*md5f+f9$shTICua!oZnot&W!zjVxRen9t2~1= delta 786 zcmX@Ev`B4&I;)|cg`V+5o#jx*jeU&9o2N5sG1lvsq!yPHgUR@;;`}_lq9i391tmRn z@%Y4)l+2P$JPK0tlJiqC^U`sekd|3dQd*Q+jI2Np+3xuC)V$Q9#FA8G6(|ZO3vh}$ zV!ExkqzGtnd~RY%at1yZl;&ju-I%(0C({$Q$&TDIo9A#YW15`7b8K=npKv|afItf# z^k6`jMhgUVX|y0fkygsjLk|EHd7w1N`?lzU*gcP~3g-1RJ{!h*Y!Qqz%&8yoMi_~U LUJ*Z!e= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2015-06-13" + s.date = "2015-06-15" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] - s.files = ["./tests/test_helper.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/test_helper.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] + s.files = ["./tests/test_helper.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/obsolete_fail1.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/json_addition_test.rb", "tests/json_common_interface_test.rb", "tests/json_encoding_test.rb", "tests/json_ext_parser_test.rb", "tests/json_fixtures_test.rb", "tests/json_generator_test.rb", "tests/json_generic_object_test.rb", "tests/json_parser_test.rb", "tests/json_string_matching_test.rb", "tests/test_helper.rb", "tools/fuzz.rb", "tools/server.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] s.rubygems_version = "2.4.6" s.summary = "JSON Implementation for Ruby" - s.test_files = ["./tests/test_helper.rb", "./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] + s.test_files = ["./tests/test_helper.rb"] if s.respond_to? :specification_version then s.specification_version = 4 diff --git a/lib/json/common.rb b/lib/json/common.rb index f44184e13..1215d41ba 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -3,12 +3,12 @@ module JSON class << self - # If _object_ is string-like, parse the string and return the parsed result - # as a Ruby data structure. Otherwise generate a JSON text from the Ruby - # data structure object and return it. + # If _object_ is string-like, parse the string and return the parsed + # result as a Ruby data structure. Otherwise generate a JSON text from the + # Ruby data structure object and return it. # - # The _opts_ argument is passed through to generate/parse respectively. See - # generate and parse for their documentation. + # The _opts_ argument is passed through to generate/parse respectively. + # See generate and parse for their documentation. def [](object, opts = {}) if object.respond_to? :to_str JSON.parse(object.to_str, opts) @@ -138,8 +138,8 @@ class MissingUnicodeSupport < JSONError; end # _opts_ can have the following # keys: # * *max_nesting*: The maximum depth of nesting allowed in the parsed data - # structures. Disable depth checking with :max_nesting => false. It defaults - # to 100. + # structures. Disable depth checking with :max_nesting => false. It + # defaults to 100. # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in # defiance of RFC 4627 to be parsed by the Parser. This option defaults # to false. @@ -161,9 +161,9 @@ def parse(source, opts = {}) # # _opts_ can have the following keys: # * *max_nesting*: The maximum depth of nesting allowed in the parsed data - # structures. Enable depth checking with :max_nesting => anInteger. The parse! - # methods defaults to not doing max depth checking: This can be dangerous - # if someone wants to fill up your stack. + # structures. Enable depth checking with :max_nesting => anInteger. The + # parse! methods defaults to not doing max depth checking: This can be + # dangerous if someone wants to fill up your stack. # * *allow_nan*: If set to true, allow NaN, Infinity, and -Infinity in # defiance of RFC 4627 to be parsed by the Parser. This option defaults # to true. diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index 9e40eb710..acabe39cd 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -48,7 +48,7 @@ class Parser < StringScanner )+ )mx - UNPARSED = Object.new + UNPARSED = Object.new.freeze # Creates a new JSON::Pure::Parser instance for the string _source_. # @@ -107,39 +107,21 @@ def reset @current_nesting = 0 end - # Parses the current JSON string _source_ and returns the complete data - # structure as a result. + # Parses the current JSON string _source_ and returns the + # complete data structure as a result. def parse reset obj = nil - if @quirks_mode - while !eos? && skip(IGNORE) - end - if eos? - raise ParserError, "source did not contain any JSON!" - else - obj = parse_value - obj == UNPARSED and raise ParserError, "source did not contain any JSON!" - end + while !eos? && skip(IGNORE) do end + if eos? + raise ParserError, "source is not valid JSON!" else - until eos? - case - when scan(OBJECT_OPEN) - obj and raise ParserError, "source '#{peek(20)}' not in JSON!" - @current_nesting = 1 - obj = parse_object - when scan(ARRAY_OPEN) - obj and raise ParserError, "source '#{peek(20)}' not in JSON!" - @current_nesting = 1 - obj = parse_array - when skip(IGNORE) - ; - else - raise ParserError, "source '#{peek(20)}' not in JSON!" - end - end - obj or raise ParserError, "source did not contain any JSON!" + obj = parse_value + UNPARSED.equal?(obj) and raise ParserError, + "source is not valid JSON!" end + while !eos? && skip(IGNORE) do end + eos? or raise ParserError, "source is not valid JSON!" obj end @@ -149,7 +131,8 @@ def convert_encoding(source) if source.respond_to?(:to_str) source = source.to_str else - raise TypeError, "#{source.inspect} is not like a string" + raise TypeError, + "#{source.inspect} is not like a string" end if defined?(::Encoding) source = source.encode(::Encoding::UTF_8) @@ -222,7 +205,7 @@ def parse_value false when scan(NULL) nil - when (string = parse_string) != UNPARSED + when !UNPARSED.equal?(string = parse_string) string when scan(ARRAY_OPEN) @current_nesting += 1 @@ -252,7 +235,7 @@ def parse_array delim = false until eos? case - when (value = parse_value) != UNPARSED + when !UNPARSED.equal?(value = parse_value) delim = false result << value skip(IGNORE) @@ -284,13 +267,13 @@ def parse_object delim = false until eos? case - when (string = parse_string) != UNPARSED + when !UNPARSED.equal?(string = parse_string) skip(IGNORE) unless scan(PAIR_DELIMITER) raise ParserError, "expected ':' in object at '#{peek(20)}'!" end skip(IGNORE) - unless (value = parse_value).equal? UNPARSED + unless UNPARSED.equal?(value = parse_value) result[@symbolize_names ? string.to_sym : string] = value delim = false skip(IGNORE) diff --git a/lib/json/version.rb b/lib/json/version.rb index 5a4013dbf..b91ccd708 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.8.3' + VERSION = '2.0.0' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: diff --git a/tests/fixtures/fail1.json b/tests/fixtures/fail1.json deleted file mode 100644 index 6216b865f..000000000 --- a/tests/fixtures/fail1.json +++ /dev/null @@ -1 +0,0 @@ -"A JSON payload should be an object or array, not a string." \ No newline at end of file diff --git a/tests/fixtures/obsolete_fail1.json b/tests/fixtures/obsolete_fail1.json new file mode 100644 index 000000000..98b77de6a --- /dev/null +++ b/tests/fixtures/obsolete_fail1.json @@ -0,0 +1 @@ +"A JSON payload should be an object or array, not a string." diff --git a/tests/test_json_addition.rb b/tests/json_addition_test.rb old mode 100755 new mode 100644 similarity index 79% rename from tests/test_json_addition.rb rename to tests/json_addition_test.rb index 110570541..128f34a41 --- a/tests/test_json_addition.rb +++ b/tests/json_addition_test.rb @@ -1,6 +1,3 @@ -#!/usr/bin/env ruby -# -*- coding:utf-8 -*- - require 'test_helper' require 'json/add/core' require 'json/add/complex' @@ -9,7 +6,7 @@ require 'json/add/ostruct' require 'date' -class TestJSONAddition < Test::Unit::TestCase +class JSONAdditionTest < Test::Unit::TestCase include JSON class A @@ -63,7 +60,7 @@ def self.json_creatable? def to_json(*args) { - 'json_class' => 'TestJSONAddition::Nix', + 'json_class' => 'JSONAdditionTest::Nix', }.to_json(*args) end end @@ -72,7 +69,7 @@ def test_extended_json a = A.new(666) assert A.json_creatable? json = generate(a) - a_again = JSON.parse(json, :create_additions => true) + a_again = parse(json, :create_additions => true) assert_kind_of a.class, a_again assert_equal a, a_again end @@ -81,7 +78,7 @@ def test_extended_json_default a = A.new(666) assert A.json_creatable? json = generate(a) - a_hash = JSON.parse(json) + a_hash = parse(json) assert_kind_of Hash, a_hash end @@ -89,13 +86,13 @@ def test_extended_json_disabled a = A.new(666) assert A.json_creatable? json = generate(a) - a_again = JSON.parse(json, :create_additions => true) + a_again = parse(json, :create_additions => true) assert_kind_of a.class, a_again assert_equal a, a_again - a_hash = JSON.parse(json, :create_additions => false) + a_hash = parse(json, :create_additions => false) assert_kind_of Hash, a_hash assert_equal( - {"args"=>[666], "json_class"=>"TestJSONAddition::A"}.sort_by { |k,| k }, + {"args"=>[666], "json_class"=>"JSONAdditionTest::A"}.sort_by { |k,| k }, a_hash.sort_by { |k,| k } ) end @@ -104,14 +101,14 @@ def test_extended_json_fail1 b = B.new assert !B.json_creatable? json = generate(b) - assert_equal({ "json_class"=>"TestJSONAddition::B" }, JSON.parse(json)) + assert_equal({ "json_class"=>"JSONAdditionTest::B" }, parse(json)) end def test_extended_json_fail2 c = C.new assert !C.json_creatable? json = generate(c) - assert_raises(ArgumentError, NameError) { JSON.parse(json, :create_additions => true) } + assert_raises(ArgumentError, NameError) { parse(json, :create_additions => true) } end def test_raw_strings @@ -129,7 +126,7 @@ def test_raw_strings assert_match(/\A\{.*\}\z/, json) assert_match(/"json_class":"String"/, json) assert_match(/"raw":\[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255\]/, json) - raw_again = JSON.parse(json, :create_additions => true) + raw_again = parse(json, :create_additions => true) assert_equal raw, raw_again end @@ -166,19 +163,19 @@ def test_core def test_utc_datetime now = Time.now - d = DateTime.parse(now.to_s, :create_additions => true) # usual case - assert_equal d, JSON.parse(d.to_json, :create_additions => true) - d = DateTime.parse(now.utc.to_s) # of = 0 - assert_equal d, JSON.parse(d.to_json, :create_additions => true) + d = DateTime.parse(now.to_s, :create_additions => true) # usual case + assert_equal d, parse(d.to_json, :create_additions => true) + d = DateTime.parse(now.utc.to_s) # of = 0 + assert_equal d, parse(d.to_json, :create_additions => true) d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(1,24)) - assert_equal d, JSON.parse(d.to_json, :create_additions => true) + assert_equal d, parse(d.to_json, :create_additions => true) d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(12,24)) - assert_equal d, JSON.parse(d.to_json, :create_additions => true) + assert_equal d, parse(d.to_json, :create_additions => true) end def test_rational_complex - assert_equal Rational(2, 9), JSON.parse(JSON(Rational(2, 9)), :create_additions => true) - assert_equal Complex(2, 9), JSON.parse(JSON(Complex(2, 9)), :create_additions => true) + assert_equal Rational(2, 9), parse(JSON(Rational(2, 9)), :create_additions => true) + assert_equal Complex(2, 9), parse(JSON(Complex(2, 9)), :create_additions => true) end def test_bigdecimal @@ -190,6 +187,6 @@ def test_ostruct o = OpenStruct.new # XXX this won't work; o.foo = { :bar => true } o.foo = { 'bar' => true } - assert_equal o, JSON.parse(JSON(o), :create_additions => true) + assert_equal o, parse(JSON(o), :create_additions => true) end end diff --git a/tests/json_common_interface_test.rb b/tests/json_common_interface_test.rb new file mode 100644 index 000000000..1fca19dbf --- /dev/null +++ b/tests/json_common_interface_test.rb @@ -0,0 +1,101 @@ +require 'test_helper' +require 'stringio' +require 'tempfile' + +class JSONParserTest < Test::Unit::TestCase + include JSON + + def setup + @hash = { + 'a' => 2, + 'b' => 3.141, + 'c' => 'c', + 'd' => [ 1, "b", 3.14 ], + 'e' => { 'foo' => 'bar' }, + 'g' => "\"\0\037", + 'h' => 1000.0, + 'i' => 0.001 + } + @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\ + '"g":"\\"\\u0000\\u001f","h":1.0E3,"i":1.0E-3}' + end + + + def test_index + end + + def test_parser + end + + def test_generator + end + + def test_state + end + + def test_create_id + end + + def test_parse + end + + def test_parse_bang + end + + def test_generate + end + + def test_fast_generate + end + + def test_pretty_generate + end + + def test_load + assert_equal @hash, JSON.load(@json) + tempfile = Tempfile.open('@json') + tempfile.write @json + tempfile.rewind + assert_equal @hash, JSON.load(tempfile) + stringio = StringIO.new(@json) + stringio.rewind + assert_equal @hash, JSON.load(stringio) + assert_equal nil, JSON.load(nil) + assert_equal nil, JSON.load('') + ensure + tempfile.close! + end + + def test_load_with_options + small_hash = JSON("foo" => 'bar') + symbol_hash = { :foo => 'bar' } + assert_equal symbol_hash, + JSON.load(small_hash, nil, :symbolize_names => true) + end + + def test_dump + too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]' + assert_equal too_deep, dump(eval(too_deep)) + assert_kind_of String, Marshal.dump(eval(too_deep)) + assert_raises(ArgumentError) { dump(eval(too_deep), 100) } + assert_raises(ArgumentError) { Marshal.dump(eval(too_deep), 100) } + assert_equal too_deep, dump(eval(too_deep), 101) + assert_kind_of String, Marshal.dump(eval(too_deep), 101) + output = StringIO.new + dump(eval(too_deep), output) + assert_equal too_deep, output.string + output = StringIO.new + dump(eval(too_deep), output, 101) + assert_equal too_deep, output.string + end + + def test_dump_should_modify_defaults + max_nesting = JSON.dump_default_options[:max_nesting] + dump([], StringIO.new, 10) + assert_equal max_nesting, JSON.dump_default_options[:max_nesting] + end + + + def test_JSON + end +end diff --git a/tests/json_encoding_test.rb b/tests/json_encoding_test.rb new file mode 100644 index 000000000..86335a1c7 --- /dev/null +++ b/tests/json_encoding_test.rb @@ -0,0 +1,109 @@ +require 'test_helper' + +class JSONEncodingTest < Test::Unit::TestCase + include JSON + + def setup + @utf_8 = '"© ≠ €!"' + @parsed = "© ≠ €!" + @generated = '"\u00a9 \u2260 \u20ac!"' + if String.method_defined?(:encode) + @utf_16_data = @parsed.encode('utf-16be', 'utf-8') + @utf_16be = @utf_8.encode('utf-16be', 'utf-8') + @utf_16le = @utf_8.encode('utf-16le', 'utf-8') + @utf_32be = @utf_8.encode('utf-32be', 'utf-8') + @utf_32le = @utf_8.encode('utf-32le', 'utf-8') + else + require 'iconv' + @utf_16_data, = Iconv.iconv('utf-16be', 'utf-8', @parsed) + @utf_16be, = Iconv.iconv('utf-16be', 'utf-8', @utf_8) + @utf_16le, = Iconv.iconv('utf-16le', 'utf-8', @utf_8) + @utf_32be, = Iconv.iconv('utf-32be', 'utf-8', @utf_8) + @utf_32le, = Iconv.iconv('utf-32le', 'utf-8', @utf_8) + end + end + + def test_parse + assert_equal @parsed, JSON.parse(@utf_8) + assert_equal @parsed, JSON.parse(@utf_16be) + assert_equal @parsed, JSON.parse(@utf_16le) + assert_equal @parsed, JSON.parse(@utf_32be) + assert_equal @parsed, JSON.parse(@utf_32le) + end + + def test_generate + assert_equal @generated, JSON.generate(@parsed, :ascii_only => true) + if defined?(::Encoding) + assert_equal @generated, JSON.generate(@utf_16_data, :ascii_only => true) + else + # XXX checking of correct utf8 data is not as strict (yet?) without + # :ascii_only + assert_raises(JSON::GeneratorError) do + JSON.generate(@utf_16_data, :ascii_only => true) + end + end + end + + def test_unicode + assert_equal '""', ''.to_json + assert_equal '"\\b"', "\b".to_json + assert_equal '"\u0001"', 0x1.chr.to_json + assert_equal '"\u001f"', 0x1f.chr.to_json + assert_equal '" "', ' '.to_json + assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json + utf8 = [ "© ≠ €! \01" ] + json = '["© ≠ €! \u0001"]' + assert_equal json, utf8.to_json(:ascii_only => false) + assert_equal utf8, parse(json) + json = '["\u00a9 \u2260 \u20ac! \u0001"]' + assert_equal json, utf8.to_json(:ascii_only => true) + assert_equal utf8, parse(json) + utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"] + json = "[\"\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212\"]" + assert_equal utf8, parse(json) + assert_equal json, utf8.to_json(:ascii_only => false) + utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"] + assert_equal utf8, parse(json) + json = "[\"\\u3042\\u3044\\u3046\\u3048\\u304a\"]" + assert_equal json, utf8.to_json(:ascii_only => true) + assert_equal utf8, parse(json) + utf8 = ['საქართველო'] + json = '["საქართველო"]' + assert_equal json, utf8.to_json(:ascii_only => false) + json = "[\"\\u10e1\\u10d0\\u10e5\\u10d0\\u10e0\\u10d7\\u10d5\\u10d4\\u10da\\u10dd\"]" + assert_equal json, utf8.to_json(:ascii_only => true) + assert_equal utf8, parse(json) + assert_equal '["Ã"]', generate(["Ã"], :ascii_only => false) + assert_equal '["\\u00c3"]', generate(["Ã"], :ascii_only => true) + assert_equal ["€"], parse('["\u20ac"]') + utf8 = ["\xf0\xa0\x80\x81"] + json = "[\"\xf0\xa0\x80\x81\"]" + assert_equal json, generate(utf8, :ascii_only => false) + assert_equal utf8, parse(json) + json = '["\ud840\udc01"]' + assert_equal json, generate(utf8, :ascii_only => true) + assert_equal utf8, parse(json) + end + + def test_chars + (0..0x7f).each do |i| + json = '["\u%04x"]' % i + if RUBY_VERSION >= "1.9." + i = i.chr + end + assert_equal i, parse(json).first[0] + if i == ?\b + generated = generate(["" << i]) + assert '["\b"]' == generated || '["\10"]' == generated + elsif [?\n, ?\r, ?\t, ?\f].include?(i) + assert_equal '[' << ('' << i).dump << ']', generate(["" << i]) + elsif i.chr < 0x20.chr + assert_equal json, generate(["" << i]) + end + end + assert_raise(JSON::GeneratorError) do + generate(["\x80"], :ascii_only => true) + end + assert_equal "\302\200", parse('["\u0080"]').first + end +end diff --git a/tests/json_ext_parser_test.rb b/tests/json_ext_parser_test.rb new file mode 100644 index 000000000..da3bdc156 --- /dev/null +++ b/tests/json_ext_parser_test.rb @@ -0,0 +1,17 @@ +require 'test_helper' +require 'stringio' +require 'tempfile' +require 'ostruct' + +class JSONExtParserTest < Test::Unit::TestCase + if defined?(JSON::Ext::Parser) + def test_allocate + parser = JSON::Ext::Parser.new("{}") + assert_raise(TypeError, '[ruby-core:35079]') do + parser.__send__(:initialize, "{}") + end + parser = JSON::Ext::Parser.allocate + assert_raise(TypeError, '[ruby-core:35079]') { parser.source } + end + end +end diff --git a/tests/test_json_fixtures.rb b/tests/json_fixtures_test.rb old mode 100755 new mode 100644 similarity index 84% rename from tests/test_json_fixtures.rb rename to tests/json_fixtures_test.rb index d580522ad..6681b8d82 --- a/tests/test_json_fixtures.rb +++ b/tests/json_fixtures_test.rb @@ -1,11 +1,8 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - require 'test_helper' -class TestJSONFixtures < Test::Unit::TestCase +class JSONFixturesTest < Test::Unit::TestCase def setup - fixtures = File.join(File.dirname(__FILE__), 'fixtures/*.json') + fixtures = File.join(File.dirname(__FILE__), 'fixtures/{fail,pass}.json') passed, failed = Dir[fixtures].partition { |f| f['pass'] } @passed = passed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort @failed = failed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort diff --git a/tests/test_json_generate.rb b/tests/json_generator_test.rb old mode 100755 new mode 100644 similarity index 85% rename from tests/test_json_generate.rb rename to tests/json_generator_test.rb index 79c00af8d..7e487d88e --- a/tests/test_json_generate.rb +++ b/tests/json_generator_test.rb @@ -1,9 +1,6 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - require 'test_helper' -class TestJSONGenerate < Test::Unit::TestCase +class JSONGeneratorTest < Test::Unit::TestCase include JSON def setup @@ -41,9 +38,9 @@ def setup def test_generate json = generate(@hash) - assert_equal(JSON.parse(@json2), JSON.parse(json)) + assert_equal(parse(@json2), parse(json)) json = JSON[@hash] - assert_equal(JSON.parse(@json2), JSON.parse(json)) + assert_equal(parse(@json2), parse(json)) parsed_json = parse(json) assert_equal(@hash, parsed_json) json = generate({1=>2}) @@ -55,8 +52,9 @@ def test_generate def test_generate_pretty json = pretty_generate(@hash) - # hashes aren't (insertion) ordered on every ruby implementation assert_equal(@json3, json) - assert_equal(JSON.parse(@json3), JSON.parse(json)) + # hashes aren't (insertion) ordered on every ruby implementation + # assert_equal(@json3, json) + assert_equal(parse(@json3), parse(json)) parsed_json = parse(json) assert_equal(@hash, parsed_json) json = pretty_generate({1=>2}) @@ -85,7 +83,7 @@ def test_generate_custom def test_fast_generate json = fast_generate(@hash) - assert_equal(JSON.parse(@json2), JSON.parse(json)) + assert_equal(parse(@json2), parse(json)) parsed_json = parse(json) assert_equal(@hash, parsed_json) json = fast_generate({1=>2}) @@ -98,7 +96,7 @@ def test_fast_generate def test_own_state state = State.new json = generate(@hash, state) - assert_equal(JSON.parse(@json2), JSON.parse(json)) + assert_equal(parse(@json2), parse(json)) parsed_json = parse(json) assert_equal(@hash, parsed_json) json = generate({1=>2}, state) @@ -198,7 +196,7 @@ def test_allow_nan def test_depth ary = []; ary << ary assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth - assert_raises(JSON::NestingError) { JSON.generate(ary) } + assert_raises(JSON::NestingError) { generate(ary) } assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth assert_raises(JSON::NestingError) { JSON.pretty_generate(ary) } @@ -324,7 +322,44 @@ def test_hash_likeness_set_string def test_json_generate assert_raise JSON::GeneratorError do - assert_equal true, JSON.generate(["\xea"]) + assert_equal true, generate(["\xea"]) end end + + def test_nesting + too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]' + too_deep_ary = eval too_deep + assert_raises(JSON::NestingError) { generate too_deep_ary } + assert_raises(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 } + ok = generate too_deep_ary, :max_nesting => 101 + assert_equal too_deep, ok + ok = generate too_deep_ary, :max_nesting => nil + assert_equal too_deep, ok + ok = generate too_deep_ary, :max_nesting => false + assert_equal too_deep, ok + ok = generate too_deep_ary, :max_nesting => 0 + assert_equal too_deep, ok + end + + def test_backslash + data = [ '\\.(?i:gif|jpe?g|png)$' ] + json = '["\\\\.(?i:gif|jpe?g|png)$"]' + assert_equal json, generate(data) + # + data = [ '\\"' ] + json = '["\\\\\""]' + assert_equal json, generate(data) + # + data = [ '/' ] + json = '["/"]' + assert_equal json, generate(data) + # + data = ['"'] + json = '["\""]' + assert_equal json, generate(data) + # + data = ["'"] + json = '["\\\'"]' + assert_equal '["\'"]', generate(data) + end end diff --git a/tests/test_json_generic_object.rb b/tests/json_generic_object_test.rb similarity index 81% rename from tests/test_json_generic_object.rb rename to tests/json_generic_object_test.rb index 66fc18d3a..171fdb853 100644 --- a/tests/test_json_generic_object.rb +++ b/tests/json_generic_object_test.rb @@ -1,9 +1,6 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - require 'test_helper' -class TestJSONGenericObject < Test::Unit::TestCase +class JSONGenericObjectTest < Test::Unit::TestCase include JSON def setup @@ -26,11 +23,20 @@ def test_generate_json end def test_parse_json - assert_kind_of Hash, JSON('{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }', :create_additions => true) + assert_kind_of Hash, + JSON( + '{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }', + :create_additions => true + ) switch_json_creatable do - assert_equal @go, l = JSON('{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }', :create_additions => true) + assert_equal @go, l = + JSON( + '{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }', + :create_additions => true + ) assert_equal 1, l.a - assert_equal @go, l = JSON('{ "a": 1, "b": 2 }', :object_class => GenericObject) + assert_equal @go, + l = JSON('{ "a": 1, "b": 2 }', :object_class => GenericObject) assert_equal 1, l.a assert_equal GenericObject[:a => GenericObject[:b => 2]], l = JSON('{ "a": { "b": 2 } }', :object_class => GenericObject) diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb new file mode 100644 index 000000000..6755e6b74 --- /dev/null +++ b/tests/json_parser_test.rb @@ -0,0 +1,433 @@ +require 'test_helper' +require 'stringio' +require 'tempfile' +require 'ostruct' + +class JSONParserTest < Test::Unit::TestCase + include JSON + + def test_construction + parser = JSON::Parser.new('test') + assert_equal 'test', parser.source + end + + def test_argument_encoding + source = "{}".encode("UTF-16") + JSON::Parser.new(source) + assert_equal Encoding::UTF_16, source.encoding + end if defined?(Encoding::UTF_16) + + def test_parsing + parser = JSON::Parser.new('"test"') + assert_equal 'test', parser.parse + end + + def test_parser_reset + parser = Parser.new('{"a":"b"}') + assert_equal({ 'a' => 'b' }, parser.parse) + assert_equal({ 'a' => 'b' }, parser.parse) + end + + def test_parse_simple_arrays + assert_equal([], parse('[]')) + assert_equal([], parse(' [ ] ')) + assert_equal([ nil ], parse('[null]')) + assert_equal([ false ], parse('[false]')) + assert_equal([ true ], parse('[true]')) + assert_equal([ -23 ], parse('[-23]')) + assert_equal([ 23 ], parse('[23]')) + assert_equal_float([ 0.23 ], parse('[0.23]')) + assert_equal_float([ 0.0 ], parse('[0e0]')) + assert_equal([""], parse('[""]')) + assert_equal(["foobar"], parse('["foobar"]')) + assert_equal([{}], parse('[{}]')) + end + + def test_parse_simple_objects + assert_equal({}, parse('{}')) + assert_equal({}, parse(' { } ')) + assert_equal({ "a" => nil }, parse('{ "a" : null}')) + assert_equal({ "a" => nil }, parse('{"a":null}')) + assert_equal({ "a" => false }, parse('{ "a" : false } ')) + assert_equal({ "a" => false }, parse('{"a":false}')) + assert_raises(JSON::ParserError) { parse('{false}') } + assert_equal({ "a" => true }, parse('{"a":true}')) + assert_equal({ "a" => true }, parse(' { "a" : true } ')) + assert_equal({ "a" => -23 }, parse(' { "a" : -23 } ')) + assert_equal({ "a" => -23 }, parse(' { "a" : -23 } ')) + assert_equal({ "a" => 23 }, parse('{"a":23 } ')) + assert_equal({ "a" => 23 }, parse(' { "a" : 23 } ')) + assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } ')) + assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } ')) + end + + def test_parse_numbers + assert_raises(JSON::ParserError) { parse('+23.2') } + assert_raises(JSON::ParserError) { parse('+23') } + assert_raises(JSON::ParserError) { parse('.23') } + assert_raises(JSON::ParserError) { parse('023') } + assert_equal 23, parse('23') + assert_equal -23, parse('-23') + assert_equal_float 3.141, parse('3.141') + assert_equal_float -3.141, parse('-3.141') + assert_equal_float 3.141, parse('3141e-3') + assert_equal_float 3.141, parse('3141.1e-3') + assert_equal_float 3.141, parse('3141E-3') + assert_equal_float 3.141, parse('3141.0E-3') + assert_equal_float -3.141, parse('-3141.0e-3') + assert_equal_float -3.141, parse('-3141e-3') + assert_raises(ParserError) { parse('NaN') } + assert parse('NaN', :allow_nan => true).nan? + assert_raises(ParserError) { parse('Infinity') } + assert_equal 1.0/0, parse('Infinity', :allow_nan => true) + assert_raises(ParserError) { parse('-Infinity') } + assert_equal -1.0/0, parse('-Infinity', :allow_nan => true) + end + + if Array.method_defined?(:permutation) + def test_parse_more_complex_arrays + a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }] + a.permutation.each do |perm| + json = pretty_generate(perm) + assert_equal perm, parse(json) + end + end + + def test_parse_complex_objects + a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }] + a.permutation.each do |perm| + s = "a" + orig_obj = perm.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h } + json = pretty_generate(orig_obj) + assert_equal orig_obj, parse(json) + end + end + end + + def test_parse_arrays + assert_equal([1,2,3], parse('[1,2,3]')) + assert_equal([1.2,2,3], parse('[1.2,2,3]')) + assert_equal([[],[[],[]]], parse('[[],[[],[]]]')) + assert_equal([], parse('[]')) + assert_equal([], parse(' [ ] ')) + assert_equal([1], parse('[1]')) + assert_equal([1], parse(' [ 1 ] ')) + ary = [[1], ["foo"], [3.14], [4711.0], [2.718], [nil], + [[1, -2, 3]], [false], [true]] + assert_equal(ary, + parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]],[false],[true]]')) + assert_equal(ary, parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]\s + , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] })) + end + + def test_parse_json_primitive_values + assert_raise(JSON::ParserError) { parse('') } + assert_raise(TypeError) { parse(nil) } + assert_raise(JSON::ParserError) { parse(' /* foo */ ') } + assert_equal nil, parse('null') + assert_equal false, parse('false') + assert_equal true, parse('true') + assert_equal 23, parse('23') + assert_equal 1, parse('1') + assert_equal_float 3.141, parse('3.141'), 1E-3 + assert_equal 2 ** 64, parse('18446744073709551616') + assert_equal 'foo', parse('"foo"') + assert parse('NaN', :allow_nan => true).nan? + assert parse('Infinity', :allow_nan => true).infinite? + assert parse('-Infinity', :allow_nan => true).infinite? + assert_raise(JSON::ParserError) { parse('[ 1, ]', :quirks_mode => true) } + end + + def test_parse_some_strings + assert_equal([""], parse('[""]')) + assert_equal(["\\"], parse('["\\\\"]')) + assert_equal(['"'], parse('["\""]')) + assert_equal(['\\"\\'], parse('["\\\\\\"\\\\"]')) + assert_equal( + ["\"\b\n\r\t\0\037"], + parse('["\"\b\n\r\t\u0000\u001f"]') + ) + end + + def test_parse_big_integers + json1 = JSON(orig = (1 << 31) - 1) + assert_equal orig, parse(json1) + json2 = JSON(orig = 1 << 31) + assert_equal orig, parse(json2) + json3 = JSON(orig = (1 << 62) - 1) + assert_equal orig, parse(json3) + json4 = JSON(orig = 1 << 62) + assert_equal orig, parse(json4) + json5 = JSON(orig = 1 << 64) + assert_equal orig, parse(json5) + end + + def test_some_wrong_inputs + assert_raises(ParserError) { parse('[] bla') } + assert_raises(ParserError) { parse('[] 1') } + assert_raises(ParserError) { parse('[] []') } + assert_raises(ParserError) { parse('[] {}') } + assert_raises(ParserError) { parse('{} []') } + assert_raises(ParserError) { parse('{} {}') } + assert_raises(ParserError) { parse('[NULL]') } + assert_raises(ParserError) { parse('[FALSE]') } + assert_raises(ParserError) { parse('[TRUE]') } + assert_raises(ParserError) { parse('[07] ') } + assert_raises(ParserError) { parse('[0a]') } + assert_raises(ParserError) { parse('[1.]') } + assert_raises(ParserError) { parse(' ') } + end + + def test_symbolize_names + assert_equal({ "foo" => "bar", "baz" => "quux" }, + parse('{"foo":"bar", "baz":"quux"}')) + assert_equal({ :foo => "bar", :baz => "quux" }, + parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true)) + end + + def test_parse_comments + json = < "value1", "key2" => "value2", "key3" => "value3" }, + parse(json)) + json = < "value1" }, parse(json)) + end + + def test_nesting + too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]' + too_deep_ary = eval too_deep + assert_raises(JSON::NestingError) { parse too_deep } + assert_raises(JSON::NestingError) { parse too_deep, :max_nesting => 100 } + ok = parse too_deep, :max_nesting => 101 + assert_equal too_deep_ary, ok + ok = parse too_deep, :max_nesting => nil + assert_equal too_deep_ary, ok + ok = parse too_deep, :max_nesting => false + assert_equal too_deep_ary, ok + ok = parse too_deep, :max_nesting => 0 + assert_equal too_deep_ary, ok + end + + def test_backslash + data = [ '\\.(?i:gif|jpe?g|png)$' ] + json = '["\\\\.(?i:gif|jpe?g|png)$"]' + assert_equal data, parse(json) + # + data = [ '\\"' ] + json = '["\\\\\""]' + assert_equal data, parse(json) + # + json = '["/"]' + data = [ '/' ] + assert_equal data, parse(json) + # + json = '["\""]' + data = ['"'] + assert_equal data, parse(json) + # + json = '["\\\'"]' + data = ["'"] + assert_equal data, parse(json) + end + + + class SubArray < Array + def <<(v) + @shifted = true + super + end + + def shifted? + @shifted + end + end + + class SubArray2 < Array + def to_json(*a) + { + JSON.create_id => self.class.name, + 'ary' => to_a, + }.to_json(*a) + end + + def self.json_create(o) + o.delete JSON.create_id + o['ary'] + end + end + + class SubArrayWrapper + def initialize + @data = [] + end + + attr_reader :data + + def [](index) + @data[index] + end + + def <<(value) + @data << value + @shifted = true + end + + def shifted? + @shifted + end + end + + def test_parse_array_custom_array_derived_class + res = parse('[1,2]', :array_class => SubArray) + assert_equal([1,2], res) + assert_equal(SubArray, res.class) + assert res.shifted? + end + + def test_parse_array_custom_non_array_derived_class + res = parse('[1,2]', :array_class => SubArrayWrapper) + assert_equal([1,2], res.data) + assert_equal(SubArrayWrapper, res.class) + assert res.shifted? + end + + def test_parse_object + assert_equal({}, parse('{}')) + assert_equal({}, parse(' { } ')) + assert_equal({'foo'=>'bar'}, parse('{"foo":"bar"}')) + assert_equal({'foo'=>'bar'}, parse(' { "foo" : "bar" } ')) + end + + class SubHash < Hash + def []=(k, v) + @item_set = true + super + end + + def item_set? + @item_set + end + end + + class SubHash2 < Hash + def to_json(*a) + { + JSON.create_id => self.class.name, + }.merge(self).to_json(*a) + end + + def self.json_create(o) + o.delete JSON.create_id + self[o] + end + end + + class SubOpenStruct < OpenStruct + def [](k) + __send__(k) + end + + def []=(k, v) + @item_set = true + __send__("#{k}=", v) + end + + def item_set? + @item_set + end + end + + def test_parse_object_custom_hash_derived_class + res = parse('{"foo":"bar"}', :object_class => SubHash) + assert_equal({"foo" => "bar"}, res) + assert_equal(SubHash, res.class) + assert res.item_set? + end + + def test_parse_object_custom_non_hash_derived_class + res = parse('{"foo":"bar"}', :object_class => SubOpenStruct) + assert_equal "bar", res.foo + assert_equal(SubOpenStruct, res.class) + assert res.item_set? + end + + def test_parse_generic_object + res = parse( + '{"foo":"bar", "baz":{}}', + :object_class => JSON::GenericObject + ) + assert_equal(JSON::GenericObject, res.class) + assert_equal "bar", res.foo + assert_equal "bar", res["foo"] + assert_equal "bar", res[:foo] + assert_equal "bar", res.to_hash[:foo] + assert_equal(JSON::GenericObject, res.baz.class) + end + + def test_generate_core_subclasses_with_new_to_json + obj = SubHash2["foo" => SubHash2["bar" => true]] + obj_json = JSON(obj) + obj_again = parse(obj_json, :create_additions => true) + assert_kind_of SubHash2, obj_again + assert_kind_of SubHash2, obj_again['foo'] + assert obj_again['foo']['bar'] + assert_equal obj, obj_again + assert_equal ["foo"], + JSON(JSON(SubArray2["foo"]), :create_additions => true) + end + + def test_generate_core_subclasses_with_default_to_json + assert_equal '{"foo":"bar"}', JSON(SubHash["foo" => "bar"]) + assert_equal '["foo"]', JSON(SubArray["foo"]) + end + + def test_generate_of_core_subclasses + obj = SubHash["foo" => SubHash["bar" => true]] + obj_json = JSON(obj) + obj_again = JSON(obj_json) + assert_kind_of Hash, obj_again + assert_kind_of Hash, obj_again['foo'] + assert obj_again['foo']['bar'] + assert_equal obj, obj_again + end + + private + + def assert_equal_float(expected, actual, delta = 1e-2) + Array === expected and expected = expected.first + Array === actual and actual = actual.first + assert_in_delta(expected, actual, delta) + end +end diff --git a/tests/json_string_matching_test.rb b/tests/json_string_matching_test.rb new file mode 100644 index 000000000..7fec8417f --- /dev/null +++ b/tests/json_string_matching_test.rb @@ -0,0 +1,37 @@ +require 'test_helper' +require 'time' + +class JSONStringMatchingTest < Test::Unit::TestCase + include JSON + + class TestTime < ::Time + def self.json_create(string) + Time.parse(string) + end + + def to_json(*) + %{"#{strftime('%FT%T%z')}"} + end + + def ==(other) + to_i == other.to_i + end + end + + def test_match_date + t = TestTime.new + t_json = [ t ].to_json + time_regexp = /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ + assert_equal [ t ], + parse( + t_json, + :create_additions => true, + :match_string => { time_regexp => TestTime } + ) + assert_equal [ t.strftime('%FT%T%z') ], + parse( + t_json, + :match_string => { time_regexp => TestTime } + ) + end +end diff --git a/tests/test_helper.rb b/tests/test_helper.rb index abc911231..752f5f536 100644 --- a/tests/test_helper.rb +++ b/tests/test_helper.rb @@ -1,4 +1,3 @@ - gem 'json', File.read('VERSION').chomp case ENV['JSON'] diff --git a/tests/test_json.rb b/tests/test_json.rb deleted file mode 100755 index 31624a350..000000000 --- a/tests/test_json.rb +++ /dev/null @@ -1,538 +0,0 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require 'test_helper' -require 'stringio' -require 'tempfile' -require 'ostruct' - -class TestJSON < Test::Unit::TestCase - include JSON - - def setup - @ary = [1, "foo", 3.14, 4711.0, 2.718, nil, [1,-2,3], false, true].map do - |x| [x] - end - @ary_to_parse = ["1", '"foo"', "3.14", "4711.0", "2.718", "null", - "[1,-2,3]", "false", "true"].map do - |x| "[#{x}]" - end - @hash = { - 'a' => 2, - 'b' => 3.141, - 'c' => 'c', - 'd' => [ 1, "b", 3.14 ], - 'e' => { 'foo' => 'bar' }, - 'g' => "\"\0\037", - 'h' => 1000.0, - 'i' => 0.001 - } - @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\ - '"g":"\\"\\u0000\\u001f","h":1.0E3,"i":1.0E-3}' - end - - def test_construction - parser = JSON::Parser.new('test') - assert_equal 'test', parser.source - end - - def assert_equal_float(expected, is) - assert_in_delta(expected.first, is.first, 1e-2) - end - - def test_parse_simple_arrays - assert_equal([], parse('[]')) - assert_equal([], parse(' [ ] ')) - assert_equal([nil], parse('[null]')) - assert_equal([false], parse('[false]')) - assert_equal([true], parse('[true]')) - assert_equal([-23], parse('[-23]')) - assert_equal([23], parse('[23]')) - assert_equal([0.23], parse('[0.23]')) - assert_equal([0.0], parse('[0e0]')) - assert_raises(JSON::ParserError) { parse('[+23.2]') } - assert_raises(JSON::ParserError) { parse('[+23]') } - assert_raises(JSON::ParserError) { parse('[.23]') } - assert_raises(JSON::ParserError) { parse('[023]') } - assert_equal_float [3.141], parse('[3.141]') - assert_equal_float [-3.141], parse('[-3.141]') - assert_equal_float [3.141], parse('[3141e-3]') - assert_equal_float [3.141], parse('[3141.1e-3]') - assert_equal_float [3.141], parse('[3141E-3]') - assert_equal_float [3.141], parse('[3141.0E-3]') - assert_equal_float [-3.141], parse('[-3141.0e-3]') - assert_equal_float [-3.141], parse('[-3141e-3]') - assert_raises(ParserError) { parse('[NaN]') } - assert parse('[NaN]', :allow_nan => true).first.nan? - assert_raises(ParserError) { parse('[Infinity]') } - assert_equal [1.0/0], parse('[Infinity]', :allow_nan => true) - assert_raises(ParserError) { parse('[-Infinity]') } - assert_equal [-1.0/0], parse('[-Infinity]', :allow_nan => true) - assert_equal([""], parse('[""]')) - assert_equal(["foobar"], parse('["foobar"]')) - assert_equal([{}], parse('[{}]')) - end - - def test_parse_simple_objects - assert_equal({}, parse('{}')) - assert_equal({}, parse(' { } ')) - assert_equal({ "a" => nil }, parse('{ "a" : null}')) - assert_equal({ "a" => nil }, parse('{"a":null}')) - assert_equal({ "a" => false }, parse('{ "a" : false } ')) - assert_equal({ "a" => false }, parse('{"a":false}')) - assert_raises(JSON::ParserError) { parse('{false}') } - assert_equal({ "a" => true }, parse('{"a":true}')) - assert_equal({ "a" => true }, parse(' { "a" : true } ')) - assert_equal({ "a" => -23 }, parse(' { "a" : -23 } ')) - assert_equal({ "a" => -23 }, parse(' { "a" : -23 } ')) - assert_equal({ "a" => 23 }, parse('{"a":23 } ')) - assert_equal({ "a" => 23 }, parse(' { "a" : 23 } ')) - assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } ')) - assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } ')) - end - - def test_parse_json_primitive_values - assert_raise(JSON::ParserError) { JSON.parse('') } - assert_raise(JSON::ParserError) { JSON.parse('', :quirks_mode => true) } - assert_raise(TypeError) { JSON::Parser.new(nil).parse } - assert_raise(TypeError) { JSON::Parser.new(nil, :quirks_mode => true).parse } - assert_raise(TypeError) { JSON.parse(nil) } - assert_raise(TypeError) { JSON.parse(nil, :quirks_mode => true) } - assert_raise(JSON::ParserError) { JSON.parse(' /* foo */ ') } - assert_raise(JSON::ParserError) { JSON.parse(' /* foo */ ', :quirks_mode => true) } - parser = JSON::Parser.new('null') - assert_equal false, parser.quirks_mode? - assert_raise(JSON::ParserError) { parser.parse } - assert_raise(JSON::ParserError) { JSON.parse('null') } - assert_equal nil, JSON.parse('null', :quirks_mode => true) - parser = JSON::Parser.new('null', :quirks_mode => true) - assert_equal true, parser.quirks_mode? - assert_equal nil, parser.parse - assert_raise(JSON::ParserError) { JSON.parse('false') } - assert_equal false, JSON.parse('false', :quirks_mode => true) - assert_raise(JSON::ParserError) { JSON.parse('true') } - assert_equal true, JSON.parse('true', :quirks_mode => true) - assert_raise(JSON::ParserError) { JSON.parse('23') } - assert_equal 23, JSON.parse('23', :quirks_mode => true) - assert_raise(JSON::ParserError) { JSON.parse('1') } - assert_equal 1, JSON.parse('1', :quirks_mode => true) - assert_raise(JSON::ParserError) { JSON.parse('3.141') } - assert_in_delta 3.141, JSON.parse('3.141', :quirks_mode => true), 1E-3 - assert_raise(JSON::ParserError) { JSON.parse('18446744073709551616') } - assert_equal 2 ** 64, JSON.parse('18446744073709551616', :quirks_mode => true) - assert_raise(JSON::ParserError) { JSON.parse('"foo"') } - assert_equal 'foo', JSON.parse('"foo"', :quirks_mode => true) - assert_raise(JSON::ParserError) { JSON.parse('NaN', :allow_nan => true) } - assert JSON.parse('NaN', :quirks_mode => true, :allow_nan => true).nan? - assert_raise(JSON::ParserError) { JSON.parse('Infinity', :allow_nan => true) } - assert JSON.parse('Infinity', :quirks_mode => true, :allow_nan => true).infinite? - assert_raise(JSON::ParserError) { JSON.parse('-Infinity', :allow_nan => true) } - assert JSON.parse('-Infinity', :quirks_mode => true, :allow_nan => true).infinite? - assert_raise(JSON::ParserError) { JSON.parse('[ 1, ]', :quirks_mode => true) } - end - - if Array.method_defined?(:permutation) - def test_parse_more_complex_arrays - a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }] - a.permutation.each do |perm| - json = pretty_generate(perm) - assert_equal perm, parse(json) - end - end - - def test_parse_complex_objects - a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }] - a.permutation.each do |perm| - s = "a" - orig_obj = perm.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h } - json = pretty_generate(orig_obj) - assert_equal orig_obj, parse(json) - end - end - end - - def test_parse_arrays - assert_equal([1,2,3], parse('[1,2,3]')) - assert_equal([1.2,2,3], parse('[1.2,2,3]')) - assert_equal([[],[[],[]]], parse('[[],[[],[]]]')) - end - - def test_parse_values - assert_equal([""], parse('[""]')) - assert_equal(["\\"], parse('["\\\\"]')) - assert_equal(['"'], parse('["\""]')) - assert_equal(['\\"\\'], parse('["\\\\\\"\\\\"]')) - assert_equal(["\"\b\n\r\t\0\037"], - parse('["\"\b\n\r\t\u0000\u001f"]')) - for i in 0 ... @ary.size - assert_equal(@ary[i], parse(@ary_to_parse[i])) - end - end - - def test_parse_array - assert_equal([], parse('[]')) - assert_equal([], parse(' [ ] ')) - assert_equal([1], parse('[1]')) - assert_equal([1], parse(' [ 1 ] ')) - assert_equal(@ary, - parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]]'\ - ',[false],[true]]')) - assert_equal(@ary, parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]\s - , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] })) - end - - class SubArray < Array - def <<(v) - @shifted = true - super - end - - def shifted? - @shifted - end - end - - class SubArray2 < Array - def to_json(*a) - { - JSON.create_id => self.class.name, - 'ary' => to_a, - }.to_json(*a) - end - - def self.json_create(o) - o.delete JSON.create_id - o['ary'] - end - end - - class SubArrayWrapper - def initialize - @data = [] - end - - attr_reader :data - - def [](index) - @data[index] - end - - def <<(value) - @data << value - @shifted = true - end - - def shifted? - @shifted - end - end - - def test_parse_array_custom_array_derived_class - res = parse('[1,2]', :array_class => SubArray) - assert_equal([1,2], res) - assert_equal(SubArray, res.class) - assert res.shifted? - end - - def test_parse_array_custom_non_array_derived_class - res = parse('[1,2]', :array_class => SubArrayWrapper) - assert_equal([1,2], res.data) - assert_equal(SubArrayWrapper, res.class) - assert res.shifted? - end - - def test_parse_object - assert_equal({}, parse('{}')) - assert_equal({}, parse(' { } ')) - assert_equal({'foo'=>'bar'}, parse('{"foo":"bar"}')) - assert_equal({'foo'=>'bar'}, parse(' { "foo" : "bar" } ')) - end - - class SubHash < Hash - def []=(k, v) - @item_set = true - super - end - - def item_set? - @item_set - end - end - - class SubHash2 < Hash - def to_json(*a) - { - JSON.create_id => self.class.name, - }.merge(self).to_json(*a) - end - - def self.json_create(o) - o.delete JSON.create_id - self[o] - end - end - - class SubOpenStruct < OpenStruct - def [](k) - __send__(k) - end - - def []=(k, v) - @item_set = true - __send__("#{k}=", v) - end - - def item_set? - @item_set - end - end - - def test_parse_object_custom_hash_derived_class - res = parse('{"foo":"bar"}', :object_class => SubHash) - assert_equal({"foo" => "bar"}, res) - assert_equal(SubHash, res.class) - assert res.item_set? - end - - def test_parse_object_custom_non_hash_derived_class - res = parse('{"foo":"bar"}', :object_class => SubOpenStruct) - assert_equal "bar", res.foo - assert_equal(SubOpenStruct, res.class) - assert res.item_set? - end - - def test_parse_generic_object - res = parse('{"foo":"bar", "baz":{}}', :object_class => JSON::GenericObject) - assert_equal(JSON::GenericObject, res.class) - assert_equal "bar", res.foo - assert_equal "bar", res["foo"] - assert_equal "bar", res[:foo] - assert_equal "bar", res.to_hash[:foo] - assert_equal(JSON::GenericObject, res.baz.class) - end - - def test_generate_core_subclasses_with_new_to_json - obj = SubHash2["foo" => SubHash2["bar" => true]] - obj_json = JSON(obj) - obj_again = JSON.parse(obj_json, :create_additions => true) - assert_kind_of SubHash2, obj_again - assert_kind_of SubHash2, obj_again['foo'] - assert obj_again['foo']['bar'] - assert_equal obj, obj_again - assert_equal ["foo"], JSON(JSON(SubArray2["foo"]), :create_additions => true) - end - - def test_generate_core_subclasses_with_default_to_json - assert_equal '{"foo":"bar"}', JSON(SubHash["foo" => "bar"]) - assert_equal '["foo"]', JSON(SubArray["foo"]) - end - - def test_generate_of_core_subclasses - obj = SubHash["foo" => SubHash["bar" => true]] - obj_json = JSON(obj) - obj_again = JSON(obj_json) - assert_kind_of Hash, obj_again - assert_kind_of Hash, obj_again['foo'] - assert obj_again['foo']['bar'] - assert_equal obj, obj_again - end - - def test_parser_reset - parser = Parser.new(@json) - assert_equal(@hash, parser.parse) - assert_equal(@hash, parser.parse) - end - - def test_comments - json = < "value1", "key2" => "value2", "key3" => "value3" }, - parse(json)) - json = < "value1" }, parse(json)) - end - - def test_backslash - data = [ '\\.(?i:gif|jpe?g|png)$' ] - json = '["\\\\.(?i:gif|jpe?g|png)$"]' - assert_equal json, JSON.generate(data) - assert_equal data, JSON.parse(json) - # - data = [ '\\"' ] - json = '["\\\\\""]' - assert_equal json, JSON.generate(data) - assert_equal data, JSON.parse(json) - # - json = '["/"]' - data = JSON.parse(json) - assert_equal ['/'], data - assert_equal json, JSON.generate(data) - # - json = '["\""]' - data = JSON.parse(json) - assert_equal ['"'], data - assert_equal json, JSON.generate(data) - json = '["\\\'"]' - data = JSON.parse(json) - assert_equal ["'"], data - assert_equal '["\'"]', JSON.generate(data) - end - - def test_wrong_inputs - assert_raises(ParserError) { JSON.parse('"foo"') } - assert_raises(ParserError) { JSON.parse('123') } - assert_raises(ParserError) { JSON.parse('[] bla') } - assert_raises(ParserError) { JSON.parse('[] 1') } - assert_raises(ParserError) { JSON.parse('[] []') } - assert_raises(ParserError) { JSON.parse('[] {}') } - assert_raises(ParserError) { JSON.parse('{} []') } - assert_raises(ParserError) { JSON.parse('{} {}') } - assert_raises(ParserError) { JSON.parse('[NULL]') } - assert_raises(ParserError) { JSON.parse('[FALSE]') } - assert_raises(ParserError) { JSON.parse('[TRUE]') } - assert_raises(ParserError) { JSON.parse('[07] ') } - assert_raises(ParserError) { JSON.parse('[0a]') } - assert_raises(ParserError) { JSON.parse('[1.]') } - assert_raises(ParserError) { JSON.parse(' ') } - end - - def test_nesting - assert_raises(JSON::NestingError) { JSON.parse '[[]]', :max_nesting => 1 } - assert_raises(JSON::NestingError) { JSON.parser.new('[[]]', :max_nesting => 1).parse } - assert_equal [[]], JSON.parse('[[]]', :max_nesting => 2) - too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]' - too_deep_ary = eval too_deep - assert_raises(JSON::NestingError) { JSON.parse too_deep } - assert_raises(JSON::NestingError) { JSON.parser.new(too_deep).parse } - assert_raises(JSON::NestingError) { JSON.parse too_deep, :max_nesting => 100 } - ok = JSON.parse too_deep, :max_nesting => 101 - assert_equal too_deep_ary, ok - ok = JSON.parse too_deep, :max_nesting => nil - assert_equal too_deep_ary, ok - ok = JSON.parse too_deep, :max_nesting => false - assert_equal too_deep_ary, ok - ok = JSON.parse too_deep, :max_nesting => 0 - assert_equal too_deep_ary, ok - assert_raises(JSON::NestingError) { JSON.generate [[]], :max_nesting => 1 } - assert_equal '[[]]', JSON.generate([[]], :max_nesting => 2) - assert_raises(JSON::NestingError) { JSON.generate too_deep_ary } - assert_raises(JSON::NestingError) { JSON.generate too_deep_ary, :max_nesting => 100 } - ok = JSON.generate too_deep_ary, :max_nesting => 101 - assert_equal too_deep, ok - ok = JSON.generate too_deep_ary, :max_nesting => nil - assert_equal too_deep, ok - ok = JSON.generate too_deep_ary, :max_nesting => false - assert_equal too_deep, ok - ok = JSON.generate too_deep_ary, :max_nesting => 0 - assert_equal too_deep, ok - end - - def test_symbolize_names - assert_equal({ "foo" => "bar", "baz" => "quux" }, - JSON.parse('{"foo":"bar", "baz":"quux"}')) - assert_equal({ :foo => "bar", :baz => "quux" }, - JSON.parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true)) - end - - def test_load - assert_equal @hash, JSON.load(@json) - tempfile = Tempfile.open('json') - tempfile.write @json - tempfile.rewind - assert_equal @hash, JSON.load(tempfile) - stringio = StringIO.new(@json) - stringio.rewind - assert_equal @hash, JSON.load(stringio) - assert_equal nil, JSON.load(nil) - assert_equal nil, JSON.load('') - ensure - tempfile.close! - end - - def test_load_with_options - small_hash = JSON("foo" => 'bar') - symbol_hash = { :foo => 'bar' } - assert_equal symbol_hash, JSON.load(small_hash, nil, :symbolize_names => true) - end - - def test_dump - too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]' - assert_equal too_deep, JSON.dump(eval(too_deep)) - assert_kind_of String, Marshal.dump(eval(too_deep)) - assert_raises(ArgumentError) { JSON.dump(eval(too_deep), 100) } - assert_raises(ArgumentError) { Marshal.dump(eval(too_deep), 100) } - assert_equal too_deep, JSON.dump(eval(too_deep), 101) - assert_kind_of String, Marshal.dump(eval(too_deep), 101) - output = StringIO.new - JSON.dump(eval(too_deep), output) - assert_equal too_deep, output.string - output = StringIO.new - JSON.dump(eval(too_deep), output, 101) - assert_equal too_deep, output.string - end - - def test_dump_should_modify_defaults - max_nesting = JSON.dump_default_options[:max_nesting] - JSON.dump([], StringIO.new, 10) - assert_equal max_nesting, JSON.dump_default_options[:max_nesting] - end - - def test_big_integers - json1 = JSON([orig = (1 << 31) - 1]) - assert_equal orig, JSON[json1][0] - json2 = JSON([orig = 1 << 31]) - assert_equal orig, JSON[json2][0] - json3 = JSON([orig = (1 << 62) - 1]) - assert_equal orig, JSON[json3][0] - json4 = JSON([orig = 1 << 62]) - assert_equal orig, JSON[json4][0] - json5 = JSON([orig = 1 << 64]) - assert_equal orig, JSON[json5][0] - end - - if defined?(JSON::Ext::Parser) - def test_allocate - parser = JSON::Ext::Parser.new("{}") - assert_raise(TypeError, '[ruby-core:35079]') {parser.__send__(:initialize, "{}")} - parser = JSON::Ext::Parser.allocate - assert_raise(TypeError, '[ruby-core:35079]') {parser.source} - end - end - - def test_argument_encoding - source = "{}".force_encoding("ascii-8bit") - JSON::Parser.new(source) - assert_equal Encoding::ASCII_8BIT, source.encoding - end if defined?(Encoding::ASCII_8BIT) -end diff --git a/tests/test_json_encoding.rb b/tests/test_json_encoding.rb deleted file mode 100644 index 3536c56c9..000000000 --- a/tests/test_json_encoding.rb +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require 'test_helper' - -class TestJSONEncoding < Test::Unit::TestCase - include JSON - - def setup - @utf_8 = '["© ≠ €!"]' - @parsed = [ "© ≠ €!" ] - @generated = '["\u00a9 \u2260 \u20ac!"]' - if String.method_defined?(:encode) - @utf_16_data = [@parsed.first.encode('utf-16be', 'utf-8')] - @utf_8_ascii_8bit = @utf_8.dup.force_encoding(Encoding::ASCII_8BIT) - @utf_16be = @utf_8.encode('utf-16be', 'utf-8') - @utf_16be_ascii_8bit = @utf_16be.dup.force_encoding(Encoding::ASCII_8BIT) - @utf_16le = @utf_8.encode('utf-16le', 'utf-8') - @utf_16le_ascii_8bit = @utf_16le.dup.force_encoding(Encoding::ASCII_8BIT) - @utf_32be = @utf_8.encode('utf-32be', 'utf-8') - @utf_32be_ascii_8bit = @utf_32be.dup.force_encoding(Encoding::ASCII_8BIT) - @utf_32le = @utf_8.encode('utf-32le', 'utf-8') - @utf_32le_ascii_8bit = @utf_32le.dup.force_encoding(Encoding::ASCII_8BIT) - else - require 'iconv' - @utf_16_data = Iconv.iconv('utf-16be', 'utf-8', @parsed.first) - @utf_8_ascii_8bit = @utf_8.dup - @utf_16be, = Iconv.iconv('utf-16be', 'utf-8', @utf_8) - @utf_16be_ascii_8bit = @utf_16be.dup - @utf_16le, = Iconv.iconv('utf-16le', 'utf-8', @utf_8) - @utf_16le_ascii_8bit = @utf_16le.dup - @utf_32be, = Iconv.iconv('utf-32be', 'utf-8', @utf_8) - @utf_32be_ascii_8bit = @utf_32be.dup - @utf_32le, = Iconv.iconv('utf-32le', 'utf-8', @utf_8) - @utf_32le_ascii_8bit = @utf_32le.dup - end - end - - def test_parse - assert_equal @parsed, JSON.parse(@utf_8) - assert_equal @parsed, JSON.parse(@utf_16be) - assert_equal @parsed, JSON.parse(@utf_16le) - assert_equal @parsed, JSON.parse(@utf_32be) - assert_equal @parsed, JSON.parse(@utf_32le) - end - - def test_parse_ascii_8bit - assert_equal @parsed, JSON.parse(@utf_8_ascii_8bit) - assert_equal @parsed, JSON.parse(@utf_16be_ascii_8bit) - assert_equal @parsed, JSON.parse(@utf_16le_ascii_8bit) - assert_equal @parsed, JSON.parse(@utf_32be_ascii_8bit) - assert_equal @parsed, JSON.parse(@utf_32le_ascii_8bit) - end - - def test_generate - assert_equal @generated, JSON.generate(@parsed, :ascii_only => true) - if defined?(::Encoding) - assert_equal @generated, JSON.generate(@utf_16_data, :ascii_only => true) - else - # XXX checking of correct utf8 data is not as strict (yet?) without :ascii_only - assert_raises(JSON::GeneratorError) { JSON.generate(@utf_16_data, :ascii_only => true) } - end - end -end diff --git a/tests/test_json_string_matching.rb b/tests/test_json_string_matching.rb deleted file mode 100644 index 2b89588d9..000000000 --- a/tests/test_json_string_matching.rb +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require 'test_helper' -require 'stringio' -require 'time' - -class TestJSONStringMatching < Test::Unit::TestCase - include JSON - - class TestTime < ::Time - def self.json_create(string) - Time.parse(string) - end - - def to_json(*) - %{"#{strftime('%FT%T%z')}"} - end - - def ==(other) - to_i == other.to_i - end - end - - def test_match_date - t = TestTime.new - t_json = [ t ].to_json - assert_equal [ t ], - JSON.parse(t_json, :create_additions => true, - :match_string => { /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime }) - assert_equal [ t.strftime('%FT%T%z') ], - JSON.parse(t_json, :create_additions => true, - :match_string => { /\A\d{3}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime }) - assert_equal [ t.strftime('%FT%T%z') ], - JSON.parse(t_json, - :match_string => { /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/ => TestTime }) - end -end diff --git a/tests/test_json_unicode.rb b/tests/test_json_unicode.rb deleted file mode 100755 index f59c36a11..000000000 --- a/tests/test_json_unicode.rb +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require 'test_helper' - -class TestJSONUnicode < Test::Unit::TestCase - include JSON - - def test_unicode - assert_equal '""', ''.to_json - assert_equal '"\\b"', "\b".to_json - assert_equal '"\u0001"', 0x1.chr.to_json - assert_equal '"\u001f"', 0x1f.chr.to_json - assert_equal '" "', ' '.to_json - assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json - utf8 = [ "© ≠ €! \01" ] - json = '["© ≠ €! \u0001"]' - assert_equal json, utf8.to_json(:ascii_only => false) - assert_equal utf8, parse(json) - json = '["\u00a9 \u2260 \u20ac! \u0001"]' - assert_equal json, utf8.to_json(:ascii_only => true) - assert_equal utf8, parse(json) - utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"] - json = "[\"\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212\"]" - assert_equal utf8, parse(json) - assert_equal json, utf8.to_json(:ascii_only => false) - utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"] - assert_equal utf8, parse(json) - json = "[\"\\u3042\\u3044\\u3046\\u3048\\u304a\"]" - assert_equal json, utf8.to_json(:ascii_only => true) - assert_equal utf8, parse(json) - utf8 = ['საქართველო'] - json = '["საქართველო"]' - assert_equal json, utf8.to_json(:ascii_only => false) - json = "[\"\\u10e1\\u10d0\\u10e5\\u10d0\\u10e0\\u10d7\\u10d5\\u10d4\\u10da\\u10dd\"]" - assert_equal json, utf8.to_json(:ascii_only => true) - assert_equal utf8, parse(json) - assert_equal '["Ã"]', JSON.generate(["Ã"], :ascii_only => false) - assert_equal '["\\u00c3"]', JSON.generate(["Ã"], :ascii_only => true) - assert_equal ["€"], JSON.parse('["\u20ac"]') - utf8 = ["\xf0\xa0\x80\x81"] - json = "[\"\xf0\xa0\x80\x81\"]" - assert_equal json, JSON.generate(utf8, :ascii_only => false) - assert_equal utf8, JSON.parse(json) - json = '["\ud840\udc01"]' - assert_equal json, JSON.generate(utf8, :ascii_only => true) - assert_equal utf8, JSON.parse(json) - end - - def test_chars - (0..0x7f).each do |i| - json = '["\u%04x"]' % i - if RUBY_VERSION >= "1.9." - i = i.chr - end - assert_equal i, JSON.parse(json).first[0] - if i == ?\b - generated = JSON.generate(["" << i]) - assert '["\b"]' == generated || '["\10"]' == generated - elsif [?\n, ?\r, ?\t, ?\f].include?(i) - assert_equal '[' << ('' << i).dump << ']', JSON.generate(["" << i]) - elsif i.chr < 0x20.chr - assert_equal json, JSON.generate(["" << i]) - end - end - assert_raise(JSON::GeneratorError) do - JSON.generate(["\x80"], :ascii_only => true) - end - assert_equal "\302\200", JSON.parse('["\u0080"]').first - end -end From 68ce5b6b564f87edd1d4f005a39a230e544d15e8 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 15 Jun 2015 14:15:48 +0200 Subject: [PATCH 093/312] Ext parser is green now as well --- Gemfile | 3 +- Rakefile | 23 +- ext/json/ext/parser/parser.c | 543 +++++++++++++--------------------- ext/json/ext/parser/parser.h | 1 - ext/json/ext/parser/parser.rl | 118 ++------ ext/json/extconf.rb | 1 - json.gemspec | Bin 4423 -> 4594 bytes json_pure.gemspec | 19 +- 8 files changed, 240 insertions(+), 468 deletions(-) diff --git a/Gemfile b/Gemfile index c2a30299d..4ce50ec1d 100644 --- a/Gemfile +++ b/Gemfile @@ -6,6 +6,7 @@ gemspec :name => 'json' gemspec :name => 'json_pure' gemspec :name => 'json-java' -gem 'utils' +gem 'rake' +gem 'rdoc' gem 'test-unit' gem 'byebug', :platform => :mri diff --git a/Rakefile b/Rakefile index 32e486c82..bef1f39e3 100644 --- a/Rakefile +++ b/Rakefile @@ -23,10 +23,6 @@ class UndocumentedTestTask < Rake::TestTask def desc(*) end end -def skip_sdoc(src) - src.gsub(/^.*sdoc.*/) { |s| s + ' if RUBY_VERSION > "1.8.6"' } -end - MAKE = ENV['MAKE'] || %w[gmake make].find { |c| system(c, '-v') } BUNDLE = ENV['BUNDLE'] || %w[bundle].find { |c| system(c, '-v') } PKG_NAME = 'json' @@ -87,13 +83,11 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.files = PKG_FILES s.require_path = 'lib' - s.add_development_dependency 'sdoc', '~>0.3.16' - s.add_development_dependency 'rake', '~>0.9.2' s.extra_rdoc_files << 'README.rdoc' s.rdoc_options << '--title' << 'JSON implemention for ruby' << '--main' << 'README.rdoc' - s.test_files.concat Dir['./tests/test_*.rb'] + s.test_files.concat Dir['./tests/*_test.rb'] s.author = "Florian Frank" s.email = "flori@ping.de" @@ -104,7 +98,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) desc 'Creates a json_pure.gemspec file' task :gemspec_pure => :version do File.open('json_pure.gemspec', 'w') do |gemspec| - gemspec.write skip_sdoc(spec_pure.to_ruby) + gemspec.write spec_pure.to_ruby end end @@ -124,12 +118,11 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.extensions = FileList['ext/**/extconf.rb'] s.require_path = 'lib' - s.add_development_dependency 'sdoc', '~>0.3.16' s.extra_rdoc_files << 'README.rdoc' s.rdoc_options << '--title' << 'JSON implemention for Ruby' << '--main' << 'README.rdoc' - s.test_files.concat Dir['./tests/test_*.rb'] + s.test_files.concat Dir['./tests/*_test.rb'] s.author = "Florian Frank" s.email = "flori@ping.de" @@ -140,7 +133,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) desc 'Creates a json.gemspec file' task :gemspec_ext => :version do File.open('json.gemspec', 'w') do |gemspec| - gemspec.write skip_sdoc(spec_ext.to_ruby) + gemspec.write spec_ext.to_ruby end end @@ -181,7 +174,7 @@ task :test_pure => [ :clean, :check_env, :do_test_pure ] UndocumentedTestTask.new do |t| t.name = 'do_test_pure' t.libs << 'lib' << 'tests' - t.test_files = FileList['tests/test_*.rb'] + t.test_files = FileList['tests/*_test.rb'] t.verbose = true t.options = '-v' end @@ -264,7 +257,7 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby' UndocumentedTestTask.new do |t| t.name = 'do_test_ext' t.libs << 'lib' << 'tests' - t.test_files = FileList['tests/test_*.rb'] + t.test_files = FileList['tests/*_test.rb'] t.verbose = true t.options = '-v' end @@ -338,14 +331,14 @@ else UndocumentedTestTask.new do |t| t.name = 'do_test_ext' t.libs << 'ext' << 'lib' << 'tests' - t.test_files = FileList['tests/test_*.rb'] + t.test_files = FileList['tests/*_test.rb'] t.verbose = true t.options = '-v' end desc "Create RDOC documentation" task :doc => [ :version, EXT_PARSER_SRC ] do - sh "sdoc -o doc -t '#{PKG_TITLE}' -m README.rdoc README.rdoc lib/json.rb #{FileList['lib/json/**/*.rb']} #{EXT_PARSER_SRC} #{EXT_GENERATOR_SRC}" + sh "rdoc -o doc -t '#{PKG_TITLE}' -m README.rdoc README.rdoc lib/json.rb #{FileList['lib/json/**/*.rb']} #{EXT_PARSER_SRC} #{EXT_GENERATOR_SRC}" end desc "Generate parser with ragel" diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index fb7ca455b..34151028e 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -79,7 +79,7 @@ static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static VALUE CNaN, CInfinity, CMinusInfinity; static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, - i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode, + i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_aref, i_leftshift; @@ -468,7 +468,7 @@ case 26: #line 470 "parser.c" static const int JSON_value_start = 1; -static const int JSON_value_first_final = 21; +static const int JSON_value_first_final = 29; static const int JSON_value_error = 0; static const int JSON_value_en_main = 1; @@ -495,40 +495,49 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul goto _test_eof; switch ( cs ) { +st1: + if ( ++p == pe ) + goto _test_eof1; case 1: switch( (*p) ) { - case 34: goto tr0; - case 45: goto tr2; - case 73: goto st2; - case 78: goto st9; - case 91: goto tr5; - case 102: goto st11; - case 110: goto st15; - case 116: goto st18; - case 123: goto tr9; + case 13: goto st1; + case 32: goto st1; + case 34: goto tr2; + case 45: goto tr3; + case 47: goto st6; + case 73: goto st10; + case 78: goto st17; + case 91: goto tr7; + case 102: goto st19; + case 110: goto st23; + case 116: goto st26; + case 123: goto tr11; } - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr2; + if ( (*p) > 10 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr3; + } else if ( (*p) >= 9 ) + goto st1; goto st0; st0: cs = 0; goto _out; -tr0: +tr2: #line 219 "parser.rl" { char *np = JSON_parse_string(json, p, pe, result); - if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } - goto st21; -tr2: + goto st29; +tr3: #line 224 "parser.rl" { char *np; - if(pe > p + 9 - json->quirks_mode && !strncmp(MinusInfinity, p, 9)) { + if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) { if (json->allow_nan) { *result = CMinusInfinity; {p = (( p + 10))-1;} - p--; {p++; cs = 21; goto _out;} + p--; {p++; cs = 29; goto _out;} } else { rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); } @@ -537,30 +546,30 @@ cs = 0; if (np != NULL) {p = (( np))-1;} np = JSON_parse_integer(json, p, pe, result); if (np != NULL) {p = (( np))-1;} - p--; {p++; cs = 21; goto _out;} + p--; {p++; cs = 29; goto _out;} } - goto st21; -tr5: + goto st29; +tr7: #line 242 "parser.rl" { char *np; json->current_nesting++; np = JSON_parse_array(json, p, pe, result); json->current_nesting--; - if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } - goto st21; -tr9: + goto st29; +tr11: #line 250 "parser.rl" { char *np; json->current_nesting++; np = JSON_parse_object(json, p, pe, result); json->current_nesting--; - if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } - goto st21; -tr16: + goto st29; +tr25: #line 212 "parser.rl" { if (json->allow_nan) { @@ -569,8 +578,8 @@ cs = 0; rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); } } - goto st21; -tr18: + goto st29; +tr27: #line 205 "parser.rl" { if (json->allow_nan) { @@ -579,168 +588,240 @@ cs = 0; rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); } } - goto st21; -tr22: + goto st29; +tr31: #line 199 "parser.rl" { *result = Qfalse; } - goto st21; -tr25: + goto st29; +tr34: #line 196 "parser.rl" { *result = Qnil; } - goto st21; -tr28: + goto st29; +tr37: #line 202 "parser.rl" { *result = Qtrue; } - goto st21; -st21: + goto st29; +st29: if ( ++p == pe ) - goto _test_eof21; -case 21: + goto _test_eof29; +case 29: #line 258 "parser.rl" - { p--; {p++; cs = 21; goto _out;} } -#line 608 "parser.c" + { p--; {p++; cs = 29; goto _out;} } +#line 617 "parser.c" + switch( (*p) ) { + case 13: goto st29; + case 32: goto st29; + case 47: goto st2; + } + if ( 9 <= (*p) && (*p) <= 10 ) + goto st29; goto st0; st2: if ( ++p == pe ) goto _test_eof2; case 2: - if ( (*p) == 110 ) - goto st3; + switch( (*p) ) { + case 42: goto st3; + case 47: goto st5; + } goto st0; st3: if ( ++p == pe ) goto _test_eof3; case 3: - if ( (*p) == 102 ) + if ( (*p) == 42 ) goto st4; - goto st0; + goto st3; st4: if ( ++p == pe ) goto _test_eof4; case 4: - if ( (*p) == 105 ) - goto st5; - goto st0; + switch( (*p) ) { + case 42: goto st4; + case 47: goto st29; + } + goto st3; st5: if ( ++p == pe ) goto _test_eof5; case 5: - if ( (*p) == 110 ) - goto st6; - goto st0; + if ( (*p) == 10 ) + goto st29; + goto st5; st6: if ( ++p == pe ) goto _test_eof6; case 6: - if ( (*p) == 105 ) - goto st7; + switch( (*p) ) { + case 42: goto st7; + case 47: goto st9; + } goto st0; st7: if ( ++p == pe ) goto _test_eof7; case 7: - if ( (*p) == 116 ) + if ( (*p) == 42 ) goto st8; - goto st0; + goto st7; st8: if ( ++p == pe ) goto _test_eof8; case 8: - if ( (*p) == 121 ) - goto tr16; - goto st0; + switch( (*p) ) { + case 42: goto st8; + case 47: goto st1; + } + goto st7; st9: if ( ++p == pe ) goto _test_eof9; case 9: - if ( (*p) == 97 ) - goto st10; - goto st0; + if ( (*p) == 10 ) + goto st1; + goto st9; st10: if ( ++p == pe ) goto _test_eof10; case 10: - if ( (*p) == 78 ) - goto tr18; + if ( (*p) == 110 ) + goto st11; goto st0; st11: if ( ++p == pe ) goto _test_eof11; case 11: - if ( (*p) == 97 ) + if ( (*p) == 102 ) goto st12; goto st0; st12: if ( ++p == pe ) goto _test_eof12; case 12: - if ( (*p) == 108 ) + if ( (*p) == 105 ) goto st13; goto st0; st13: if ( ++p == pe ) goto _test_eof13; case 13: - if ( (*p) == 115 ) + if ( (*p) == 110 ) goto st14; goto st0; st14: if ( ++p == pe ) goto _test_eof14; case 14: - if ( (*p) == 101 ) - goto tr22; + if ( (*p) == 105 ) + goto st15; goto st0; st15: if ( ++p == pe ) goto _test_eof15; case 15: - if ( (*p) == 117 ) + if ( (*p) == 116 ) goto st16; goto st0; st16: if ( ++p == pe ) goto _test_eof16; case 16: - if ( (*p) == 108 ) - goto st17; + if ( (*p) == 121 ) + goto tr25; goto st0; st17: if ( ++p == pe ) goto _test_eof17; case 17: - if ( (*p) == 108 ) - goto tr25; + if ( (*p) == 97 ) + goto st18; goto st0; st18: if ( ++p == pe ) goto _test_eof18; case 18: - if ( (*p) == 114 ) - goto st19; + if ( (*p) == 78 ) + goto tr27; goto st0; st19: if ( ++p == pe ) goto _test_eof19; case 19: - if ( (*p) == 117 ) + if ( (*p) == 97 ) goto st20; goto st0; st20: if ( ++p == pe ) goto _test_eof20; case 20: + if ( (*p) == 108 ) + goto st21; + goto st0; +st21: + if ( ++p == pe ) + goto _test_eof21; +case 21: + if ( (*p) == 115 ) + goto st22; + goto st0; +st22: + if ( ++p == pe ) + goto _test_eof22; +case 22: if ( (*p) == 101 ) - goto tr28; + goto tr31; + goto st0; +st23: + if ( ++p == pe ) + goto _test_eof23; +case 23: + if ( (*p) == 117 ) + goto st24; + goto st0; +st24: + if ( ++p == pe ) + goto _test_eof24; +case 24: + if ( (*p) == 108 ) + goto st25; + goto st0; +st25: + if ( ++p == pe ) + goto _test_eof25; +case 25: + if ( (*p) == 108 ) + goto tr34; + goto st0; +st26: + if ( ++p == pe ) + goto _test_eof26; +case 26: + if ( (*p) == 114 ) + goto st27; + goto st0; +st27: + if ( ++p == pe ) + goto _test_eof27; +case 27: + if ( (*p) == 117 ) + goto st28; + goto st0; +st28: + if ( ++p == pe ) + goto _test_eof28; +case 28: + if ( (*p) == 101 ) + goto tr37; goto st0; } - _test_eof21: cs = 21; goto _test_eof; + _test_eof1: cs = 1; goto _test_eof; + _test_eof29: cs = 29; goto _test_eof; _test_eof2: cs = 2; goto _test_eof; _test_eof3: cs = 3; goto _test_eof; _test_eof4: cs = 4; goto _test_eof; @@ -760,6 +841,14 @@ case 20: _test_eof18: cs = 18; goto _test_eof; _test_eof19: cs = 19; goto _test_eof; _test_eof20: cs = 20; goto _test_eof; + _test_eof21: cs = 21; goto _test_eof; + _test_eof22: cs = 22; goto _test_eof; + _test_eof23: cs = 23; goto _test_eof; + _test_eof24: cs = 24; goto _test_eof; + _test_eof25: cs = 25; goto _test_eof; + _test_eof26: cs = 26; goto _test_eof; + _test_eof27: cs = 27; goto _test_eof; + _test_eof28: cs = 28; goto _test_eof; _test_eof: {} _out: {} @@ -775,7 +864,7 @@ case 20: } -#line 779 "parser.c" +#line 868 "parser.c" static const int JSON_integer_start = 1; static const int JSON_integer_first_final = 3; static const int JSON_integer_error = 0; @@ -791,7 +880,7 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res int cs = EVIL; -#line 795 "parser.c" +#line 884 "parser.c" { cs = JSON_integer_start; } @@ -799,7 +888,7 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res #line 302 "parser.rl" json->memo = p; -#line 803 "parser.c" +#line 892 "parser.c" { if ( p == pe ) goto _test_eof; @@ -840,7 +929,7 @@ case 3: if ( ++p == pe ) goto _test_eof4; case 4: -#line 844 "parser.c" +#line 933 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -874,7 +963,7 @@ case 5: } -#line 878 "parser.c" +#line 967 "parser.c" static const int JSON_float_start = 1; static const int JSON_float_first_final = 8; static const int JSON_float_error = 0; @@ -890,7 +979,7 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 894 "parser.c" +#line 983 "parser.c" { cs = JSON_float_start; } @@ -898,7 +987,7 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul #line 336 "parser.rl" json->memo = p; -#line 902 "parser.c" +#line 991 "parser.c" { if ( p == pe ) goto _test_eof; @@ -963,7 +1052,7 @@ case 8: if ( ++p == pe ) goto _test_eof9; case 9: -#line 967 "parser.c" +#line 1056 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -1040,7 +1129,7 @@ case 7: -#line 1044 "parser.c" +#line 1133 "parser.c" static const int JSON_array_start = 1; static const int JSON_array_first_final = 17; static const int JSON_array_error = 0; @@ -1062,14 +1151,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); -#line 1066 "parser.c" +#line 1155 "parser.c" { cs = JSON_array_start; } #line 394 "parser.rl" -#line 1073 "parser.c" +#line 1162 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1128,7 +1217,7 @@ case 2: if ( ++p == pe ) goto _test_eof3; case 3: -#line 1132 "parser.c" +#line 1221 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -1235,7 +1324,7 @@ case 12: if ( ++p == pe ) goto _test_eof17; case 17: -#line 1239 "parser.c" +#line 1328 "parser.c" goto st0; st13: if ( ++p == pe ) @@ -1372,7 +1461,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1376 "parser.c" +#line 1465 "parser.c" static const int JSON_string_start = 1; static const int JSON_string_first_final = 8; static const int JSON_string_error = 0; @@ -1402,7 +1491,7 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = rb_str_buf_new(0); -#line 1406 "parser.c" +#line 1495 "parser.c" { cs = JSON_string_start; } @@ -1410,7 +1499,7 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu #line 515 "parser.rl" json->memo = p; -#line 1414 "parser.c" +#line 1503 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1453,7 +1542,7 @@ case 2: if ( ++p == pe ) goto _test_eof8; case 8: -#line 1457 "parser.c" +#line 1546 "parser.c" goto st0; st3: if ( ++p == pe ) @@ -1566,8 +1655,6 @@ case 7: static VALUE convert_encoding(VALUE source) { - char *ptr = RSTRING_PTR(source); - long len = RSTRING_LEN(source); #ifdef HAVE_RUBY_ENCODING_H { source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); @@ -1640,13 +1727,6 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->symbolize_names = 0; } - tmp = ID2SYM(i_quirks_mode); - if (option_given_p(opts, tmp)) { - VALUE quirks_mode = rb_hash_aref(opts, tmp); - json->quirks_mode = RTEST(quirks_mode) ? 1 : 0; - } else { - json->quirks_mode = 0; - } tmp = ID2SYM(i_create_additions); if (option_given_p(opts, tmp)) { json->create_additions = RTEST(rb_hash_aref(opts, tmp)); @@ -1688,9 +1768,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) json->array_class = Qnil; } source = rb_convert_type(source, T_STRING, "String", "to_str"); - if (!json->quirks_mode) { - source = convert_encoding(StringValue(source)); - } + source = convert_encoding(StringValue(source)); json->current_nesting = 0; StringValue(source); json->len = RSTRING_LEN(source); @@ -1700,7 +1778,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1704 "parser.c" +#line 1782 "parser.c" static const int JSON_start = 1; static const int JSON_first_final = 10; static const int JSON_error = 0; @@ -1708,201 +1786,33 @@ static const int JSON_error = 0; static const int JSON_en_main = 1; -#line 711 "parser.rl" +#line 690 "parser.rl" -static VALUE cParser_parse_strict(VALUE self) +/* + * call-seq: parse() + * + * Parses the current JSON text _source_ and returns the complete data + * structure as a result. + */ +static VALUE cParser_parse(VALUE self) { - char *p, *pe; - int cs = EVIL; - VALUE result = Qnil; - GET_PARSER; + char *p, *pe; + int cs = EVIL; + VALUE result = Qnil; + GET_PARSER; -#line 1723 "parser.c" +#line 1807 "parser.c" { cs = JSON_start; } -#line 721 "parser.rl" - p = json->source; - pe = p + json->len; +#line 706 "parser.rl" + p = json->source; + pe = p + json->len; -#line 1732 "parser.c" - { - if ( p == pe ) - goto _test_eof; - switch ( cs ) - { -st1: - if ( ++p == pe ) - goto _test_eof1; -case 1: - switch( (*p) ) { - case 13: goto st1; - case 32: goto st1; - case 47: goto st2; - case 91: goto tr3; - case 123: goto tr4; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st1; - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 42: goto st3; - case 47: goto st5; - } - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - if ( (*p) == 42 ) - goto st4; - goto st3; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - switch( (*p) ) { - case 42: goto st4; - case 47: goto st1; - } - goto st3; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - if ( (*p) == 10 ) - goto st1; - goto st5; -tr3: -#line 700 "parser.rl" - { - char *np; - json->current_nesting = 1; - np = JSON_parse_array(json, p, pe, &result); - if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} - } - goto st10; -tr4: -#line 693 "parser.rl" - { - char *np; - json->current_nesting = 1; - np = JSON_parse_object(json, p, pe, &result); - if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} - } - goto st10; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: -#line 1809 "parser.c" - switch( (*p) ) { - case 13: goto st10; - case 32: goto st10; - case 47: goto st6; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st10; - goto st0; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - switch( (*p) ) { - case 42: goto st7; - case 47: goto st9; - } - goto st0; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - if ( (*p) == 42 ) - goto st8; - goto st7; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - switch( (*p) ) { - case 42: goto st8; - case 47: goto st10; - } - goto st7; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: - if ( (*p) == 10 ) - goto st10; - goto st9; - } - _test_eof1: cs = 1; goto _test_eof; - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - - _test_eof: {} - _out: {} - } - -#line 724 "parser.rl" - - if (cs >= JSON_first_final && p == pe) { - return result; - } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); - return Qnil; - } -} - - - -#line 1878 "parser.c" -static const int JSON_quirks_mode_start = 1; -static const int JSON_quirks_mode_first_final = 10; -static const int JSON_quirks_mode_error = 0; - -static const int JSON_quirks_mode_en_main = 1; - - -#line 749 "parser.rl" - - -static VALUE cParser_parse_quirks_mode(VALUE self) -{ - char *p, *pe; - int cs = EVIL; - VALUE result = Qnil; - GET_PARSER; - - -#line 1897 "parser.c" - { - cs = JSON_quirks_mode_start; - } - -#line 759 "parser.rl" - p = json->source; - pe = p + json->len; - -#line 1906 "parser.c" +#line 1816 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1936,7 +1846,7 @@ case 1: cs = 0; goto _out; tr2: -#line 741 "parser.rl" +#line 682 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1946,7 +1856,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1950 "parser.c" +#line 1860 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2035,30 +1945,13 @@ case 9: _out: {} } -#line 762 "parser.rl" - - if (cs >= JSON_quirks_mode_first_final && p == pe) { - return result; - } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); - return Qnil; - } -} - -/* - * call-seq: parse() - * - * Parses the current JSON text _source_ and returns the complete data - * structure as a result. - */ -static VALUE cParser_parse(VALUE self) -{ - GET_PARSER; +#line 709 "parser.rl" - if (json->quirks_mode) { - return cParser_parse_quirks_mode(self); + if (cs >= JSON_first_final && p == pe) { + return result; } else { - return cParser_parse_strict(self); + rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); + return Qnil; } } @@ -2116,18 +2009,6 @@ static VALUE cParser_source(VALUE self) return rb_str_dup(json->Vsource); } -/* - * call-seq: quirks_mode?() - * - * Returns a true, if this parser is in quirks_mode, false otherwise. - */ -static VALUE cParser_quirks_mode_p(VALUE self) -{ - GET_PARSER; - return json->quirks_mode ? Qtrue : Qfalse; -} - - void Init_parser(void) { rb_require("json/common"); @@ -2140,7 +2021,6 @@ void Init_parser(void) rb_define_method(cParser, "initialize", cParser_initialize, -1); rb_define_method(cParser, "parse", cParser_parse, 0); rb_define_method(cParser, "source", cParser_source, 0); - rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0); CNaN = rb_const_get(mJSON, rb_intern("NaN")); CInfinity = rb_const_get(mJSON, rb_intern("Infinity")); @@ -2154,7 +2034,6 @@ void Init_parser(void) i_max_nesting = rb_intern("max_nesting"); i_allow_nan = rb_intern("allow_nan"); i_symbolize_names = rb_intern("symbolize_names"); - i_quirks_mode = rb_intern("quirks_mode"); i_object_class = rb_intern("object_class"); i_array_class = rb_intern("array_class"); i_match = rb_intern("match"); diff --git a/ext/json/ext/parser/parser.h b/ext/json/ext/parser/parser.h index abcc2571f..ec26e852b 100644 --- a/ext/json/ext/parser/parser.h +++ b/ext/json/ext/parser/parser.h @@ -38,7 +38,6 @@ typedef struct JSON_ParserStruct { int allow_nan; int parsing_name; int symbolize_names; - int quirks_mode; VALUE object_class; VALUE array_class; int create_additions; diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index a34245eb9..5d6933d85 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -77,7 +77,7 @@ static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static VALUE CNaN, CInfinity, CMinusInfinity; static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, - i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode, + i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_aref, i_leftshift; @@ -223,7 +223,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu action parse_number { char *np; - if(pe > fpc + 9 - json->quirks_mode && !strncmp(MinusInfinity, fpc, 9)) { + if(pe > fpc + 8 && !strncmp(MinusInfinity, fpc, 9)) { if (json->allow_nan) { *result = CMinusInfinity; fexec p + 10; @@ -257,7 +257,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu action exit { fhold; fbreak; } -main := ( +main := ignore* ( Vnull @parse_null | Vfalse @parse_false | Vtrue @parse_true | @@ -267,7 +267,7 @@ main := ( begin_string >parse_string | begin_array >parse_array | begin_object >parse_object - ) %*exit; + ) ignore* %*exit; }%% static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -550,8 +550,6 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu static VALUE convert_encoding(VALUE source) { - char *ptr = RSTRING_PTR(source); - long len = RSTRING_LEN(source); #ifdef HAVE_RUBY_ENCODING_H { source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); @@ -624,13 +622,6 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->symbolize_names = 0; } - tmp = ID2SYM(i_quirks_mode); - if (option_given_p(opts, tmp)) { - VALUE quirks_mode = rb_hash_aref(opts, tmp); - json->quirks_mode = RTEST(quirks_mode) ? 1 : 0; - } else { - json->quirks_mode = 0; - } tmp = ID2SYM(i_create_additions); if (option_given_p(opts, tmp)) { json->create_additions = RTEST(rb_hash_aref(opts, tmp)); @@ -672,9 +663,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) json->array_class = Qnil; } source = rb_convert_type(source, T_STRING, "String", "to_str"); - if (!json->quirks_mode) { - source = convert_encoding(StringValue(source)); - } + source = convert_encoding(StringValue(source)); json->current_nesting = 0; StringValue(source); json->len = RSTRING_LEN(source); @@ -690,54 +679,6 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) include JSON_common; - action parse_object { - char *np; - json->current_nesting = 1; - np = JSON_parse_object(json, fpc, pe, &result); - if (np == NULL) { fhold; fbreak; } else fexec np; - } - - action parse_array { - char *np; - json->current_nesting = 1; - np = JSON_parse_array(json, fpc, pe, &result); - if (np == NULL) { fhold; fbreak; } else fexec np; - } - - main := ignore* ( - begin_object >parse_object | - begin_array >parse_array - ) ignore*; -}%% - -static VALUE cParser_parse_strict(VALUE self) -{ - char *p, *pe; - int cs = EVIL; - VALUE result = Qnil; - GET_PARSER; - - %% write init; - p = json->source; - pe = p + json->len; - %% write exec; - - if (cs >= JSON_first_final && p == pe) { - return result; - } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); - return Qnil; - } -} - - -%%{ - machine JSON_quirks_mode; - - write data; - - include JSON_common; - action parse_value { char *np = JSON_parse_value(json, fpc, pe, &result); if (np == NULL) { fhold; fbreak; } else fexec np; @@ -748,26 +689,6 @@ static VALUE cParser_parse_strict(VALUE self) ) ignore*; }%% -static VALUE cParser_parse_quirks_mode(VALUE self) -{ - char *p, *pe; - int cs = EVIL; - VALUE result = Qnil; - GET_PARSER; - - %% write init; - p = json->source; - pe = p + json->len; - %% write exec; - - if (cs >= JSON_quirks_mode_first_final && p == pe) { - return result; - } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); - return Qnil; - } -} - /* * call-seq: parse() * @@ -776,12 +697,21 @@ static VALUE cParser_parse_quirks_mode(VALUE self) */ static VALUE cParser_parse(VALUE self) { + char *p, *pe; + int cs = EVIL; + VALUE result = Qnil; GET_PARSER; - if (json->quirks_mode) { - return cParser_parse_quirks_mode(self); + %% write init; + p = json->source; + pe = p + json->len; + %% write exec; + + if (cs >= JSON_first_final && p == pe) { + return result; } else { - return cParser_parse_strict(self); + rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); + return Qnil; } } @@ -839,18 +769,6 @@ static VALUE cParser_source(VALUE self) return rb_str_dup(json->Vsource); } -/* - * call-seq: quirks_mode?() - * - * Returns a true, if this parser is in quirks_mode, false otherwise. - */ -static VALUE cParser_quirks_mode_p(VALUE self) -{ - GET_PARSER; - return json->quirks_mode ? Qtrue : Qfalse; -} - - void Init_parser(void) { rb_require("json/common"); @@ -863,7 +781,6 @@ void Init_parser(void) rb_define_method(cParser, "initialize", cParser_initialize, -1); rb_define_method(cParser, "parse", cParser_parse, 0); rb_define_method(cParser, "source", cParser_source, 0); - rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0); CNaN = rb_const_get(mJSON, rb_intern("NaN")); CInfinity = rb_const_get(mJSON, rb_intern("Infinity")); @@ -877,7 +794,6 @@ void Init_parser(void) i_max_nesting = rb_intern("max_nesting"); i_allow_nan = rb_intern("allow_nan"); i_symbolize_names = rb_intern("symbolize_names"); - i_quirks_mode = rb_intern("quirks_mode"); i_object_class = rb_intern("object_class"); i_array_class = rb_intern("array_class"); i_match = rb_intern("match"); diff --git a/ext/json/extconf.rb b/ext/json/extconf.rb index 850798c64..7595d58a9 100644 --- a/ext/json/extconf.rb +++ b/ext/json/extconf.rb @@ -1,3 +1,2 @@ require 'mkmf' create_makefile('json') - diff --git a/json.gemspec b/json.gemspec index 75f1ae960a2da154e81c697ff88c8b066106b2b0..5bd9463af2aa23665ba42d1f7afc2adbff21e0a8 100644 GIT binary patch delta 187 zcmX@E^htTcI;P2bypl|M`jg#x)j?DquRMtAmaS;spW5aFOqY3RV6ZYbWhE-vI>Lf z)XPgP*8mIDhq(p?d;0rnD%ja7U?@>H)HBjEP}fA*1hOkJB_%#3wJbF!zaTd?uLQ_0 zNX<)0%}cJ-P%X46PRUQU(@}_4s= Gem::Version.new('1.2.0') then - s.add_development_dependency(%q, ["~> 0.3.16"]) if RUBY_VERSION > "1.8.6" - s.add_development_dependency(%q, ["~> 0.9.2"]) - else - s.add_dependency(%q, ["~> 0.3.16"]) if RUBY_VERSION > "1.8.6" - s.add_dependency(%q, ["~> 0.9.2"]) - end - else - s.add_dependency(%q, ["~> 0.3.16"]) if RUBY_VERSION > "1.8.6" - s.add_dependency(%q, ["~> 0.9.2"]) - end + s.test_files = ["./tests/json_addition_test.rb", "./tests/json_common_interface_test.rb", "./tests/json_encoding_test.rb", "./tests/json_ext_parser_test.rb", "./tests/json_fixtures_test.rb", "./tests/json_generator_test.rb", "./tests/json_generic_object_test.rb", "./tests/json_parser_test.rb", "./tests/json_string_matching_test.rb"] end From 500738e0052eebb306b9e972e2b70065972e45be Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 15 Jun 2015 22:39:32 +0200 Subject: [PATCH 094/312] Disallow usage of symbolize_names and create_additions --- ext/json/ext/parser/parser.c | 26 ++++++++++++++++---------- ext/json/ext/parser/parser.rl | 10 ++++++++-- lib/json/pure/parser.rb | 8 ++++++-- tests/json_common_interface_test.rb | 6 ++---- tests/json_parser_test.rb | 3 +++ 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 34151028e..c63a4621c 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1681,8 +1681,9 @@ static VALUE convert_encoding(VALUE source) * defiance of RFC 4627 to be parsed by the Parser. This option defaults to * false. * * *symbolize_names*: If set to true, returns symbols for the names - * (keys) in a JSON object. Otherwise strings are returned, which is also - * the default. + * (keys) in a JSON object. Otherwise strings are returned, which is + * also the default. It's not possible to use this option in + * conjunction with the *create_additions* option. * * *create_additions*: If set to false, the Parser doesn't create * additions even if a matching class and create_id was found. This option * defaults to false. @@ -1733,6 +1734,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->create_additions = 0; } + if (json->symbolize_names && json->create_additions) { + rb_raise(rb_eArgError, + "options :symbolize_names and :create_additions cannot be " + " used in conjunction"); + } tmp = ID2SYM(i_create_id); if (option_given_p(opts, tmp)) { json->create_id = rb_hash_aref(opts, tmp); @@ -1778,7 +1784,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1782 "parser.c" +#line 1788 "parser.c" static const int JSON_start = 1; static const int JSON_first_final = 10; static const int JSON_error = 0; @@ -1786,7 +1792,7 @@ static const int JSON_error = 0; static const int JSON_en_main = 1; -#line 690 "parser.rl" +#line 696 "parser.rl" /* @@ -1803,16 +1809,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -#line 1807 "parser.c" +#line 1813 "parser.c" { cs = JSON_start; } -#line 706 "parser.rl" +#line 712 "parser.rl" p = json->source; pe = p + json->len; -#line 1816 "parser.c" +#line 1822 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1846,7 +1852,7 @@ case 1: cs = 0; goto _out; tr2: -#line 682 "parser.rl" +#line 688 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1856,7 +1862,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1860 "parser.c" +#line 1866 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1945,7 +1951,7 @@ case 9: _out: {} } -#line 709 "parser.rl" +#line 715 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index 5d6933d85..6f7330790 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -576,8 +576,9 @@ static VALUE convert_encoding(VALUE source) * defiance of RFC 4627 to be parsed by the Parser. This option defaults to * false. * * *symbolize_names*: If set to true, returns symbols for the names - * (keys) in a JSON object. Otherwise strings are returned, which is also - * the default. + * (keys) in a JSON object. Otherwise strings are returned, which is + * also the default. It's not possible to use this option in + * conjunction with the *create_additions* option. * * *create_additions*: If set to false, the Parser doesn't create * additions even if a matching class and create_id was found. This option * defaults to false. @@ -628,6 +629,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->create_additions = 0; } + if (json->symbolize_names && json->create_additions) { + rb_raise(rb_eArgError, + "options :symbolize_names and :create_additions cannot be " + " used in conjunction"); + } tmp = ID2SYM(i_create_id); if (option_given_p(opts, tmp)) { json->create_id = rb_hash_aref(opts, tmp); diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index acabe39cd..c5d1501b1 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -61,8 +61,9 @@ class Parser < StringScanner # defiance of RFC 4627 to be parsed by the Parser. This option defaults # to false. # * *symbolize_names*: If set to true, returns symbols for the names - # (keys) in a JSON object. Otherwise strings are returned, which is also - # the default. + # (keys) in a JSON object. Otherwise strings are returned, which is + # also the default. It's not possible to use this option in + # conjunction with the *create_additions* option. # * *create_additions*: If set to true, the Parser creates # additions when if a matching class and create_id was found. This # option defaults to false. @@ -90,6 +91,9 @@ def initialize(source, opts = {}) else @create_additions = false end + @symbolize_names && @create_additions and raise ArgumentError, + 'options :symbolize_names and :create_additions cannot be used '\ + 'in conjunction' @create_id = @create_additions ? JSON.create_id : nil @object_class = opts[:object_class] || Hash @array_class = opts[:array_class] || Array diff --git a/tests/json_common_interface_test.rb b/tests/json_common_interface_test.rb index 1fca19dbf..9aae2c6fb 100644 --- a/tests/json_common_interface_test.rb +++ b/tests/json_common_interface_test.rb @@ -67,10 +67,8 @@ def test_load end def test_load_with_options - small_hash = JSON("foo" => 'bar') - symbol_hash = { :foo => 'bar' } - assert_equal symbol_hash, - JSON.load(small_hash, nil, :symbolize_names => true) + json = '{ "foo": NaN }' + assert JSON.load(json, nil, :allow_nan => true)['foo'].nan? end def test_dump diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb index 6755e6b74..b21e7ec77 100644 --- a/tests/json_parser_test.rb +++ b/tests/json_parser_test.rb @@ -183,6 +183,9 @@ def test_symbolize_names parse('{"foo":"bar", "baz":"quux"}')) assert_equal({ :foo => "bar", :baz => "quux" }, parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true)) + assert_raise(ArgumentError) do + parse('{}', :symbolize_names => true, :create_additions => true) + end end def test_parse_comments From bf8ef07bf3cf0fe7126b029b888e4054116c7c09 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 15 Jun 2015 14:15:48 +0200 Subject: [PATCH 095/312] Specify JSON module interface --- tests/json_common_interface_test.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/json_common_interface_test.rb b/tests/json_common_interface_test.rb index 9aae2c6fb..648532851 100644 --- a/tests/json_common_interface_test.rb +++ b/tests/json_common_interface_test.rb @@ -2,7 +2,7 @@ require 'stringio' require 'tempfile' -class JSONParserTest < Test::Unit::TestCase +class JSONCommonInterfaceTest < Test::Unit::TestCase include JSON def setup @@ -20,7 +20,6 @@ def setup '"g":"\\"\\u0000\\u001f","h":1.0E3,"i":1.0E-3}' end - def test_index end From 811bc7d0b924453a3ec8ea187ab8e27dda2f162b Mon Sep 17 00:00:00 2001 From: Rebecca Skinner Date: Fri, 21 Aug 2015 19:34:15 +0800 Subject: [PATCH 096/312] Also build against 2.2.3 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 22cb59f39..17bde5dbd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ rvm: - 2.1 - 2.2.1 - 2.2.2 + - 2.2.3 - 2.2 - ree - rbx-2 From 2a6ec15be82172865090a26180e03d1f0c08e39a Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 18 Aug 2015 11:21:09 +0200 Subject: [PATCH 097/312] Remove remnants of GPL licenses --- COPYING | 58 ---- COPYING-json-jruby | 57 ---- GPL | 340 ---------------------- README.rdoc | 4 +- java/src/json/ext/ByteListTranscoder.java | 3 +- java/src/json/ext/Generator.java | 3 +- java/src/json/ext/GeneratorMethods.java | 3 +- java/src/json/ext/GeneratorService.java | 3 +- java/src/json/ext/GeneratorState.java | 3 +- java/src/json/ext/OptionsReader.java | 3 +- java/src/json/ext/Parser.java | 3 +- java/src/json/ext/Parser.rl | 3 +- java/src/json/ext/ParserService.java | 3 +- java/src/json/ext/RuntimeInfo.java | 3 +- java/src/json/ext/StringDecoder.java | 3 +- java/src/json/ext/StringEncoder.java | 5 + java/src/json/ext/Utils.java | 3 +- 17 files changed, 18 insertions(+), 482 deletions(-) delete mode 100644 COPYING delete mode 100644 COPYING-json-jruby delete mode 100644 GPL diff --git a/COPYING b/COPYING deleted file mode 100644 index c3a2126d5..000000000 --- a/COPYING +++ /dev/null @@ -1,58 +0,0 @@ -Ruby is copyrighted free software by Yukihiro Matsumoto . -You can redistribute it and/or modify it under either the terms of the GPL -(see GPL file), or the conditions below: - - 1. You may make and give away verbatim copies of the source form of the - software without restriction, provided that you duplicate all of the - original copyright notices and associated disclaimers. - - 2. You may modify your copy of the software in any way, provided that - you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise - make them Freely Available, such as by posting said - modifications to Usenet or an equivalent medium, or by allowing - the author to include your modifications in the software. - - b) use the modified software only within your corporation or - organization. - - c) rename any non-standard executables so the names do not conflict - with standard executables, which must also be provided. - - d) make other distribution arrangements with the author. - - 3. You may distribute the software in object code or executable - form, provided that you do at least ONE of the following: - - a) distribute the executables and library files of the software, - together with instructions (in the manual page or equivalent) - on where to get the original distribution. - - b) accompany the distribution with the machine-readable source of - the software. - - c) give non-standard executables non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 4. You may modify and include the part of the software into any other - software (possibly commercial). But some files in the distribution - are not written by the author, so that they are not under this terms. - - They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some - files under the ./missing directory. See each file for the copying - condition. - - 5. The scripts and library files supplied as input to or produced as - output from the software do not automatically fall under the - copyright of the software, but belong to whomever generated them, - and may be sold commercially, and may be aggregated with this - software. - - 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. - diff --git a/COPYING-json-jruby b/COPYING-json-jruby deleted file mode 100644 index 137a3da2b..000000000 --- a/COPYING-json-jruby +++ /dev/null @@ -1,57 +0,0 @@ -JSON-JRuby is copyrighted free software by Daniel Luz , -and is a derivative work of Florian Frank's json library . -You can redistribute it and/or modify it under either the terms of the GPL -version 2 (see the file GPL), or the conditions below: - - 1. You may make and give away verbatim copies of the source form of the - software without restriction, provided that you duplicate all of the - original copyright notices and associated disclaimers. - - 2. You may modify your copy of the software in any way, provided that - you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise - make them Freely Available, such as by posting said - modifications to Usenet or an equivalent medium, or by allowing - the author to include your modifications in the software. - - b) use the modified software only within your corporation or - organization. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 3. You may distribute the software in object code or binary form, - provided that you do at least ONE of the following: - - a) distribute the binaries and library files of the software, - together with instructions (in the manual page or equivalent) - on where to get the original distribution. - - b) accompany the distribution with the machine-readable source of - the software. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 4. You may modify and include the part of the software into any other - software (possibly commercial). But some files in the distribution - are not written by the author, so that they are not under these terms. - - For the list of those files and their copying conditions, see the - file LEGAL. - - 5. The scripts and library files supplied as input to or produced as - output from the software do not automatically fall under the - copyright of the software, but belong to whomever generated them, - and may be sold commercially, and may be aggregated with this - software. - - 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. diff --git a/GPL b/GPL deleted file mode 100644 index db2fc4505..000000000 --- a/GPL +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/README.rdoc b/README.rdoc index ebb8b82d1..dad34a9e5 100644 --- a/README.rdoc +++ b/README.rdoc @@ -343,9 +343,7 @@ Florian Frank == License -Ruby License, see the COPYING file included in the source distribution. The -Ruby License includes the GNU General Public License (GPL), Version 2, so see -the file GPL as well. +Ruby License, see https://www.ruby-lang.org/en/about/license.txt. == Download diff --git a/java/src/json/ext/ByteListTranscoder.java b/java/src/json/ext/ByteListTranscoder.java index ed9e54b71..6f6ab66c1 100644 --- a/java/src/json/ext/ByteListTranscoder.java +++ b/java/src/json/ext/ByteListTranscoder.java @@ -1,8 +1,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; diff --git a/java/src/json/ext/Generator.java b/java/src/json/ext/Generator.java index ecceb2709..d9be209f1 100644 --- a/java/src/json/ext/Generator.java +++ b/java/src/json/ext/Generator.java @@ -1,8 +1,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; diff --git a/java/src/json/ext/GeneratorMethods.java b/java/src/json/ext/GeneratorMethods.java index 637b57965..bde7a18d9 100644 --- a/java/src/json/ext/GeneratorMethods.java +++ b/java/src/json/ext/GeneratorMethods.java @@ -1,8 +1,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; diff --git a/java/src/json/ext/GeneratorService.java b/java/src/json/ext/GeneratorService.java index ed3363908..e665ad144 100644 --- a/java/src/json/ext/GeneratorService.java +++ b/java/src/json/ext/GeneratorService.java @@ -1,8 +1,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; diff --git a/java/src/json/ext/GeneratorState.java b/java/src/json/ext/GeneratorState.java index 30653074c..afc7640d9 100644 --- a/java/src/json/ext/GeneratorState.java +++ b/java/src/json/ext/GeneratorState.java @@ -1,8 +1,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; diff --git a/java/src/json/ext/OptionsReader.java b/java/src/json/ext/OptionsReader.java index 821250311..9bb6e64c3 100644 --- a/java/src/json/ext/OptionsReader.java +++ b/java/src/json/ext/OptionsReader.java @@ -1,8 +1,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index 37423f540..5458fb18b 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -3,8 +3,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 6d6596314..d43c74f99 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -1,8 +1,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; diff --git a/java/src/json/ext/ParserService.java b/java/src/json/ext/ParserService.java index dde883479..b6015f964 100644 --- a/java/src/json/ext/ParserService.java +++ b/java/src/json/ext/ParserService.java @@ -1,8 +1,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; diff --git a/java/src/json/ext/RuntimeInfo.java b/java/src/json/ext/RuntimeInfo.java index 5de57407b..ceaca5bad 100644 --- a/java/src/json/ext/RuntimeInfo.java +++ b/java/src/json/ext/RuntimeInfo.java @@ -1,8 +1,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; diff --git a/java/src/json/ext/StringDecoder.java b/java/src/json/ext/StringDecoder.java index 602311387..76cf18375 100644 --- a/java/src/json/ext/StringDecoder.java +++ b/java/src/json/ext/StringDecoder.java @@ -1,8 +1,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; diff --git a/java/src/json/ext/StringEncoder.java b/java/src/json/ext/StringEncoder.java index 57bd19bce..9d40dd383 100644 --- a/java/src/json/ext/StringEncoder.java +++ b/java/src/json/ext/StringEncoder.java @@ -1,3 +1,8 @@ +/* + * This code is copyrighted work by Daniel Luz . + * + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt + */ package json.ext; import org.jruby.exceptions.RaiseException; diff --git a/java/src/json/ext/Utils.java b/java/src/json/ext/Utils.java index 44d6a55ea..ed6f8329e 100644 --- a/java/src/json/ext/Utils.java +++ b/java/src/json/ext/Utils.java @@ -1,8 +1,7 @@ /* * This code is copyrighted work by Daniel Luz . * - * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files - * for details. + * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt */ package json.ext; From 6b1e528468a32471d252fde94ae16471cd534ec4 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 11 Sep 2015 03:26:40 +0200 Subject: [PATCH 098/312] Bump version to 1.8.4 and add to CHANGES --- CHANGES | 8 ++++++++ VERSION | 2 +- lib/json/version.rb | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 8ffecf7c5..143467630 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +2015-09-11 (1.8.4) + * There were still some mentions of dual GPL licensing in the source, but JSON + has just the Ruby license that itself includes an explicit dual-licensing + clause that allows covered software to be distributed under the terms of + the Simplified BSD License instead for all ruby versions >= 1.9.3. This is + however a GPL compatible license according to the Free Software Foundation. + I changed these mentions to be consistent with the Ruby license setting in + the gemspec files which were already correct now. 2015-06-01 (1.8.3) * Fix potential memory leak, thx to nobu. 2015-01-08 (1.8.2) diff --git a/VERSION b/VERSION index a7ee35a3e..bfa363e76 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8.3 +1.8.4 diff --git a/lib/json/version.rb b/lib/json/version.rb index 5a4013dbf..a4696d853 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.8.3' + VERSION = '1.8.4' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: From 14adce7b632244d532e04d80ddf2d79724210a09 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 11 Sep 2015 03:28:03 +0200 Subject: [PATCH 099/312] Remove sdoc and upgrade dependencies --- Rakefile | 17 +++-------------- json.gemspec | Bin 5008 -> 4736 bytes json_pure.gemspec | 19 ++++++++----------- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/Rakefile b/Rakefile index 1d13c2cab..7fa6d9273 100644 --- a/Rakefile +++ b/Rakefile @@ -23,10 +23,6 @@ class UndocumentedTestTask < Rake::TestTask def desc(*) end end -def skip_sdoc(src) - src.gsub(/^.*sdoc.*/) { |s| s + ' if RUBY_VERSION > "1.8.6"' } -end - MAKE = ENV['MAKE'] || %w[gmake make].find { |c| system(c, '-v') } BUNDLE = ENV['BUNDLE'] || %w[bundle].find { |c| system(c, '-v') } PKG_NAME = 'json' @@ -88,8 +84,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.require_path = 'lib' s.add_development_dependency 'permutation' - s.add_development_dependency 'sdoc', '~>0.3.16' - s.add_development_dependency 'rake', '~>0.9.2' + s.add_development_dependency 'rake' s.extra_rdoc_files << 'README.rdoc' s.rdoc_options << @@ -105,7 +100,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) desc 'Creates a json_pure.gemspec file' task :gemspec_pure => :version do File.open('json_pure.gemspec', 'w') do |gemspec| - gemspec.write skip_sdoc(spec_pure.to_ruby) + gemspec.write spec_pure.to_ruby end end @@ -126,7 +121,6 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.require_path = 'lib' s.add_development_dependency 'permutation' - s.add_development_dependency 'sdoc', '~>0.3.16' s.extra_rdoc_files << 'README.rdoc' s.rdoc_options << @@ -142,7 +136,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) desc 'Creates a json.gemspec file' task :gemspec_ext => :version do File.open('json.gemspec', 'w') do |gemspec| - gemspec.write skip_sdoc(spec_ext.to_ruby) + gemspec.write spec_ext.to_ruby end end @@ -341,11 +335,6 @@ else t.options = '-v' end - desc "Create RDOC documentation" - task :doc => [ :version, EXT_PARSER_SRC ] do - sh "sdoc -o doc -t '#{PKG_TITLE}' -m README.rdoc README.rdoc lib/json.rb #{FileList['lib/json/**/*.rb']} #{EXT_PARSER_SRC} #{EXT_GENERATOR_SRC}" - end - desc "Generate parser with ragel" task :ragel => EXT_PARSER_SRC diff --git a/json.gemspec b/json.gemspec index 0b40989f84b991ea34a62dadbee4c3319c9adeb9..b000f87fe7edd55b5627a487c920d25f2f4878d2 100644 GIT binary patch delta 54 zcmbQB-k>@`o6%&V&T1fWV>h#m delta 285 zcmZorouEEJo6&fp&T1fWV>h#zuEFMMjLu9d&i(= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2015-06-01" + s.date = "2015-09-11" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] - s.files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "COPYING", "COPYING-json-jruby", "GPL", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] + s.files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] - s.rubygems_version = "2.4.6" + s.rubygems_version = "2.4.8" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] @@ -25,16 +25,13 @@ Gem::Specification.new do |s| if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, ["~> 0.3.16"]) if RUBY_VERSION > "1.8.6" - s.add_development_dependency(%q, ["~> 0.9.2"]) + s.add_development_dependency(%q, [">= 0"]) else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 0.3.16"]) if RUBY_VERSION > "1.8.6" - s.add_dependency(%q, ["~> 0.9.2"]) + s.add_dependency(%q, [">= 0"]) end else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 0.3.16"]) if RUBY_VERSION > "1.8.6" - s.add_dependency(%q, ["~> 0.9.2"]) + s.add_dependency(%q, [">= 0"]) end end From 18e432c0a60466fd0326e90c890848739689f26b Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 11 Sep 2015 03:31:05 +0200 Subject: [PATCH 100/312] Add 2.2.3 explicitely --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 22cb59f39..17bde5dbd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ rvm: - 2.1 - 2.2.1 - 2.2.2 + - 2.2.3 - 2.2 - ree - rbx-2 From 532fa1430a10acb89e6cd34849e6be7ceaf2f7f2 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 20 Oct 2015 17:52:43 +0200 Subject: [PATCH 101/312] Skip 1.8.4 --- VERSION | 2 +- json.gemspec | Bin 4736 -> 4736 bytes json_pure.gemspec | 6 +++--- lib/json/version.rb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index bfa363e76..8decb929b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8.4 +1.8.5 diff --git a/json.gemspec b/json.gemspec index b000f87fe7edd55b5627a487c920d25f2f4878d2..35efb0e023c67f80d02fa7756ab6ad521f9c6d81 100644 GIT binary patch delta 27 hcmZorZBU({&1gDNXEl(xv5VEvK-b7%^K{0S0swuc2{r%# delta 27 hcmZorZBU({&1f=FXEl(xv5VEfQrFOM^K{0S0swu<2|NG* diff --git a/json_pure.gemspec b/json_pure.gemspec index b72f1a3f6..3020176bb 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -1,14 +1,14 @@ # -*- encoding: utf-8 -*- -# stub: json_pure 1.8.4 ruby lib +# stub: json_pure 1.8.5 ruby lib Gem::Specification.new do |s| s.name = "json_pure" - s.version = "1.8.4" + s.version = "1.8.5" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2015-09-11" + s.date = "2015-10-20" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] diff --git a/lib/json/version.rb b/lib/json/version.rb index a4696d853..2a1709123 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.8.4' + VERSION = '1.8.5' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: From 5f1c9589fadf07ca8bd86ff42b491fcb6332e0ff Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 5 Nov 2015 11:15:23 +0100 Subject: [PATCH 102/312] Fix some links --- README.rdoc | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/README.rdoc b/README.rdoc index dad34a9e5..2410fb7dd 100644 --- a/README.rdoc +++ b/README.rdoc @@ -11,7 +11,7 @@ will be two variants available: * The quite a bit faster native extension variant, which is in parts implemented in C or Java and comes with its own unicode conversion functions and a parser generated by the ragel state machine compiler - http://www.cs.queensu.ca/~thurston/ragel . + http://www.complang.org/ragel/ . Both variants of the JSON generator generate UTF-8 character sequences by default. If an :ascii_only option with a true value is given, they escape all @@ -65,20 +65,9 @@ with: == Compiling the extensions yourself -If you want to build the extensions yourself you need rake: - - You can get it from rubyforge: - http://rubyforge.org/projects/rake - - or just type - - # gem install rake - - for the installation via rubygems. - If you want to create the parser.c file from its parser.rl file or draw nice -graphviz images of the state machines, you need ragel from: http://www.cs.queensu.ca/~thurston/ragel - +graphviz images of the state machines, you need ragel from: +http://www.complang.org/ragel/ == Usage @@ -349,7 +338,7 @@ Ruby License, see https://www.ruby-lang.org/en/about/license.txt. The latest version of this library can be downloaded at -* http://rubyforge.org/frs?group_id=953 +* https://rubygems.org/gems/json Online Documentation should be located at From 5ec2b17a06275726770bb8f7bf38659e07125172 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 6 Nov 2015 16:40:46 +0100 Subject: [PATCH 103/312] Convert README to markdown --- README.rdoc => README.md | 52 +++++++++++++++++++-------------------- Rakefile | 8 +++--- json.gemspec | Bin 4736 -> 4730 bytes json_pure.gemspec | 10 ++++---- 4 files changed, 35 insertions(+), 35 deletions(-) rename README.rdoc => README.md (88%) diff --git a/README.rdoc b/README.md similarity index 88% rename from README.rdoc rename to README.md index 2410fb7dd..7fc6c14c6 100644 --- a/README.rdoc +++ b/README.md @@ -1,6 +1,6 @@ -= JSON implementation for Ruby {}[http://travis-ci.org/flori/json] +# JSON implementation for Ruby {}[http://travis-ci.org/flori/json] -== Description +## Description This is a implementation of the JSON specification according to RFC 4627 http://www.ietf.org/rfc/rfc4627.txt . Starting from version 1.0.0 on there @@ -14,14 +14,14 @@ will be two variants available: http://www.complang.org/ragel/ . Both variants of the JSON generator generate UTF-8 character sequences by -default. If an :ascii_only option with a true value is given, they escape all +default. If an :ascii\_only option with a true value is given, they escape all non-ASCII and control characters with \uXXXX escape sequences, and support UTF-16 surrogate pairs in order to be able to generate the whole range of unicode code points. All strings, that are to be encoded as JSON strings, should be UTF-8 byte sequences on the Ruby side. To encode raw binary strings, that aren't UTF-8 -encoded, please use the to_json_raw_object method of String (which produces +encoded, please use the to\_json\_raw\_object method of String (which produces an object, that contains a byte array) and decode the result on the receiving endpoint. @@ -32,7 +32,7 @@ String#encoding set. If a document string has ASCII-8BIT as an encoding the parser attempts to figure out which of the UTF encodings from above it is and trys to parse it. -== Installation +## Installation It's recommended to use the extension variant of JSON, because it's faster than the pure ruby variant. If you cannot build it on your system, you can settle @@ -63,18 +63,18 @@ with: # gem install json_pure -== Compiling the extensions yourself +## Compiling the extensions yourself If you want to create the parser.c file from its parser.rl file or draw nice graphviz images of the state machines, you need ragel from: http://www.complang.org/ragel/ -== Usage +## Usage To use JSON you can require 'json' to load the installed variant (either the extension 'json' or the pure -variant 'json_pure'). If you have installed the extension variant, you can +variant 'json\_pure'). If you have installed the extension variant, you can pick either the extension variant or the pure variant by typing require 'json/ext' or @@ -87,8 +87,8 @@ Now you can parse a JSON document into a ruby data structure by calling If you want to generate a JSON document from a ruby data structure call JSON.generate(data) -You can also use the pretty_generate method (which formats the output more -verbosely and nicely) or fast_generate (which doesn't do any of the security +You can also use the pretty\_generate method (which formats the output more +verbosely and nicely) or fast\_generate (which doesn't do any of the security checks generate performs, e. g. nesting deepness checks). To create a valid JSON document you have to make sure, that the output is @@ -123,7 +123,7 @@ To get the best compatibility to rails' JSON implementation, you can Both of the additions attempt to require 'json' (like above) first, if it has not been required yet. -== More Examples +## More Examples To create a JSON document from a ruby data structure, you can call JSON.generate like that: @@ -140,11 +140,11 @@ JSON.parse on it: Note, that the range from the original data structure is a simple string now. The reason for this is, that JSON doesn't support ranges or arbitrary classes. In this case the json library falls back to call -Object#to_json, which is the same as #to_s.to_json. +Object#to\_json, which is the same as #to\_s.to\_json. It's possible to add JSON support serialization to arbitrary classes by -simply implementing a more specialized version of the #to_json method, that -should return a JSON object (a hash converted to JSON with #to_json) like +simply implementing a more specialized version of the #to\_json method, that +should return a JSON object (a hash converted to JSON with #to\_json) like this (don't forget the *a for all the arguments): class Range @@ -156,15 +156,15 @@ this (don't forget the *a for all the arguments): end end -The hash key 'json_class' is the class, that will be asked to deserialise the +The hash key 'json\_class' is the class, that will be asked to deserialise the JSON representation later. In this case it's 'Range', but any namespace of the form 'A::B' or '::A::B' will do. All other keys are arbitrary and can be used to store the necessary data to configure the object to be deserialised. -If a the key 'json_class' is found in a JSON object, the JSON parser checks -if the given class responds to the json_create class method. If so, it is +If a the key 'json\_class' is found in a JSON object, the JSON parser checks +if the given class responds to the json\_create class method. If so, it is called with the JSON object converted to a Ruby hash. So a range can -be deserialised by implementing Range.json_create like this: +be deserialised by implementing Range.json\_create like this: class Range def self.json_create(o) @@ -182,7 +182,7 @@ Now it possible to serialise/deserialise ranges as well: JSON.generate always creates the shortest possible string representation of a ruby data structure in one line. This is good for data storage or network protocols, but not so good for humans to read. Fortunately there's also -JSON.pretty_generate (or JSON.pretty_generate) that creates a more readable +JSON.pretty\_generate (or JSON.pretty\_generate) that creates a more readable output: puts JSON.pretty_generate([1, 2, {"a"=>3.141}, false, true, nil, 4..10]) @@ -206,14 +206,14 @@ output: ] There are also the methods Kernel#j for generate, and Kernel#jj for -pretty_generate output to the console, that work analogous to Core Ruby's p and +pretty\_generate output to the console, that work analogous to Core Ruby's p and the pp library's pp methods. The script tools/server.rb contains a small example if you want to test, how receiving a JSON object from a webrick server in your browser with the javasript prototype library http://www.prototypejs.org works. -== Speed Comparisons +## Speed Comparisons I have created some benchmark results (see the benchmarks/data-p4-3Ghz subdir of the package) for the JSON-parser to estimate the speed up in the C @@ -292,10 +292,10 @@ speed: In the table above 1-3 are JSON::Ext::Generator methods. 4, 6, and 7 are JSON::Pure::Generator methods and 5 is the Rails JSON generator. It is now a -bit faster than the generator_safe and generator_pretty methods of the pure +bit faster than the generator\_safe and generator\_pretty methods of the pure variant but slower than the others. -To achieve the fastest JSON document output, you can use the fast_generate +To achieve the fastest JSON document output, you can use the fast\_generate method. Beware, that this will disable the checking for circular Ruby data structures, which may cause JSON to go into an infinite loop. @@ -326,15 +326,15 @@ Here are the median comparisons for completeness' sake: calls/sec ( time) -> speed covers secs/call -== Author +## Author Florian Frank -== License +## License Ruby License, see https://www.ruby-lang.org/en/about/license.txt. -== Download +## Download The latest version of this library can be downloaded at diff --git a/Rakefile b/Rakefile index 7fa6d9273..ab5569cb2 100644 --- a/Rakefile +++ b/Rakefile @@ -86,9 +86,9 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.add_development_dependency 'permutation' s.add_development_dependency 'rake' - s.extra_rdoc_files << 'README.rdoc' + s.extra_rdoc_files << 'README.md' s.rdoc_options << - '--title' << 'JSON implemention for ruby' << '--main' << 'README.rdoc' + '--title' << 'JSON implemention for ruby' << '--main' << 'README.md' s.test_files.concat Dir['./tests/test_*.rb'] s.author = "Florian Frank" @@ -122,9 +122,9 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.require_path = 'lib' s.add_development_dependency 'permutation' - s.extra_rdoc_files << 'README.rdoc' + s.extra_rdoc_files << 'README.md' s.rdoc_options << - '--title' << 'JSON implemention for Ruby' << '--main' << 'README.rdoc' + '--title' << 'JSON implemention for Ruby' << '--main' << 'README.md' s.test_files.concat Dir['./tests/test_*.rb'] s.author = "Florian Frank" diff --git a/json.gemspec b/json.gemspec index 35efb0e023c67f80d02fa7756ab6ad521f9c6d81..286577612c7e3bf34515aa32c93824cf88459a0d 100644 GIT binary patch delta 59 zcmZor{iU*DG9!zju7TO)>5RWPb5oRJxfB$N^)?F%2r*7x#~jU+o3fdgWd%2op1hM^ Omf2L#VDnA>5RX)i&FBFm14OR6pHmWa|;MDPF}+t%>okK%*nEXTLnqF is5GfEJvFyDzAUw= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2015-10-20" + s.date = "2015-11-06" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" - s.extra_rdoc_files = ["README.rdoc"] - s.files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "Gemfile", "README-json-jruby.markdown", "README.rdoc", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] + s.extra_rdoc_files = ["README.md"] + s.files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb", ".gitignore", ".travis.yml", "CHANGES", "Gemfile", "README-json-jruby.markdown", "README.md", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail1.json", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/setup_variant.rb", "tests/test_json.rb", "tests/test_json_addition.rb", "tests/test_json_encoding.rb", "tests/test_json_fixtures.rb", "tests/test_json_generate.rb", "tests/test_json_generic_object.rb", "tests/test_json_string_matching.rb", "tests/test_json_unicode.rb", "tools/fuzz.rb", "tools/server.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] - s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.rdoc"] - s.rubygems_version = "2.4.8" + s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.md"] + s.rubygems_version = "2.5.0" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] From d2a22c030a039d3833a13361c8d0cc2f75e94e5c Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 6 Nov 2015 16:48:43 +0100 Subject: [PATCH 104/312] Correct CHANGES --- CHANGES | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 143467630..cb0019e2a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,4 @@ -2015-09-11 (1.8.4) +2015-09-11 (1.8.5) * There were still some mentions of dual GPL licensing in the source, but JSON has just the Ruby license that itself includes an explicit dual-licensing clause that allows covered software to be distributed under the terms of @@ -6,6 +6,7 @@ however a GPL compatible license according to the Free Software Foundation. I changed these mentions to be consistent with the Ruby license setting in the gemspec files which were already correct now. +---------- (1.8.4) Skipped. 2015-06-01 (1.8.3) * Fix potential memory leak, thx to nobu. 2015-01-08 (1.8.2) From 5fd6c4e168005c68995a97ef436725a01c42dfd9 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 00:10:42 +0100 Subject: [PATCH 105/312] Call OBJECT_HANDLER for objects without #to_json as a last-ditch effort. --- java/src/json/ext/Generator.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/java/src/json/ext/Generator.java b/java/src/json/ext/Generator.java index d9be209f1..bb3a394b9 100644 --- a/java/src/json/ext/Generator.java +++ b/java/src/json/ext/Generator.java @@ -427,11 +427,14 @@ void generate(Session session, IRubyObject object, ByteList buffer) { new Handler() { @Override RubyString generateNew(Session session, IRubyObject object) { - IRubyObject result = - object.callMethod(session.getContext(), "to_json", - new IRubyObject[] {session.getState()}); - if (result instanceof RubyString) return (RubyString)result; - throw session.getRuntime().newTypeError("to_json must return a String"); + if (object.respondsTo("to_json")) { + IRubyObject result = object.callMethod(session.getContext(), "to_json", + new IRubyObject[] {session.getState()}); + if (result instanceof RubyString) return (RubyString)result; + throw session.getRuntime().newTypeError("to_json must return a String"); + } else { + return OBJECT_HANDLER.generateNew(session, object); + } } @Override From bc33e102a6b8babc38f735ce22c973bd59c4588b Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 00:13:04 +0100 Subject: [PATCH 106/312] Add missing tests --- tests/test_json_generate.rb | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index 8db0b7890..3dea970b0 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -1,5 +1,6 @@ #!/usr/bin/env ruby # encoding: utf-8 +# frozen_string_literal: false require 'test/unit' require File.join(File.dirname(__FILE__), 'setup_variant') @@ -334,4 +335,27 @@ def test_json_generate assert_equal true, JSON.generate(["\xea"]) end end + + def test_string_subclass + s = Class.new(String) do + def to_s; self; end + undef to_json + end + assert_nothing_raised(SystemStackError) do + assert_equal '[""]', JSON.generate([s.new]) + end + end + + if EnvUtil.gc_stress_to_class? + def assert_no_memory_leak(code, *rest, **opt) + code = "8.times {20_000.times {begin #{code}; rescue NoMemoryError; end}; GC.start}" + super(["-rjson/ext/generator"], + "GC.add_stress_to_class(JSON::Ext::Generator::State); "\ + "#{code}", code, *rest, rss: true, limit: 1.1, **opt) + end + + def test_no_memory_leak_allocate + assert_no_memory_leak("JSON::Ext::Generator::State.allocate") + end + end end From 111bdfea3a60c8ce169b1a86640ca51093c6b7de Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 00:13:53 +0100 Subject: [PATCH 107/312] Add 2.3.0 for travis teting --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 17bde5dbd..ca87d5c23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ rvm: - 2.2.2 - 2.2.3 - 2.2 + - 2.3.0 - ree - rbx-2 - jruby-18mode From 7a62bde10d24553d7d47d0f5c36e107d4d946785 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 00:19:42 +0100 Subject: [PATCH 108/312] Attempt to switch jruby into 2.0 mode --- .travis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ca87d5c23..70db3f85f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,14 +15,13 @@ rvm: - 2.2 - 2.3.0 - ree - - rbx-2 - - jruby-18mode - - jruby-19mode - ruby-head matrix: + include: + - rvm: jruby + env: JRUBY_OPTS="--2.0" allow_failures: - rvm: rbx-2 - rvm: ruby-head script: "bundle exec rake" - sudo: false From 8d08bb3db9e9e04a5a500c34e44cce4bb04b2ad8 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 00:24:59 +0100 Subject: [PATCH 109/312] =?UTF-8?q?Be=20gone=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_json_generate.rb | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index 3dea970b0..cc8e7cd4a 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -345,17 +345,4 @@ def to_s; self; end assert_equal '[""]', JSON.generate([s.new]) end end - - if EnvUtil.gc_stress_to_class? - def assert_no_memory_leak(code, *rest, **opt) - code = "8.times {20_000.times {begin #{code}; rescue NoMemoryError; end}; GC.start}" - super(["-rjson/ext/generator"], - "GC.add_stress_to_class(JSON::Ext::Generator::State); "\ - "#{code}", code, *rest, rss: true, limit: 1.1, **opt) - end - - def test_no_memory_leak_allocate - assert_no_memory_leak("JSON::Ext::Generator::State.allocate") - end - end end From ed95eebd5b8dd21eab95f86c1bba1285ebf0a414 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 00:45:21 +0100 Subject: [PATCH 110/312] Remove permutation dependency --- Rakefile | 2 -- json.gemspec | Bin 4730 -> 4387 bytes json_pure.gemspec | 7 ++----- tests/test_json.rb | 34 ---------------------------------- 4 files changed, 2 insertions(+), 41 deletions(-) diff --git a/Rakefile b/Rakefile index ab5569cb2..3ff77853f 100644 --- a/Rakefile +++ b/Rakefile @@ -83,7 +83,6 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.files = PKG_FILES s.require_path = 'lib' - s.add_development_dependency 'permutation' s.add_development_dependency 'rake' s.extra_rdoc_files << 'README.md' @@ -120,7 +119,6 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.extensions = FileList['ext/**/extconf.rb'] s.require_path = 'lib' - s.add_development_dependency 'permutation' s.extra_rdoc_files << 'README.md' s.rdoc_options << diff --git a/json.gemspec b/json.gemspec index 286577612c7e3bf34515aa32c93824cf88459a0d..a2c10451151ca76444942dc61dd48274d2c2e241 100644 GIT binary patch delta 32 ocmeyRvRG-u1V(l~RsBa_Y38Ljyk4L4ur_hDp7%}e0|0IFCCaR2}S delta 377 zcmZ3i^h;&K1V(mKT|+}%1GCN38Ljyk4K`oq_hGE(Qc%cDQz+IeN-ZwP&r69f$+uUq zDlSM(&P>ZpPAtjH&xLf)XPgP z*MJDP1_gWi`)MlJ*+Nv*BP&ri)HBjEP}fA*1hOkJB_%#3wJbF!zaTd?uLQ_0NX<)0 z%}cJ-P%X46NG-}OEde{!PDdeH323l^QmiJ}8L2tNsbB`e7<8?%IQ8bG0JXwRfH?zQ MKX&av_i=$R0B1CI5C8xG diff --git a/json_pure.gemspec b/json_pure.gemspec index 0ac2236f0..30d2f81ee 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2015-11-06" + s.date = "2016-02-24" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.md"] @@ -16,7 +16,7 @@ Gem::Specification.new do |s| s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.md"] - s.rubygems_version = "2.5.0" + s.rubygems_version = "2.5.1" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] @@ -24,14 +24,11 @@ Gem::Specification.new do |s| s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) else - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) end else - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) end end diff --git a/tests/test_json.rb b/tests/test_json.rb index 7957773f2..98f7a49f1 100755 --- a/tests/test_json.rb +++ b/tests/test_json.rb @@ -7,20 +7,6 @@ require 'tempfile' require 'ostruct' -unless Array.method_defined?(:permutation) - begin - require 'enumerator' - require 'permutation' - class Array - def permutation - Permutation.for(self).to_enum.map { |x| x.project } - end - end - rescue LoadError - warn "Skipping permutation tests." - end -end - class TestJSON < Test::Unit::TestCase include JSON @@ -146,26 +132,6 @@ def test_parse_json_primitive_values assert_raise(JSON::ParserError) { JSON.parse('[ 1, ]', :quirks_mode => true) } end - if Array.method_defined?(:permutation) - def test_parse_more_complex_arrays - a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }] - a.permutation.each do |perm| - json = pretty_generate(perm) - assert_equal perm, parse(json) - end - end - - def test_parse_complex_objects - a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }] - a.permutation.each do |perm| - s = "a" - orig_obj = perm.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h } - json = pretty_generate(orig_obj) - assert_equal orig_obj, parse(json) - end - end - end - def test_parse_arrays assert_equal([1,2,3], parse('[1,2,3]')) assert_equal([1.2,2,3], parse('[1.2,2,3]')) From 4dec168abb84a9175549e8d03a95a57df6a384e7 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 00:46:14 +0100 Subject: [PATCH 111/312] Avoid system stack error --- ext/json/ext/generator/generator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 6300c64f3..a135e2834 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -871,7 +871,7 @@ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *s } else { tmp = rb_funcall(obj, i_to_s, 0); Check_Type(tmp, T_STRING); - generate_json(buffer, Vstate, state, tmp); + generate_json_string(buffer, Vstate, state, tmp); } } From 4922d2ae6cf93d14f7d51d416f518b5945935b3a Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 00:46:45 +0100 Subject: [PATCH 112/312] Check for existence of #to_json method before call --- lib/json/pure/generator.rb | 12 ++++++++++-- tests/test_json_generate.rb | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index 9056a5d7f..141907447 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -363,7 +363,11 @@ def json_transform(state) result << state.space_before result << ':' result << state.space - result << value.to_json(state) + if value.respond_to?(:to_json) + result << value.to_json(state) + else + result << %{"#{String(value)}"} + end first = false } depth = state.depth -= 1 @@ -398,7 +402,11 @@ def json_transform(state) each { |value| result << delim unless first result << state.indent * depth if indent - result << value.to_json(state) + if value.respond_to?(:to_json) + result << value.to_json(state) + else + result << %{"#{String(value)}"} + end first = false } depth = state.depth -= 1 diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index cc8e7cd4a..95c9266be 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -342,7 +342,7 @@ def to_s; self; end undef to_json end assert_nothing_raised(SystemStackError) do - assert_equal '[""]', JSON.generate([s.new]) + assert_equal '["foo"]', JSON.generate([s.new('foo')]) end end end From ff4e8e9e40c4a065076a6d54517e4ba4c287a8a5 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 10:37:22 +0100 Subject: [PATCH 113/312] Move dependencies into gemspec files --- Gemfile | 3 --- Rakefile | 3 +++ json-java.gemspec | 15 +++++++++++++++ json.gemspec | Bin 4387 -> 4863 bytes json_pure.gemspec | 7 +++++-- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index ef9ce01fc..71fac4735 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,3 @@ source 'https://rubygems.org' gemspec :name => 'json' gemspec :name => 'json_pure' gemspec :name => 'json-java' - -gem 'utils' -gem 'test-unit' diff --git a/Rakefile b/Rakefile index 3ff77853f..fd4e003ff 100644 --- a/Rakefile +++ b/Rakefile @@ -84,6 +84,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.require_path = 'lib' s.add_development_dependency 'rake' + s.add_development_dependency 'test-unit' s.extra_rdoc_files << 'README.md' s.rdoc_options << @@ -119,6 +120,8 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.extensions = FileList['ext/**/extconf.rb'] s.require_path = 'lib' + s.add_development_dependency 'rake' + s.add_development_dependency 'test-unit' s.extra_rdoc_files << 'README.md' s.rdoc_options << diff --git a/json-java.gemspec b/json-java.gemspec index 14864f8c4..e691a3edd 100644 --- a/json-java.gemspec +++ b/json-java.gemspec @@ -14,6 +14,21 @@ spec = Gem::Specification.new do |s| s.licenses = ["Ruby"] s.files = Dir["{docs,lib,tests}/**/*"] + + if s.respond_to? :specification_version then + s.specification_version = 4 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end end if $0 == __FILE__ diff --git a/json.gemspec b/json.gemspec index a2c10451151ca76444942dc61dd48274d2c2e241..d685332de4c2dea23cde29b082993ca1f593f578 100644 GIT binary patch delta 505 zcmZ3i^j~$uG)6|#&C?mJ`4|m0U*`8=tmjft$V^ix)+d2GR;88L4?d3$V&lQ a0kkO@VinAn$hxum44Xn+)&N6^3xok2rJI!i delta 26 icmeybx>#w$G)6{~&C?mJ`4|m1U*`8=WJ%3S;Q|1EXb4jP diff --git a/json_pure.gemspec b/json_pure.gemspec index 30d2f81ee..57562fb08 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2016-02-24" + s.date = "2016-02-25" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.md"] @@ -16,7 +16,7 @@ Gem::Specification.new do |s| s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.md"] - s.rubygems_version = "2.5.1" + s.rubygems_version = "2.5.0" s.summary = "JSON Implementation for Ruby" s.test_files = ["./tests/test_json.rb", "./tests/test_json_addition.rb", "./tests/test_json_encoding.rb", "./tests/test_json_fixtures.rb", "./tests/test_json_generate.rb", "./tests/test_json_generic_object.rb", "./tests/test_json_string_matching.rb", "./tests/test_json_unicode.rb"] @@ -25,10 +25,13 @@ Gem::Specification.new do |s| if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) else s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) end else s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) end end From 8237e6b71ab605629b7e5133c68c017f7ffdf9d5 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 10:40:51 +0100 Subject: [PATCH 114/312] Only test main 2.2 branch --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 70db3f85f..e1ebedae1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,6 @@ rvm: - 1.9.3 - 2.0.0 - 2.1 - - 2.2.1 - - 2.2.2 - - 2.2.3 - 2.2 - 2.3.0 - ree From e99c5d534ab5d6832c292500889bef82c5510828 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 11:35:16 +0100 Subject: [PATCH 115/312] Use ~> 2.0 test-unit that runs on 1.8 rubies as well --- Rakefile | 4 ++-- json-java.gemspec | 6 +++--- json.gemspec | Bin 4863 -> 4869 bytes json_pure.gemspec | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Rakefile b/Rakefile index fd4e003ff..cf19ecc21 100644 --- a/Rakefile +++ b/Rakefile @@ -84,7 +84,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.require_path = 'lib' s.add_development_dependency 'rake' - s.add_development_dependency 'test-unit' + s.add_development_dependency 'test-unit', '~> 2.0' s.extra_rdoc_files << 'README.md' s.rdoc_options << @@ -121,7 +121,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.require_path = 'lib' s.add_development_dependency 'rake' - s.add_development_dependency 'test-unit' + s.add_development_dependency 'test-unit', '~> 2.0' s.extra_rdoc_files << 'README.md' s.rdoc_options << diff --git a/json-java.gemspec b/json-java.gemspec index e691a3edd..1524b1f9a 100644 --- a/json-java.gemspec +++ b/json-java.gemspec @@ -20,14 +20,14 @@ spec = Gem::Specification.new do |s| if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 2.0"]) else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end end diff --git a/json.gemspec b/json.gemspec index d685332de4c2dea23cde29b082993ca1f593f578..d0b0674683a2332712f792d0fd6fdbb98408b0fa 100644 GIT binary patch delta 48 scmeyb+N!oeS%|gHPQgfTvYJpLl+`7aECLoYP>R*$Qcy_EOW^`x08q#b=>Px# delta 42 qcmZow`>(n|S%}%rR$;P+P$HP_6G|2W@(q+?HMtZNQu9){Ko|h~Tnh#O diff --git a/json_pure.gemspec b/json_pure.gemspec index 57562fb08..dfd90b0e5 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -25,13 +25,13 @@ Gem::Specification.new do |s| if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 2.0"]) else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end end From 5bda8c9252e70ebb3ab5da1be7eb668e1050285f Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 11:35:16 +0100 Subject: [PATCH 116/312] Use ~> 2.0 test-unit that runs on 1.8 rubies as well --- Rakefile | 3 +++ json-java.gemspec | 15 +++++++++++++++ json.gemspec | Bin 3962 -> 4444 bytes json_pure.gemspec | 3 +++ 4 files changed, 21 insertions(+) diff --git a/Rakefile b/Rakefile index 3b99c608c..4aa311e57 100644 --- a/Rakefile +++ b/Rakefile @@ -84,6 +84,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.require_path = 'lib' s.add_development_dependency 'rake' + s.add_development_dependency 'test-unit', '~> 2.0' s.extra_rdoc_files << 'README.md' s.rdoc_options << @@ -119,6 +120,8 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.extensions = FileList['ext/**/extconf.rb'] s.require_path = 'lib' + s.add_development_dependency 'rake' + s.add_development_dependency 'test-unit', '~> 2.0' s.extra_rdoc_files << 'README.md' s.rdoc_options << diff --git a/json-java.gemspec b/json-java.gemspec index 14864f8c4..1524b1f9a 100644 --- a/json-java.gemspec +++ b/json-java.gemspec @@ -14,6 +14,21 @@ spec = Gem::Specification.new do |s| s.licenses = ["Ruby"] s.files = Dir["{docs,lib,tests}/**/*"] + + if s.respond_to? :specification_version then + s.specification_version = 4 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 2.0"]) + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) + end + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) + end end if $0 == __FILE__ diff --git a/json.gemspec b/json.gemspec index 00f074463efff9a576e9b072ae9f28546342618c..a9493ff60a417c5cd266723aa9a2249adf5029ed 100644 GIT binary patch delta 497 zcmb7=!3u&v5QgtwdV?5*NTH;nla!qzx)c<2i4buoTB_09&FGS^)C2V-o!S&j!iWyb zF2nc#AG7!BO~1yKL<8V!5LSdD42Zch7=SH8^!b|mp5y_!F-Ah&AU8+~2St|yeduZ_ zpc+TGx9vriv= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 2.0"]) else s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end else s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end end From 6e226a12479f482db7b4b4fe1a539d5db5fc9c45 Mon Sep 17 00:00:00 2001 From: Edoardo Rossi Date: Wed, 6 Apr 2016 12:44:04 +0200 Subject: [PATCH 117/312] Update README.md with formatting --- README.md | 208 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 133 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 7fc6c14c6..ea0810f20 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# JSON implementation for Ruby {}[http://travis-ci.org/flori/json] +# JSON implementation for Ruby ![Travis Widget] +[Travis Widget]: http://travis-ci.org/flori/json.svg?branch=master ## Description @@ -40,113 +41,155 @@ for the latter. Just type into the command line as root: - # rake install +``` +# rake install +``` The above command will build the extensions and install them on your system. - # rake install_pure +``` +# rake install_pure +``` or - # ruby install.rb +``` +# ruby install.rb +``` will just install the pure ruby implementation of JSON. If you use Rubygems you can type - # gem install json +``` +# gem install json +``` instead, to install the newest JSON version. There is also a pure ruby json only variant of the gem, that can be installed with: - # gem install json_pure +``` +# gem install json_pure +``` ## Compiling the extensions yourself -If you want to create the parser.c file from its parser.rl file or draw nice +If you want to create the `parser.c` file from its `parser.rl` file or draw nice graphviz images of the state machines, you need ragel from: http://www.complang.org/ragel/ ## Usage To use JSON you can - require 'json' -to load the installed variant (either the extension 'json' or the pure -variant 'json\_pure'). If you have installed the extension variant, you can + +```ruby +require 'json' +``` + +to load the installed variant (either the extension `'json'` or the pure +variant `'json_pure'`). If you have installed the extension variant, you can pick either the extension variant or the pure variant by typing - require 'json/ext' + +```ruby +require 'json/ext' +``` + or - require 'json/pure' + +```ruby +require 'json/pure' +``` Now you can parse a JSON document into a ruby data structure by calling - JSON.parse(document) +```ruby +JSON.parse(document) +``` If you want to generate a JSON document from a ruby data structure call - JSON.generate(data) +```ruby +JSON.generate(data) +``` -You can also use the pretty\_generate method (which formats the output more -verbosely and nicely) or fast\_generate (which doesn't do any of the security +You can also use the `pretty_generate` method (which formats the output more +verbosely and nicely) or `fast_generate` (which doesn't do any of the security checks generate performs, e. g. nesting deepness checks). To create a valid JSON document you have to make sure, that the output is -embedded in either a JSON array [] or a JSON object {}. The easiest way to do +embedded in either a JSON array `[]` or a JSON object `{}`. The easiest way to do this, is by putting your values in a Ruby Array or Hash instance. -There are also the JSON and JSON[] methods which use parse on a String or +There are also the `JSON` and `JSON[]` methods which use parse on a String or generate a JSON document from an array or hash: - document = JSON 'test' => 23 # => "{\"test\":23}" - document = JSON['test'] => 23 # => "{\"test\":23}" +```ruby +document = JSON 'test' => 23 # => "{\"test\":23}" +document = JSON['test'] => 23 # => "{\"test\":23}" +``` and - data = JSON '{"test":23}' # => {"test"=>23} - data = JSON['{"test":23}'] # => {"test"=>23} +```ruby +data = JSON '{"test":23}' # => {"test"=>23} +data = JSON['{"test":23}'] # => {"test"=>23} +``` You can choose to load a set of common additions to ruby core's objects if you - require 'json/add/core' + +```ruby +require 'json/add/core' +``` After requiring this you can, e. g., serialise/deserialise Ruby ranges: - JSON JSON(1..10) # => 1..10 +```ruby +JSON JSON(1..10) # => 1..10 +``` To find out how to add JSON support to other or your own classes, read the section "More Examples" below. To get the best compatibility to rails' JSON implementation, you can - require 'json/add/rails' -Both of the additions attempt to require 'json' (like above) first, if it has +```ruby +require 'json/add/rails' +``` + +Both of the additions attempt to require `'json'` (like above) first, if it has not been required yet. ## More Examples To create a JSON document from a ruby data structure, you can call -JSON.generate like that: +`JSON.generate` like that: - json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] - # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]" +```ruby +json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +# => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]" +``` To get back a ruby data structure from a JSON document, you have to call JSON.parse on it: - JSON.parse json - # => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"] +```ruby +JSON.parse json +# => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"] +``` Note, that the range from the original data structure is a simple string now. The reason for this is, that JSON doesn't support ranges or arbitrary classes. In this case the json library falls back to call -Object#to\_json, which is the same as #to\_s.to\_json. +`Object#to_json`, which is the same as `#to_s.to_json`. It's possible to add JSON support serialization to arbitrary classes by -simply implementing a more specialized version of the #to\_json method, that -should return a JSON object (a hash converted to JSON with #to\_json) like -this (don't forget the *a for all the arguments): +simply implementing a more specialized version of the `#to_json method`, that +should return a JSON object (a hash converted to JSON with `#to_json`) like +this (don't forget the `*a` for all the arguments): +```ruby class Range def to_json(*a) { @@ -155,36 +198,42 @@ this (don't forget the *a for all the arguments): }.to_json(*a) end end +``` -The hash key 'json\_class' is the class, that will be asked to deserialise the -JSON representation later. In this case it's 'Range', but any namespace of -the form 'A::B' or '::A::B' will do. All other keys are arbitrary and can be +The hash key `json_class` is the class, that will be asked to deserialise the +JSON representation later. In this case it's `Range`, but any namespace of +the form `A::B` or `::A::B` will do. All other keys are arbitrary and can be used to store the necessary data to configure the object to be deserialised. -If a the key 'json\_class' is found in a JSON object, the JSON parser checks -if the given class responds to the json\_create class method. If so, it is +If a the key `json_class` is found in a JSON object, the JSON parser checks +if the given class responds to the `json_create` class method. If so, it is called with the JSON object converted to a Ruby hash. So a range can -be deserialised by implementing Range.json\_create like this: +be deserialised by implementing `Range.json_create` like this: +```ruby class Range def self.json_create(o) new(*o['data']) end end +``` Now it possible to serialise/deserialise ranges as well: +```ruby json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] # => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]" JSON.parse json # => [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +``` -JSON.generate always creates the shortest possible string representation of a +`JSON.generate` always creates the shortest possible string representation of a ruby data structure in one line. This is good for data storage or network protocols, but not so good for humans to read. Fortunately there's also -JSON.pretty\_generate (or JSON.pretty\_generate) that creates a more readable +`JSON.pretty_generate` (or `JSON.pretty_generate`) that creates a more readable output: +```ruby puts JSON.pretty_generate([1, 2, {"a"=>3.141}, false, true, nil, 4..10]) [ 1, @@ -204,12 +253,13 @@ output: ] } ] +``` -There are also the methods Kernel#j for generate, and Kernel#jj for -pretty\_generate output to the console, that work analogous to Core Ruby's p and -the pp library's pp methods. +There are also the methods `Kernel#j` for generate, and `Kernel#jj` for +`pretty_generate` output to the console, that work analogous to Core Ruby's `p` and +the `pp` library's `pp` methods. -The script tools/server.rb contains a small example if you want to test, how +The script `tools/server.rb` contains a small example if you want to test, how receiving a JSON object from a webrick server in your browser with the javasript prototype library http://www.prototypejs.org works. @@ -219,67 +269,72 @@ I have created some benchmark results (see the benchmarks/data-p4-3Ghz subdir of the package) for the JSON-parser to estimate the speed up in the C extension: +``` Comparing times (call_time_mean): 1 ParserBenchmarkExt#parser 900 repeats: - 553.922304770 ( real) -> 21.500x + 553.922304770 ( real) -> 21.500x 0.001805307 2 ParserBenchmarkYAML#parser 1000 repeats: - 224.513358139 ( real) -> 8.714x + 224.513358139 ( real) -> 8.714x 0.004454078 3 ParserBenchmarkPure#parser 1000 repeats: - 26.755020642 ( real) -> 1.038x + 26.755020642 ( real) -> 1.038x 0.037376163 4 ParserBenchmarkRails#parser 1000 repeats: - 25.763381731 ( real) -> 1.000x + 25.763381731 ( real) -> 1.000x 0.038814780 calls/sec ( time) -> speed covers secs/call +``` -In the table above 1 is JSON::Ext::Parser, 2 is YAML.load with YAML -compatbile JSON document, 3 is is JSON::Pure::Parser, and 4 is -ActiveSupport::JSON.decode. The ActiveSupport JSON-decoder converts the +In the table above 1 is `JSON::Ext::Parser`, 2 is `YAML.load` with YAML +compatbile JSON document, 3 is is `JSON::Pure::Parser`, and 4 is +`ActiveSupport::JSON.decode`. The ActiveSupport JSON-decoder converts the input first to YAML and then uses the YAML-parser, the conversion seems to -slow it down so much that it is only as fast as the JSON::Pure::Parser! +slow it down so much that it is only as fast as the `JSON::Pure::Parser`! If you look at the benchmark data you can see that this is mostly caused by the frequent high outliers - the median of the Rails-parser runs is still -overall smaller than the median of the JSON::Pure::Parser runs: +overall smaller than the median of the `JSON::Pure::Parser` runs: +``` Comparing times (call_time_median): 1 ParserBenchmarkExt#parser 900 repeats: - 800.592479481 ( real) -> 26.936x + 800.592479481 ( real) -> 26.936x 0.001249075 2 ParserBenchmarkYAML#parser 1000 repeats: - 271.002390644 ( real) -> 9.118x + 271.002390644 ( real) -> 9.118x 0.003690004 3 ParserBenchmarkRails#parser 1000 repeats: - 30.227910865 ( real) -> 1.017x + 30.227910865 ( real) -> 1.017x 0.033082008 4 ParserBenchmarkPure#parser 1000 repeats: - 29.722384421 ( real) -> 1.000x + 29.722384421 ( real) -> 1.000x 0.033644676 calls/sec ( time) -> speed covers secs/call +``` -I have benchmarked the JSON-Generator as well. This generated a few more +I have benchmarked the `JSON-Generator` as well. This generated a few more values, because there are different modes that also influence the achieved speed: +``` Comparing times (call_time_mean): 1 GeneratorBenchmarkExt#generator_fast 1000 repeats: - 547.354332608 ( real) -> 15.090x + 547.354332608 ( real) -> 15.090x 0.001826970 2 GeneratorBenchmarkExt#generator_safe 1000 repeats: - 443.968212317 ( real) -> 12.240x + 443.968212317 ( real) -> 12.240x 0.002252414 3 GeneratorBenchmarkExt#generator_pretty 900 repeats: - 375.104545883 ( real) -> 10.341x + 375.104545883 ( real) -> 10.341x 0.002665923 4 GeneratorBenchmarkPure#generator_fast 1000 repeats: - 49.978706968 ( real) -> 1.378x + 49.978706968 ( real) -> 1.378x 0.020008521 5 GeneratorBenchmarkRails#generator 1000 repeats: - 38.531868759 ( real) -> 1.062x + 38.531868759 ( real) -> 1.062x 0.025952543 6 GeneratorBenchmarkPure#generator_safe 1000 repeats: 36.927649925 ( real) -> 1.018x 7 (>=3859) @@ -289,33 +344,35 @@ speed: 0.027569373 calls/sec ( time) -> speed covers secs/call +``` -In the table above 1-3 are JSON::Ext::Generator methods. 4, 6, and 7 are -JSON::Pure::Generator methods and 5 is the Rails JSON generator. It is now a -bit faster than the generator\_safe and generator\_pretty methods of the pure +In the table above 1-3 are `JSON::Ext::Generator` methods. 4, 6, and 7 are +`JSON::Pure::Generator` methods and 5 is the Rails JSON generator. It is now a +bit faster than the `generator_safe` and `generator_pretty` methods of the pure variant but slower than the others. -To achieve the fastest JSON document output, you can use the fast\_generate +To achieve the fastest JSON document output, you can use the `fast_generate` method. Beware, that this will disable the checking for circular Ruby data structures, which may cause JSON to go into an infinite loop. Here are the median comparisons for completeness' sake: +``` Comparing times (call_time_median): 1 GeneratorBenchmarkExt#generator_fast 1000 repeats: - 708.258020939 ( real) -> 16.547x + 708.258020939 ( real) -> 16.547x 0.001411915 2 GeneratorBenchmarkExt#generator_safe 1000 repeats: - 569.105020353 ( real) -> 13.296x + 569.105020353 ( real) -> 13.296x 0.001757145 3 GeneratorBenchmarkExt#generator_pretty 900 repeats: - 482.825371244 ( real) -> 11.280x + 482.825371244 ( real) -> 11.280x 0.002071142 4 GeneratorBenchmarkPure#generator_fast 1000 repeats: - 62.717626652 ( real) -> 1.465x + 62.717626652 ( real) -> 1.465x 0.015944481 5 GeneratorBenchmarkRails#generator 1000 repeats: - 43.965681162 ( real) -> 1.027x + 43.965681162 ( real) -> 1.027x 0.022745013 6 GeneratorBenchmarkPure#generator_safe 1000 repeats: 43.929073409 ( real) -> 1.026x 7 (>=3859) @@ -325,6 +382,7 @@ Here are the median comparisons for completeness' sake: 0.023363113 calls/sec ( time) -> speed covers secs/call +``` ## Author From f931291a053caacd7396cff1fbcc336e50b2cdb7 Mon Sep 17 00:00:00 2001 From: Marcus Stollsteimer Date: Mon, 25 Apr 2016 20:25:05 +0200 Subject: [PATCH 118/312] Remove comments from core classes in json/add --- lib/json/add/date.rb | 1 - lib/json/add/date_time.rb | 1 - lib/json/add/exception.rb | 1 - lib/json/add/ostruct.rb | 1 - lib/json/add/range.rb | 1 - lib/json/add/regexp.rb | 1 - lib/json/add/struct.rb | 1 - lib/json/add/symbol.rb | 1 - lib/json/add/time.rb | 1 - 9 files changed, 9 deletions(-) diff --git a/lib/json/add/date.rb b/lib/json/add/date.rb index 4288237db..458d9eba9 100644 --- a/lib/json/add/date.rb +++ b/lib/json/add/date.rb @@ -3,7 +3,6 @@ end require 'date' -# Date serialization/deserialization class Date # Deserializes JSON string by converting Julian year y, month diff --git a/lib/json/add/date_time.rb b/lib/json/add/date_time.rb index 5ea42ea65..a1009cf5d 100644 --- a/lib/json/add/date_time.rb +++ b/lib/json/add/date_time.rb @@ -3,7 +3,6 @@ end require 'date' -# DateTime serialization/deserialization class DateTime # Deserializes JSON string by converting year y, month m, diff --git a/lib/json/add/exception.rb b/lib/json/add/exception.rb index e6ad257ab..f4b150d23 100644 --- a/lib/json/add/exception.rb +++ b/lib/json/add/exception.rb @@ -2,7 +2,6 @@ require 'json' end -# Exception serialization/deserialization class Exception # Deserializes JSON string by constructing new Exception object with message diff --git a/lib/json/add/ostruct.rb b/lib/json/add/ostruct.rb index da81e107a..a62f92f59 100644 --- a/lib/json/add/ostruct.rb +++ b/lib/json/add/ostruct.rb @@ -3,7 +3,6 @@ end require 'ostruct' -# OpenStruct serialization/deserialization class OpenStruct # Deserializes JSON string by constructing new Struct object with values diff --git a/lib/json/add/range.rb b/lib/json/add/range.rb index e61e553cd..0df382c60 100644 --- a/lib/json/add/range.rb +++ b/lib/json/add/range.rb @@ -2,7 +2,6 @@ require 'json' end -# Range serialization/deserialization class Range # Deserializes JSON string by constructing new Range object with arguments diff --git a/lib/json/add/regexp.rb b/lib/json/add/regexp.rb index 2fcbb6fb1..9adf06c8f 100644 --- a/lib/json/add/regexp.rb +++ b/lib/json/add/regexp.rb @@ -2,7 +2,6 @@ require 'json' end -# Regexp serialization/deserialization class Regexp # Deserializes JSON string by constructing new Regexp object with source diff --git a/lib/json/add/struct.rb b/lib/json/add/struct.rb index 6847cde99..e1e24800d 100644 --- a/lib/json/add/struct.rb +++ b/lib/json/add/struct.rb @@ -2,7 +2,6 @@ require 'json' end -# Struct serialization/deserialization class Struct # Deserializes JSON string by constructing new Struct object with values diff --git a/lib/json/add/symbol.rb b/lib/json/add/symbol.rb index 03dc9a56a..6df77cab0 100644 --- a/lib/json/add/symbol.rb +++ b/lib/json/add/symbol.rb @@ -2,7 +2,6 @@ require 'json' end -# Symbol serialization/deserialization class Symbol # Returns a hash, that will be turned into a JSON object and represent this # object. diff --git a/lib/json/add/time.rb b/lib/json/add/time.rb index d9834677a..122750828 100644 --- a/lib/json/add/time.rb +++ b/lib/json/add/time.rb @@ -2,7 +2,6 @@ require 'json' end -# Time serialization/deserialization class Time # Deserializes JSON string by converting time since epoch to Time From 53b66c76f346ef927bde16c97d404a7612d96449 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 2 Jun 2016 10:08:26 +0200 Subject: [PATCH 119/312] Declare encoding --- tests/json_encoding_test.rb | 1 + tests/json_parser_test.rb | 2 ++ 2 files changed, 3 insertions(+) diff --git a/tests/json_encoding_test.rb b/tests/json_encoding_test.rb index 86335a1c7..c220f90c7 100644 --- a/tests/json_encoding_test.rb +++ b/tests/json_encoding_test.rb @@ -1,3 +1,4 @@ +# encoding: utf-8 require 'test_helper' class JSONEncodingTest < Test::Unit::TestCase diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb index b21e7ec77..1123aaba0 100644 --- a/tests/json_parser_test.rb +++ b/tests/json_parser_test.rb @@ -1,3 +1,5 @@ +# encoding: utf-8 + require 'test_helper' require 'stringio' require 'tempfile' From cca0565febed4006398d4fc2f85d99d7020f75df Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 2 Jun 2016 11:53:19 +0200 Subject: [PATCH 120/312] Allow usage of simplecov with START_SIMPLECOV=1 --- Gemfile | 2 ++ tests/test_helper.rb | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/Gemfile b/Gemfile index 71fac4735..51ff10afc 100644 --- a/Gemfile +++ b/Gemfile @@ -5,3 +5,5 @@ source 'https://rubygems.org' gemspec :name => 'json' gemspec :name => 'json_pure' gemspec :name => 'json-java' + +gem 'simplecov' diff --git a/tests/test_helper.rb b/tests/test_helper.rb index 752f5f536..9d3665d47 100644 --- a/tests/test_helper.rb +++ b/tests/test_helper.rb @@ -17,3 +17,7 @@ require 'byebug' rescue LoadError end +if ENV['START_SIMPLECOV'].to_i == 1 + require 'simplecov' + SimpleCov.start +end From cc5083707b7e6cb8699e505cd434bc7f4521412d Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 2 Jun 2016 12:48:16 +0200 Subject: [PATCH 121/312] current RFC added --- references/rfc7159.txt | 899 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 899 insertions(+) create mode 100644 references/rfc7159.txt diff --git a/references/rfc7159.txt b/references/rfc7159.txt new file mode 100644 index 000000000..64fcada43 --- /dev/null +++ b/references/rfc7159.txt @@ -0,0 +1,899 @@ + + + + + + +Internet Engineering Task Force (IETF) T. Bray, Ed. +Request for Comments: 7159 Google, Inc. +Obsoletes: 4627, 7158 March 2014 +Category: Standards Track +ISSN: 2070-1721 + + + The JavaScript Object Notation (JSON) Data Interchange Format + +Abstract + + JavaScript Object Notation (JSON) is a lightweight, text-based, + language-independent data interchange format. It was derived from + the ECMAScript Programming Language Standard. JSON defines a small + set of formatting rules for the portable representation of structured + data. + + This document removes inconsistencies with other specifications of + JSON, repairs specification errors, and offers experience-based + interoperability guidance. + +Status of This Memo + + This is an Internet Standards Track document. + + This document is a product of the Internet Engineering Task Force + (IETF). It represents the consensus of the IETF community. It has + received public review and has been approved for publication by the + Internet Engineering Steering Group (IESG). Further information on + Internet Standards is available in Section 2 of RFC 5741. + + Information about the current status of this document, any errata, + and how to provide feedback on it may be obtained at + http://www.rfc-editor.org/info/rfc7159. + + + + + + + + + + + + + + + + + +Bray Standards Track [Page 1] + +RFC 7159 JSON March 2014 + + +Copyright Notice + + Copyright (c) 2014 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. Code Components extracted from this document must + include Simplified BSD License text as described in Section 4.e of + the Trust Legal Provisions and are provided without warranty as + described in the Simplified BSD License. + + This document may contain material from IETF Documents or IETF + Contributions published or made publicly available before November + 10, 2008. The person(s) controlling the copyright in some of this + material may not have granted the IETF Trust the right to allow + modifications of such material outside the IETF Standards Process. + Without obtaining an adequate license from the person(s) controlling + the copyright in such materials, this document may not be modified + outside the IETF Standards Process, and derivative works of it may + not be created outside the IETF Standards Process, except to format + it for publication as an RFC or to translate it into languages other + than English. + + + + + + + + + + + + + + + + + + + + + + + + + +Bray Standards Track [Page 2] + +RFC 7159 JSON March 2014 + + +Table of Contents + + 1. Introduction ....................................................3 + 1.1. Conventions Used in This Document ..........................4 + 1.2. Specifications of JSON .....................................4 + 1.3. Introduction to This Revision ..............................4 + 2. JSON Grammar ....................................................4 + 3. Values ..........................................................5 + 4. Objects .........................................................6 + 5. Arrays ..........................................................6 + 6. Numbers .........................................................6 + 7. Strings .........................................................8 + 8. String and Character Issues .....................................9 + 8.1. Character Encoding .........................................9 + 8.2. Unicode Characters .........................................9 + 8.3. String Comparison ..........................................9 + 9. Parsers ........................................................10 + 10. Generators ....................................................10 + 11. IANA Considerations ...........................................10 + 12. Security Considerations .......................................11 + 13. Examples ......................................................12 + 14. Contributors ..................................................13 + 15. References ....................................................13 + 15.1. Normative References .....................................13 + 15.2. Informative References ...................................13 + Appendix A. Changes from RFC 4627 .................................15 + +1. Introduction + + JavaScript Object Notation (JSON) is a text format for the + serialization of structured data. It is derived from the object + literals of JavaScript, as defined in the ECMAScript Programming + Language Standard, Third Edition [ECMA-262]. + + JSON can represent four primitive types (strings, numbers, booleans, + and null) and two structured types (objects and arrays). + + A string is a sequence of zero or more Unicode characters [UNICODE]. + Note that this citation references the latest version of Unicode + rather than a specific release. It is not expected that future + changes in the UNICODE specification will impact the syntax of JSON. + + An object is an unordered collection of zero or more name/value + pairs, where a name is a string and a value is a string, number, + boolean, null, object, or array. + + An array is an ordered sequence of zero or more values. + + + + +Bray Standards Track [Page 3] + +RFC 7159 JSON March 2014 + + + The terms "object" and "array" come from the conventions of + JavaScript. + + JSON's design goals were for it to be minimal, portable, textual, and + a subset of JavaScript. + +1.1. Conventions Used in This Document + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in [RFC2119]. + + The grammatical rules in this document are to be interpreted as + described in [RFC5234]. + +1.2. Specifications of JSON + + This document updates [RFC4627], which describes JSON and registers + the media type "application/json". + + A description of JSON in ECMAScript terms appears in Version 5.1 of + the ECMAScript specification [ECMA-262], Section 15.12. JSON is also + described in [ECMA-404]. + + All of the specifications of JSON syntax agree on the syntactic + elements of the language. + +1.3. Introduction to This Revision + + In the years since the publication of RFC 4627, JSON has found very + wide use. This experience has revealed certain patterns, which, + while allowed by its specifications, have caused interoperability + problems. + + Also, a small number of errata have been reported (see RFC Errata IDs + 607 [Err607] and 3607 [Err3607]). + + This document's goal is to apply the errata, remove inconsistencies + with other specifications of JSON, and highlight practices that can + lead to interoperability problems. + +2. JSON Grammar + + A JSON text is a sequence of tokens. The set of tokens includes six + structural characters, strings, numbers, and three literal names. + + A JSON text is a serialized value. Note that certain previous + specifications of JSON constrained a JSON text to be an object or an + + + +Bray Standards Track [Page 4] + +RFC 7159 JSON March 2014 + + + array. Implementations that generate only objects or arrays where a + JSON text is called for will be interoperable in the sense that all + implementations will accept these as conforming JSON texts. + + JSON-text = ws value ws + + These are the six structural characters: + + begin-array = ws %x5B ws ; [ left square bracket + + begin-object = ws %x7B ws ; { left curly bracket + + end-array = ws %x5D ws ; ] right square bracket + + end-object = ws %x7D ws ; } right curly bracket + + name-separator = ws %x3A ws ; : colon + + value-separator = ws %x2C ws ; , comma + + Insignificant whitespace is allowed before or after any of the six + structural characters. + + ws = *( + %x20 / ; Space + %x09 / ; Horizontal tab + %x0A / ; Line feed or New line + %x0D ) ; Carriage return + +3. Values + + A JSON value MUST be an object, array, number, or string, or one of + the following three literal names: + + false null true + + The literal names MUST be lowercase. No other literal names are + allowed. + + value = false / null / true / object / array / number / string + + false = %x66.61.6c.73.65 ; false + + null = %x6e.75.6c.6c ; null + + true = %x74.72.75.65 ; true + + + + + +Bray Standards Track [Page 5] + +RFC 7159 JSON March 2014 + + +4. Objects + + An object structure is represented as a pair of curly brackets + surrounding zero or more name/value pairs (or members). A name is a + string. A single colon comes after each name, separating the name + from the value. A single comma separates a value from a following + name. The names within an object SHOULD be unique. + + object = begin-object [ member *( value-separator member ) ] + end-object + + member = string name-separator value + + An object whose names are all unique is interoperable in the sense + that all software implementations receiving that object will agree on + the name-value mappings. When the names within an object are not + unique, the behavior of software that receives such an object is + unpredictable. Many implementations report the last name/value pair + only. Other implementations report an error or fail to parse the + object, and some implementations report all of the name/value pairs, + including duplicates. + + JSON parsing libraries have been observed to differ as to whether or + not they make the ordering of object members visible to calling + software. Implementations whose behavior does not depend on member + ordering will be interoperable in the sense that they will not be + affected by these differences. + +5. Arrays + + An array structure is represented as square brackets surrounding zero + or more values (or elements). Elements are separated by commas. + + array = begin-array [ value *( value-separator value ) ] end-array + + There is no requirement that the values in an array be of the same + type. + +6. Numbers + + The representation of numbers is similar to that used in most + programming languages. A number is represented in base 10 using + decimal digits. It contains an integer component that may be + prefixed with an optional minus sign, which may be followed by a + fraction part and/or an exponent part. Leading zeros are not + allowed. + + A fraction part is a decimal point followed by one or more digits. + + + +Bray Standards Track [Page 6] + +RFC 7159 JSON March 2014 + + + An exponent part begins with the letter E in upper or lower case, + which may be followed by a plus or minus sign. The E and optional + sign are followed by one or more digits. + + Numeric values that cannot be represented in the grammar below (such + as Infinity and NaN) are not permitted. + + number = [ minus ] int [ frac ] [ exp ] + + decimal-point = %x2E ; . + + digit1-9 = %x31-39 ; 1-9 + + e = %x65 / %x45 ; e E + + exp = e [ minus / plus ] 1*DIGIT + + frac = decimal-point 1*DIGIT + + int = zero / ( digit1-9 *DIGIT ) + + minus = %x2D ; - + + plus = %x2B ; + + + zero = %x30 ; 0 + + This specification allows implementations to set limits on the range + and precision of numbers accepted. Since software that implements + IEEE 754-2008 binary64 (double precision) numbers [IEEE754] is + generally available and widely used, good interoperability can be + achieved by implementations that expect no more precision or range + than these provide, in the sense that implementations will + approximate JSON numbers within the expected precision. A JSON + number such as 1E400 or 3.141592653589793238462643383279 may indicate + potential interoperability problems, since it suggests that the + software that created it expects receiving software to have greater + capabilities for numeric magnitude and precision than is widely + available. + + Note that when such software is used, numbers that are integers and + are in the range [-(2**53)+1, (2**53)-1] are interoperable in the + sense that implementations will agree exactly on their numeric + values. + + + + + + + +Bray Standards Track [Page 7] + +RFC 7159 JSON March 2014 + + +7. Strings + + The representation of strings is similar to conventions used in the C + family of programming languages. A string begins and ends with + quotation marks. All Unicode characters may be placed within the + quotation marks, except for the characters that must be escaped: + quotation mark, reverse solidus, and the control characters (U+0000 + through U+001F). + + Any character may be escaped. If the character is in the Basic + Multilingual Plane (U+0000 through U+FFFF), then it may be + represented as a six-character sequence: a reverse solidus, followed + by the lowercase letter u, followed by four hexadecimal digits that + encode the character's code point. The hexadecimal letters A though + F can be upper or lower case. So, for example, a string containing + only a single reverse solidus character may be represented as + "\u005C". + + Alternatively, there are two-character sequence escape + representations of some popular characters. So, for example, a + string containing only a single reverse solidus character may be + represented more compactly as "\\". + + To escape an extended character that is not in the Basic Multilingual + Plane, the character is represented as a 12-character sequence, + encoding the UTF-16 surrogate pair. So, for example, a string + containing only the G clef character (U+1D11E) may be represented as + "\uD834\uDD1E". + + string = quotation-mark *char quotation-mark + + char = unescaped / + escape ( + %x22 / ; " quotation mark U+0022 + %x5C / ; \ reverse solidus U+005C + %x2F / ; / solidus U+002F + %x62 / ; b backspace U+0008 + %x66 / ; f form feed U+000C + %x6E / ; n line feed U+000A + %x72 / ; r carriage return U+000D + %x74 / ; t tab U+0009 + %x75 4HEXDIG ) ; uXXXX U+XXXX + + escape = %x5C ; \ + + quotation-mark = %x22 ; " + + unescaped = %x20-21 / %x23-5B / %x5D-10FFFF + + + +Bray Standards Track [Page 8] + +RFC 7159 JSON March 2014 + + +8. String and Character Issues + +8.1. Character Encoding + + JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32. The default + encoding is UTF-8, and JSON texts that are encoded in UTF-8 are + interoperable in the sense that they will be read successfully by the + maximum number of implementations; there are many implementations + that cannot successfully read texts in other encodings (such as + UTF-16 and UTF-32). + + Implementations MUST NOT add a byte order mark to the beginning of a + JSON text. In the interests of interoperability, implementations + that parse JSON texts MAY ignore the presence of a byte order mark + rather than treating it as an error. + +8.2. Unicode Characters + + When all the strings represented in a JSON text are composed entirely + of Unicode characters [UNICODE] (however escaped), then that JSON + text is interoperable in the sense that all software implementations + that parse it will agree on the contents of names and of string + values in objects and arrays. + + However, the ABNF in this specification allows member names and + string values to contain bit sequences that cannot encode Unicode + characters; for example, "\uDEAD" (a single unpaired UTF-16 + surrogate). Instances of this have been observed, for example, when + a library truncates a UTF-16 string without checking whether the + truncation split a surrogate pair. The behavior of software that + receives JSON texts containing such values is unpredictable; for + example, implementations might return different values for the length + of a string value or even suffer fatal runtime exceptions. + +8.3. String Comparison + + Software implementations are typically required to test names of + object members for equality. Implementations that transform the + textual representation into sequences of Unicode code units and then + perform the comparison numerically, code unit by code unit, are + interoperable in the sense that implementations will agree in all + cases on equality or inequality of two strings. For example, + implementations that compare strings with escaped characters + unconverted may incorrectly find that "a\\b" and "a\u005Cb" are not + equal. + + + + + + +Bray Standards Track [Page 9] + +RFC 7159 JSON March 2014 + + +9. Parsers + + A JSON parser transforms a JSON text into another representation. A + JSON parser MUST accept all texts that conform to the JSON grammar. + A JSON parser MAY accept non-JSON forms or extensions. + + An implementation may set limits on the size of texts that it + accepts. An implementation may set limits on the maximum depth of + nesting. An implementation may set limits on the range and precision + of numbers. An implementation may set limits on the length and + character contents of strings. + +10. Generators + + A JSON generator produces JSON text. The resulting text MUST + strictly conform to the JSON grammar. + +11. IANA Considerations + + The MIME media type for JSON text is application/json. + + Type name: application + + Subtype name: json + + Required parameters: n/a + + Optional parameters: n/a + + Encoding considerations: binary + + Security considerations: See [RFC7159], Section 12. + + Interoperability considerations: Described in [RFC7159] + + Published specification: [RFC7159] + + Applications that use this media type: + JSON has been used to exchange data between applications written + in all of these programming languages: ActionScript, C, C#, + Clojure, ColdFusion, Common Lisp, E, Erlang, Go, Java, JavaScript, + Lua, Objective CAML, Perl, PHP, Python, Rebol, Ruby, Scala, and + Scheme. + + + + + + + + +Bray Standards Track [Page 10] + +RFC 7159 JSON March 2014 + + + Additional information: + Magic number(s): n/a + File extension(s): .json + Macintosh file type code(s): TEXT + + Person & email address to contact for further information: + IESG + + + Intended usage: COMMON + + Restrictions on usage: none + + Author: + Douglas Crockford + + + Change controller: + IESG + + + Note: No "charset" parameter is defined for this registration. + Adding one really has no effect on compliant recipients. + +12. Security Considerations + + Generally, there are security issues with scripting languages. JSON + is a subset of JavaScript but excludes assignment and invocation. + + Since JSON's syntax is borrowed from JavaScript, it is possible to + use that language's "eval()" function to parse JSON texts. This + generally constitutes an unacceptable security risk, since the text + could contain executable code along with data declarations. The same + consideration applies to the use of eval()-like functions in any + other programming language in which JSON texts conform to that + language's syntax. + + + + + + + + + + + + + + + +Bray Standards Track [Page 11] + +RFC 7159 JSON March 2014 + + +13. Examples + + This is a JSON object: + + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } + } + + Its Image member is an object whose Thumbnail member is an object and + whose IDs member is an array of numbers. + + This is a JSON array containing two objects: + + [ + { + "precision": "zip", + "Latitude": 37.7668, + "Longitude": -122.3959, + "Address": "", + "City": "SAN FRANCISCO", + "State": "CA", + "Zip": "94107", + "Country": "US" + }, + { + "precision": "zip", + "Latitude": 37.371991, + "Longitude": -122.026020, + "Address": "", + "City": "SUNNYVALE", + "State": "CA", + "Zip": "94085", + "Country": "US" + } + ] + + + + + +Bray Standards Track [Page 12] + +RFC 7159 JSON March 2014 + + + Here are three small JSON texts containing only values: + + "Hello world!" + + 42 + + true + +14. Contributors + + RFC 4627 was written by Douglas Crockford. This document was + constructed by making a relatively small number of changes to that + document; thus, the vast majority of the text here is his. + +15. References + +15.1. Normative References + + [IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", IEEE + Standard 754, August 2008, + . + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax + Specifications: ABNF", STD 68, RFC 5234, January 2008. + + [UNICODE] The Unicode Consortium, "The Unicode Standard", + . + +15.2. Informative References + + [ECMA-262] Ecma International, "ECMAScript Language Specification + Edition 5.1", Standard ECMA-262, June 2011, + . + + [ECMA-404] Ecma International, "The JSON Data Interchange Format", + Standard ECMA-404, October 2013, + . + + [Err3607] RFC Errata, Errata ID 3607, RFC 3607, + . + + + + + + +Bray Standards Track [Page 13] + +RFC 7159 JSON March 2014 + + + [Err607] RFC Errata, Errata ID 607, RFC 607, + . + + [RFC4627] Crockford, D., "The application/json Media Type for + JavaScript Object Notation (JSON)", RFC 4627, July 2006. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bray Standards Track [Page 14] + +RFC 7159 JSON March 2014 + + +Appendix A. Changes from RFC 4627 + + This section lists changes between this document and the text in RFC + 4627. + + o Changed the title and abstract of the document. + + o Changed the reference to [UNICODE] to be not version specific. + + o Added a "Specifications of JSON" section. + + o Added an "Introduction to This Revision" section. + + o Changed the definition of "JSON text" so that it can be any JSON + value, removing the constraint that it be an object or array. + + o Added language about duplicate object member names, member + ordering, and interoperability. + + o Clarified the absence of a requirement that values in an array be + of the same JSON type. + + o Applied erratum #607 from RFC 4627 to correctly align the artwork + for the definition of "object". + + o Changed "as sequences of digits" to "in the grammar below" in the + "Numbers" section, and made base-10-ness explicit. + + o Added language about number interoperability as a function of + IEEE754, and added an IEEE754 reference. + + o Added language about interoperability and Unicode characters and + about string comparisons. To do this, turned the old "Encoding" + section into a "String and Character Issues" section, with three + subsections: "Character Encoding", "Unicode Characters", and + "String Comparison". + + o Changed guidance in the "Parsers" section to point out that + implementations may set limits on the range "and precision" of + numbers. + + o Updated and tidied the "IANA Considerations" section. + + o Made a real "Security Considerations" section and lifted the text + out of the previous "IANA Considerations" section. + + + + + + +Bray Standards Track [Page 15] + +RFC 7159 JSON March 2014 + + + o Applied erratum #3607 from RFC 4627 by removing the security + consideration that begins "A JSON text can be safely passed" and + the JavaScript code that went with that consideration. + + o Added a note to the "Security Considerations" section pointing out + the risks of using the "eval()" function in JavaScript or any + other language in which JSON texts conform to that language's + syntax. + + o Added a note to the "IANA Considerations" clarifying the absence + of a "charset" parameter for the application/json media type. + + o Changed "100" to 100 and added a boolean field, both in the first + example. + + o Added examples of JSON texts with simple values, neither objects + nor arrays. + + o Added a "Contributors" section crediting Douglas Crockford. + + o Added a reference to RFC 4627. + + o Moved the ECMAScript reference from Normative to Informative and + updated it to reference ECMAScript 5.1, and added a reference to + ECMA 404. + +Author's Address + + Tim Bray (editor) + Google, Inc. + + EMail: tbray@textuality.com + + + + + + + + + + + + + + + + + + + +Bray Standards Track [Page 16] + From 6cee8d7dc22d2d8559a49ed27e79f943edd34389 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 2 Jun 2016 13:23:07 +0200 Subject: [PATCH 122/312] Support newer rubies --- tools/fuzz.rb | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tools/fuzz.rb b/tools/fuzz.rb index c0fae12c6..826193019 100755 --- a/tools/fuzz.rb +++ b/tools/fuzz.rb @@ -1,13 +1,5 @@ require 'json' -require 'iconv' -ISO_8859_1_TO_UTF8 = Iconv.new('utf-8', 'iso-8859-15') -class ::String - def to_utf8 - ISO_8859_1_TO_UTF8.iconv self - end -end - class Fuzzer def initialize(n, freqs = {}) sum = freqs.inject(0.0) { |s, x| s + x.last } @@ -25,7 +17,7 @@ def initialize(n, freqs = {}) def random_string s = '' 30.times { s << @alpha[rand(@alpha.size)] } - s.to_utf8 + s end def pick From 08b6febac4f2382f2526c51060b630b7b7130577 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 2 Jun 2016 14:10:27 +0200 Subject: [PATCH 123/312] Change rfc reference --- lib/json/common.rb | 28 +++++----------------------- lib/json/pure/parser.rb | 2 +- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/lib/json/common.rb b/lib/json/common.rb index 1215d41ba..c47938f23 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -141,7 +141,7 @@ class MissingUnicodeSupport < JSONError; end # structures. Disable depth checking with :max_nesting => false. It # defaults to 100. # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in - # defiance of RFC 4627 to be parsed by the Parser. This option defaults + # defiance of RFC 7159 to be parsed by the Parser. This option defaults # to false. # * *symbolize_names*: If set to true, returns symbols for the names # (keys) in a JSON object. Otherwise strings are returned. Strings are @@ -165,7 +165,7 @@ def parse(source, opts = {}) # parse! methods defaults to not doing max depth checking: This can be # dangerous if someone wants to fill up your stack. # * *allow_nan*: If set to true, allow NaN, Infinity, and -Infinity in - # defiance of RFC 4627 to be parsed by the Parser. This option defaults + # defiance of RFC 7159 to be parsed by the Parser. This option defaults # to true. # * *create_additions*: If set to false, the Parser doesn't create # additions even if a matching class and create_id was found. This option @@ -402,27 +402,9 @@ def dump(obj, anIO = nil, limit = nil) raise ArgumentError, "exceed depth limit" end - # Swap consecutive bytes of _string_ in place. - def self.swap!(string) # :nodoc: - 0.upto(string.size / 2) do |i| - break unless string[2 * i + 1] - string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i] - end - string - end - - # Shortcut for iconv. - if ::String.method_defined?(:encode) - # Encodes string using Ruby's _String.encode_ - def self.iconv(to, from, string) - string.encode(to, from) - end - else - require 'iconv' - # Encodes string using _iconv_ library - def self.iconv(to, from, string) - Iconv.conv(to, from, string) - end + # Encodes string using Ruby's _String.encode_ + def self.iconv(to, from, string) + string.encode(to, from) end if ::Object.method(:const_defined?).arity == 1 diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index c5d1501b1..c96fadb11 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -58,7 +58,7 @@ class Parser < StringScanner # structures. Disable depth checking with :max_nesting => false|nil|0, # it defaults to 100. # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in - # defiance of RFC 4627 to be parsed by the Parser. This option defaults + # defiance of RFC 7159 to be parsed by the Parser. This option defaults # to false. # * *symbolize_names*: If set to true, returns symbols for the names # (keys) in a JSON object. Otherwise strings are returned, which is From a985a0c4b074280e2a9e215ead95b1e66797b6c3 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 2 Jun 2016 14:13:37 +0200 Subject: [PATCH 124/312] Update documentation for RFC 7159 support --- README.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/README.md b/README.md index 7fc6c14c6..3a9f6ab5c 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,6 @@ encoded, please use the to\_json\_raw\_object method of String (which produces an object, that contains a byte array) and decode the result on the receiving endpoint. -The JSON parsers can parse UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, and UTF-32LE -JSON documents under Ruby 1.8. Under Ruby 1.9 they take advantage of Ruby's -M17n features and can parse all documents which have the correct -String#encoding set. If a document string has ASCII-8BIT as an encoding the -parser attempts to figure out which of the UTF encodings from above it is and -trys to parse it. - ## Installation It's recommended to use the extension variant of JSON, because it's faster than @@ -91,10 +84,6 @@ You can also use the pretty\_generate method (which formats the output more verbosely and nicely) or fast\_generate (which doesn't do any of the security checks generate performs, e. g. nesting deepness checks). -To create a valid JSON document you have to make sure, that the output is -embedded in either a JSON array [] or a JSON object {}. The easiest way to do -this, is by putting your values in a Ruby Array or Hash instance. - There are also the JSON and JSON[] methods which use parse on a String or generate a JSON document from an array or hash: From 7d2ad6d6556da03300a5aeadeeacaec563435773 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 2 Jun 2016 21:10:36 +0200 Subject: [PATCH 125/312] Remove quirks mode --- Gemfile | 2 - TODO | 1 - ext/json/ext/generator/generator.c | 34 +- ext/json/ext/generator/generator.h | 1 - java/src/json/ext/Generator.java | 7 +- java/src/json/ext/GeneratorState.java | 6 +- java/src/json/ext/OptionsReader.java | 2 +- java/src/json/ext/Parser.java | 512 ++++++-------------------- java/src/json/ext/Parser.rl | 135 +------ java/src/json/ext/RuntimeInfo.java | 4 - json.gemspec | Bin 4444 -> 4470 bytes json_pure.gemspec | 4 +- lib/json/common.rb | 9 +- lib/json/pure/generator.rb | 13 - lib/json/pure/parser.rb | 16 +- tests/json_common_interface_test.rb | 7 +- tests/json_generator_test.rb | 3 - tests/json_parser_test.rb | 2 +- tests/test_helper.rb | 4 - 19 files changed, 143 insertions(+), 619 deletions(-) delete mode 100644 TODO diff --git a/Gemfile b/Gemfile index 51ff10afc..71fac4735 100644 --- a/Gemfile +++ b/Gemfile @@ -5,5 +5,3 @@ source 'https://rubygems.org' gemspec :name => 'json' gemspec :name => 'json_pure' gemspec :name => 'json-java' - -gem 'simplecov' diff --git a/TODO b/TODO deleted file mode 100644 index 8b1378917..000000000 --- a/TODO +++ /dev/null @@ -1 +0,0 @@ - diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 393e29c0e..2a3db2965 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -14,7 +14,7 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject, static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before, i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only, - i_quirks_mode, i_pack, i_unpack, i_create_id, i_extend, i_key_p, + i_pack, i_unpack, i_create_id, i_extend, i_key_p, i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth, i_buffer_initial_length, i_dup; @@ -622,8 +622,6 @@ static VALUE cState_configure(VALUE self, VALUE opts) state->allow_nan = RTEST(tmp); tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only)); state->ascii_only = RTEST(tmp); - tmp = rb_hash_aref(opts, ID2SYM(i_quirks_mode)); - state->quirks_mode = RTEST(tmp); return self; } @@ -657,7 +655,6 @@ static VALUE cState_to_h(VALUE self) rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len)); rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse); rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse); - rb_hash_aset(result, ID2SYM(i_quirks_mode), state->quirks_mode ? Qtrue : Qfalse); rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting)); rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth)); rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length)); @@ -943,8 +940,6 @@ static VALUE cState_generate(VALUE self, VALUE obj) * * *allow_nan*: true if NaN, Infinity, and -Infinity should be * generated, otherwise an exception is thrown, if these values are * encountered. This options defaults to false. - * * *quirks_mode*: Enables quirks_mode for parser, that is for example - * generating single JSON values instead of documents is possible. * * *buffer_initial_length*: sets the initial length of the generator's * internal buffer. */ @@ -1251,29 +1246,6 @@ static VALUE cState_ascii_only_p(VALUE self) return state->ascii_only ? Qtrue : Qfalse; } -/* - * call-seq: quirks_mode? - * - * Returns true, if quirks mode is enabled. Otherwise returns false. - */ -static VALUE cState_quirks_mode_p(VALUE self) -{ - GET_STATE(self); - return state->quirks_mode ? Qtrue : Qfalse; -} - -/* - * call-seq: quirks_mode=(enable) - * - * If set to true, enables the quirks_mode mode. - */ -static VALUE cState_quirks_mode_set(VALUE self, VALUE enable) -{ - GET_STATE(self); - state->quirks_mode = RTEST(enable); - return Qnil; -} - /* * call-seq: depth * @@ -1362,9 +1334,6 @@ void Init_generator(void) rb_define_method(cState, "check_circular?", cState_check_circular_p, 0); rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0); rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0); - rb_define_method(cState, "quirks_mode?", cState_quirks_mode_p, 0); - rb_define_method(cState, "quirks_mode", cState_quirks_mode_p, 0); - rb_define_method(cState, "quirks_mode=", cState_quirks_mode_set, 1); rb_define_method(cState, "depth", cState_depth, 0); rb_define_method(cState, "depth=", cState_depth_set, 1); rb_define_method(cState, "buffer_initial_length", cState_buffer_initial_length, 0); @@ -1416,7 +1385,6 @@ void Init_generator(void) i_max_nesting = rb_intern("max_nesting"); i_allow_nan = rb_intern("allow_nan"); i_ascii_only = rb_intern("ascii_only"); - i_quirks_mode = rb_intern("quirks_mode"); i_depth = rb_intern("depth"); i_buffer_initial_length = rb_intern("buffer_initial_length"); i_pack = rb_intern("pack"); diff --git a/ext/json/ext/generator/generator.h b/ext/json/ext/generator/generator.h index 298c0a496..7432f2682 100644 --- a/ext/json/ext/generator/generator.h +++ b/ext/json/ext/generator/generator.h @@ -73,7 +73,6 @@ typedef struct JSON_Generator_StateStruct { long max_nesting; char allow_nan; char ascii_only; - char quirks_mode; long depth; long buffer_initial_length; } JSON_Generator_State; diff --git a/java/src/json/ext/Generator.java b/java/src/json/ext/Generator.java index bb3a394b9..96a5e7e4f 100644 --- a/java/src/json/ext/Generator.java +++ b/java/src/json/ext/Generator.java @@ -172,9 +172,7 @@ RubyString generateNew(Session session, T object) { result = RubyString.newString(session.getRuntime(), buffer); ThreadContext context = session.getContext(); RuntimeInfo info = session.getInfo(); - if (info.encodingsSupported()) { - result.force_encoding(context, info.utf8.get()); - } + result.force_encoding(context, info.utf8.get()); return result; } @@ -381,8 +379,7 @@ void generate(Session session, RubyString object, ByteList buffer) { RuntimeInfo info = session.getInfo(); RubyString src; - if (info.encodingsSupported() && - object.encoding(session.getContext()) != info.utf8.get()) { + if (object.encoding(session.getContext()) != info.utf8.get()) { src = (RubyString)object.encode(session.getContext(), info.utf8.get()); } else { diff --git a/java/src/json/ext/GeneratorState.java b/java/src/json/ext/GeneratorState.java index 11d98d0b0..f43087bf9 100644 --- a/java/src/json/ext/GeneratorState.java +++ b/java/src/json/ext/GeneratorState.java @@ -208,9 +208,7 @@ public IRubyObject initialize_copy(ThreadContext context, IRubyObject vOrig) { public IRubyObject generate(ThreadContext context, IRubyObject obj) { RubyString result = Generator.generateJson(context, obj, this); RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); - if (info.encodingsSupported()) { - result.force_encoding(context, info.utf8.get()); - } + result.force_encoding(context, info.utf8.get()); return result; } @@ -412,7 +410,7 @@ public IRubyObject depth_set(IRubyObject vDepth) { private ByteList prepareByteList(ThreadContext context, IRubyObject value) { RubyString str = value.convertToString(); RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); - if (info.encodingsSupported() && str.encoding(context) != info.utf8.get()) { + if (str.encoding(context) != info.utf8.get()) { str = (RubyString)str.encode(context, info.utf8.get()); } return str.getByteList().dup(); diff --git a/java/src/json/ext/OptionsReader.java b/java/src/json/ext/OptionsReader.java index 9bb6e64c3..70426d427 100644 --- a/java/src/json/ext/OptionsReader.java +++ b/java/src/json/ext/OptionsReader.java @@ -84,7 +84,7 @@ RubyString getString(String key, RubyString defaultValue) { RubyString str = value.convertToString(); RuntimeInfo info = getRuntimeInfo(); - if (info.encodingsSupported() && str.encoding(context) != info.utf8.get()) { + if (str.encoding(context) != info.utf8.get()) { str = (RubyString)str.encode(context, info.utf8.get()); } return str; diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index 5458fb18b..57053e9f8 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -52,10 +52,9 @@ public class Parser extends RubyObject { private int maxNesting; private boolean allowNaN; private boolean symbolizeNames; - private boolean quirksMode; private RubyClass objectClass; private RubyClass arrayClass; - private RubyHash match_string; + private RubyHash matchString; private static final int DEFAULT_MAX_NESTING = 100; @@ -123,10 +122,6 @@ public Parser(Ruby runtime, RubyClass metaClass) { *
If set to true, returns symbols for the names (keys) in * a JSON object. Otherwise strings are returned, which is also the default. * - *
:quirks_mode? - *
If set to true, if the parse is in quirks_mode, false - * otherwise. - * *
:create_additions *
If set to false, the Parser doesn't create additions * even if a matching class and create_id was found. This option @@ -138,9 +133,6 @@ public Parser(Ruby runtime, RubyClass metaClass) { *
:array_class *
Defaults to Array. * - *
:quirks_mode - *
Enables quirks_mode for parser, that is for example parsing single - * JSON values instead of documents is possible. * */ @JRubyMethod(name = "new", required = 1, optional = 1, meta = true) @@ -163,15 +155,20 @@ public IRubyObject initialize(ThreadContext context, IRubyObject[] args) { this.maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING); this.allowNaN = opts.getBool("allow_nan", false); this.symbolizeNames = opts.getBool("symbolize_names", false); - this.quirksMode = opts.getBool("quirks_mode", false); this.createId = opts.getString("create_id", getCreateId(context)); this.createAdditions = opts.getBool("create_additions", false); this.objectClass = opts.getClass("object_class", runtime.getHash()); this.arrayClass = opts.getClass("array_class", runtime.getArray()); - this.match_string = opts.getHash("match_string"); + this.matchString = opts.getHash("match_string"); + if(symbolizeNames && createAdditions) { + throw runtime.newArgumentError( + "options :symbolize_names and :create_additions cannot be " + + " used in conjunction" + ); + } this.vSource = args[0].convertToString(); - if (!quirksMode) this.vSource = convertEncoding(context, vSource); + this.vSource = convertEncoding(context, vSource); return this; } @@ -182,33 +179,7 @@ public IRubyObject initialize(ThreadContext context, IRubyObject[] args) { * Returns the source string if no conversion is needed. */ private RubyString convertEncoding(ThreadContext context, RubyString source) { - ByteList bl = source.getByteList(); - int len = bl.length(); - if (len < 2) { - throw Utils.newException(context, Utils.M_PARSER_ERROR, - "A JSON text must at least contain two octets!"); - } - - if (info.encodingsSupported()) { - RubyEncoding encoding = (RubyEncoding)source.encoding(context); - if (encoding != info.ascii8bit.get()) { - return (RubyString)source.encode(context, info.utf8.get()); - } - - String sniffedEncoding = sniffByteList(bl); - if (sniffedEncoding == null) return source; // assume UTF-8 - return reinterpretEncoding(context, source, sniffedEncoding); - } - - String sniffedEncoding = sniffByteList(bl); - if (sniffedEncoding == null) return source; // assume UTF-8 - Ruby runtime = context.getRuntime(); - return (RubyString)info.jsonModule.get(). - callMethod(context, "iconv", - new IRubyObject[] { - runtime.newString("utf-8"), - runtime.newString(sniffedEncoding), - source}); + return (RubyString)source.encode(context, info.utf8.get()); } /** @@ -261,17 +232,6 @@ public IRubyObject source_get() { return checkAndGetSource().dup(); } - /** - * Parser#quirks_mode?() - * - *

If set to true, if the parse is in quirks_mode, false - * otherwise. - */ - @JRubyMethod(name = "quirks_mode?") - public IRubyObject quirks_mode_p(ThreadContext context) { - return context.getRuntime().newBoolean(quirksMode); - } - public RubyString checkAndGetSource() { if (vSource != null) { return vSource; @@ -338,11 +298,11 @@ private Ruby getRuntime() { } -// line 365 "Parser.rl" +// line 324 "Parser.rl" -// line 347 "Parser.java" +// line 306 "Parser.java" private static byte[] init__JSON_value_actions_0() { return new byte [] { @@ -456,7 +416,7 @@ private static byte[] init__JSON_value_from_state_actions_0() static final int JSON_value_en_main = 1; -// line 471 "Parser.rl" +// line 430 "Parser.rl" void parseValue(ParserResult res, int p, int pe) { @@ -464,14 +424,14 @@ void parseValue(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 469 "Parser.java" +// line 428 "Parser.java" { cs = JSON_value_start; } -// line 478 "Parser.rl" +// line 437 "Parser.rl" -// line 476 "Parser.java" +// line 435 "Parser.java" { int _klen; int _trans = 0; @@ -497,13 +457,13 @@ void parseValue(ParserResult res, int p, int pe) { while ( _nacts-- > 0 ) { switch ( _JSON_value_actions[_acts++] ) { case 9: -// line 456 "Parser.rl" +// line 415 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 508 "Parser.java" +// line 467 "Parser.java" } } @@ -566,25 +526,25 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) switch ( _JSON_value_actions[_acts++] ) { case 0: -// line 373 "Parser.rl" +// line 332 "Parser.rl" { result = getRuntime().getNil(); } break; case 1: -// line 376 "Parser.rl" +// line 335 "Parser.rl" { result = getRuntime().getFalse(); } break; case 2: -// line 379 "Parser.rl" +// line 338 "Parser.rl" { result = getRuntime().getTrue(); } break; case 3: -// line 382 "Parser.rl" +// line 341 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_NAN); @@ -594,7 +554,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 4: -// line 389 "Parser.rl" +// line 348 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_INFINITY); @@ -604,9 +564,9 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 5: -// line 396 "Parser.rl" +// line 355 "Parser.rl" { - if (pe > p + 9 - (parser.quirksMode ? 1 : 0) && + if (pe > p + 8 && absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) { if (parser.allowNaN) { @@ -633,7 +593,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 6: -// line 422 "Parser.rl" +// line 381 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -646,7 +606,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 7: -// line 432 "Parser.rl" +// line 391 "Parser.rl" { currentNesting++; parseArray(res, p, pe); @@ -661,7 +621,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 8: -// line 444 "Parser.rl" +// line 403 "Parser.rl" { currentNesting++; parseObject(res, p, pe); @@ -675,7 +635,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } } break; -// line 680 "Parser.java" +// line 639 "Parser.java" } } } @@ -695,7 +655,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) break; } } -// line 479 "Parser.rl" +// line 438 "Parser.rl" if (cs >= JSON_value_first_final && result != null) { res.update(result, p); @@ -705,7 +665,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } -// line 710 "Parser.java" +// line 669 "Parser.java" private static byte[] init__JSON_integer_actions_0() { return new byte [] { @@ -804,7 +764,7 @@ private static byte[] init__JSON_integer_trans_actions_0() static final int JSON_integer_en_main = 1; -// line 498 "Parser.rl" +// line 457 "Parser.rl" void parseInteger(ParserResult res, int p, int pe) { @@ -822,15 +782,15 @@ int parseIntegerInternal(int p, int pe) { int cs = EVIL; -// line 827 "Parser.java" +// line 786 "Parser.java" { cs = JSON_integer_start; } -// line 515 "Parser.rl" +// line 474 "Parser.rl" int memo = p; -// line 835 "Parser.java" +// line 794 "Parser.java" { int _klen; int _trans = 0; @@ -911,13 +871,13 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) switch ( _JSON_integer_actions[_acts++] ) { case 0: -// line 492 "Parser.rl" +// line 451 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 922 "Parser.java" +// line 881 "Parser.java" } } } @@ -937,7 +897,7 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) break; } } -// line 517 "Parser.rl" +// line 476 "Parser.rl" if (cs < JSON_integer_first_final) { return -1; @@ -959,7 +919,7 @@ RubyInteger bytesToInum(Ruby runtime, ByteList num) { } -// line 964 "Parser.java" +// line 923 "Parser.java" private static byte[] init__JSON_float_actions_0() { return new byte [] { @@ -1061,7 +1021,7 @@ private static byte[] init__JSON_float_trans_actions_0() static final int JSON_float_en_main = 1; -// line 552 "Parser.rl" +// line 511 "Parser.rl" void parseFloat(ParserResult res, int p, int pe) { @@ -1079,15 +1039,15 @@ int parseFloatInternal(int p, int pe) { int cs = EVIL; -// line 1084 "Parser.java" +// line 1043 "Parser.java" { cs = JSON_float_start; } -// line 569 "Parser.rl" +// line 528 "Parser.rl" int memo = p; -// line 1092 "Parser.java" +// line 1051 "Parser.java" { int _klen; int _trans = 0; @@ -1168,13 +1128,13 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) switch ( _JSON_float_actions[_acts++] ) { case 0: -// line 543 "Parser.rl" +// line 502 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1179 "Parser.java" +// line 1138 "Parser.java" } } } @@ -1194,7 +1154,7 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) break; } } -// line 571 "Parser.rl" +// line 530 "Parser.rl" if (cs < JSON_float_first_final) { return -1; @@ -1210,7 +1170,7 @@ RubyFloat createFloat(int p, int new_p) { } -// line 1215 "Parser.java" +// line 1174 "Parser.java" private static byte[] init__JSON_string_actions_0() { return new byte [] { @@ -1312,7 +1272,7 @@ private static byte[] init__JSON_string_trans_actions_0() static final int JSON_string_en_main = 1; -// line 616 "Parser.rl" +// line 575 "Parser.rl" void parseString(ParserResult res, int p, int pe) { @@ -1320,15 +1280,15 @@ void parseString(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 1325 "Parser.java" +// line 1284 "Parser.java" { cs = JSON_string_start; } -// line 623 "Parser.rl" +// line 582 "Parser.rl" int memo = p; -// line 1333 "Parser.java" +// line 1292 "Parser.java" { int _klen; int _trans = 0; @@ -1409,7 +1369,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) switch ( _JSON_string_actions[_acts++] ) { case 0: -// line 591 "Parser.rl" +// line 550 "Parser.rl" { int offset = byteList.begin(); ByteList decoded = decoder.decode(byteList, memo + 1 - offset, @@ -1424,13 +1384,13 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) } break; case 1: -// line 604 "Parser.rl" +// line 563 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1435 "Parser.java" +// line 1394 "Parser.java" } } } @@ -1450,14 +1410,14 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) break; } } -// line 625 "Parser.rl" +// line 584 "Parser.rl" if (parser.createAdditions) { - RubyHash match_string = parser.match_string; - if (match_string != null) { + RubyHash matchString = parser.matchString; + if (matchString != null) { final IRubyObject[] memoArray = { result, null }; try { - match_string.visitAll(new RubyHash.Visitor() { + matchString.visitAll(new RubyHash.Visitor() { @Override public void visit(IRubyObject pattern, IRubyObject klass) { if (pattern.callMethod(context, "===", memoArray[0]).isTrue()) { @@ -1478,7 +1438,7 @@ public void visit(IRubyObject pattern, IRubyObject klass) { } if (cs >= JSON_string_first_final && result != null) { - if (info.encodingsSupported() && result instanceof RubyString) { + if (result instanceof RubyString) { ((RubyString)result).force_encoding(context, info.utf8.get()); } res.update(result, p + 1); @@ -1488,7 +1448,7 @@ public void visit(IRubyObject pattern, IRubyObject klass) { } -// line 1493 "Parser.java" +// line 1452 "Parser.java" private static byte[] init__JSON_array_actions_0() { return new byte [] { @@ -1601,7 +1561,7 @@ private static byte[] init__JSON_array_trans_actions_0() static final int JSON_array_en_main = 1; -// line 698 "Parser.rl" +// line 657 "Parser.rl" void parseArray(ParserResult res, int p, int pe) { @@ -1621,14 +1581,14 @@ void parseArray(ParserResult res, int p, int pe) { } -// line 1626 "Parser.java" +// line 1585 "Parser.java" { cs = JSON_array_start; } -// line 717 "Parser.rl" +// line 676 "Parser.rl" -// line 1633 "Parser.java" +// line 1592 "Parser.java" { int _klen; int _trans = 0; @@ -1709,7 +1669,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) switch ( _JSON_array_actions[_acts++] ) { case 0: -// line 667 "Parser.rl" +// line 626 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1726,13 +1686,13 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } break; case 1: -// line 682 "Parser.rl" +// line 641 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1737 "Parser.java" +// line 1696 "Parser.java" } } } @@ -1752,7 +1712,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) break; } } -// line 718 "Parser.rl" +// line 677 "Parser.rl" if (cs >= JSON_array_first_final) { res.update(result, p + 1); @@ -1762,7 +1722,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } -// line 1767 "Parser.java" +// line 1726 "Parser.java" private static byte[] init__JSON_object_actions_0() { return new byte [] { @@ -1885,7 +1845,7 @@ private static byte[] init__JSON_object_trans_actions_0() static final int JSON_object_en_main = 1; -// line 777 "Parser.rl" +// line 736 "Parser.rl" void parseObject(ParserResult res, int p, int pe) { @@ -1910,14 +1870,14 @@ void parseObject(ParserResult res, int p, int pe) { } -// line 1915 "Parser.java" +// line 1874 "Parser.java" { cs = JSON_object_start; } -// line 801 "Parser.rl" +// line 760 "Parser.rl" -// line 1922 "Parser.java" +// line 1881 "Parser.java" { int _klen; int _trans = 0; @@ -1998,7 +1958,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) switch ( _JSON_object_actions[_acts++] ) { case 0: -// line 732 "Parser.rl" +// line 691 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2015,7 +1975,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 1: -// line 747 "Parser.rl" +// line 706 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -2035,13 +1995,13 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 2: -// line 765 "Parser.rl" +// line 724 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 2046 "Parser.java" +// line 2005 "Parser.java" } } } @@ -2061,7 +2021,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) break; } } -// line 802 "Parser.rl" +// line 761 "Parser.rl" if (cs < JSON_object_first_final) { res.update(null, p + 1); @@ -2094,11 +2054,11 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } -// line 2099 "Parser.java" +// line 2058 "Parser.java" private static byte[] init__JSON_actions_0() { return new byte [] { - 0, 1, 0, 1, 1 + 0, 1, 0 }; } @@ -2108,7 +2068,7 @@ private static byte[] init__JSON_actions_0() private static byte[] init__JSON_key_offsets_0() { return new byte [] { - 0, 0, 7, 9, 10, 12, 13, 15, 16, 18, 19 + 0, 0, 16, 18, 19, 21, 22, 24, 25, 27, 28 }; } @@ -2118,9 +2078,9 @@ private static byte[] init__JSON_key_offsets_0() private static char[] init__JSON_trans_keys_0() { return new char [] { - 13, 32, 47, 91, 123, 9, 10, 42, 47, 42, 42, 47, - 10, 42, 47, 42, 42, 47, 10, 13, 32, 47, 9, 10, - 0 + 13, 32, 34, 45, 47, 73, 78, 91, 102, 110, 116, 123, + 9, 10, 48, 57, 42, 47, 42, 42, 47, 10, 42, 47, + 42, 42, 47, 10, 13, 32, 47, 9, 10, 0 }; } @@ -2130,7 +2090,7 @@ private static char[] init__JSON_trans_keys_0() private static byte[] init__JSON_single_lengths_0() { return new byte [] { - 0, 5, 2, 1, 2, 1, 2, 1, 2, 1, 3 + 0, 12, 2, 1, 2, 1, 2, 1, 2, 1, 3 }; } @@ -2140,7 +2100,7 @@ private static byte[] init__JSON_single_lengths_0() private static byte[] init__JSON_range_lengths_0() { return new byte [] { - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } @@ -2150,7 +2110,7 @@ private static byte[] init__JSON_range_lengths_0() private static byte[] init__JSON_index_offsets_0() { return new byte [] { - 0, 0, 7, 10, 12, 15, 17, 20, 22, 25, 27 + 0, 0, 15, 18, 20, 23, 25, 28, 30, 33, 35 }; } @@ -2160,9 +2120,10 @@ private static byte[] init__JSON_index_offsets_0() private static byte[] init__JSON_indicies_0() { return new byte [] { - 0, 0, 2, 3, 4, 0, 1, 5, 6, 1, 7, 5, - 7, 0, 5, 0, 6, 8, 9, 1, 10, 8, 10, 11, - 8, 11, 9, 11, 11, 12, 11, 1, 0 + 0, 0, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, + 0, 2, 1, 4, 5, 1, 6, 4, 6, 7, 4, 7, + 5, 8, 9, 1, 10, 8, 10, 0, 8, 0, 9, 7, + 7, 11, 7, 1, 0 }; } @@ -2172,8 +2133,7 @@ private static byte[] init__JSON_indicies_0() private static byte[] init__JSON_trans_targs_0() { return new byte [] { - 1, 0, 2, 10, 10, 3, 5, 4, 7, 9, 8, 10, - 6 + 1, 0, 10, 6, 3, 5, 4, 10, 7, 9, 8, 2 }; } @@ -2183,8 +2143,7 @@ private static byte[] init__JSON_trans_targs_0() private static byte[] init__JSON_trans_actions_0() { return new byte [] { - 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, - 0 + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; } @@ -2198,26 +2157,26 @@ private static byte[] init__JSON_trans_actions_0() static final int JSON_en_main = 1; -// line 867 "Parser.rl" +// line 812 "Parser.rl" - public IRubyObject parseStrict() { + public IRubyObject parseImplemetation() { int cs = EVIL; int p, pe; IRubyObject result = null; ParserResult res = new ParserResult(); -// line 2213 "Parser.java" +// line 2171 "Parser.java" { cs = JSON_start; } -// line 876 "Parser.rl" +// line 821 "Parser.rl" p = byteList.begin(); pe = p + byteList.length(); -// line 2222 "Parser.java" +// line 2180 "Parser.java" { int _klen; int _trans = 0; @@ -2298,267 +2257,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) switch ( _JSON_actions[_acts++] ) { case 0: -// line 839 "Parser.rl" - { - currentNesting = 1; - parseObject(res, p, pe); - if (res.result == null) { - p--; - { p += 1; _goto_targ = 5; if (true) continue _goto;} - } else { - result = res.result; - {p = (( res.p))-1;} - } - } - break; - case 1: -// line 851 "Parser.rl" - { - currentNesting = 1; - parseArray(res, p, pe); - if (res.result == null) { - p--; - { p += 1; _goto_targ = 5; if (true) continue _goto;} - } else { - result = res.result; - {p = (( res.p))-1;} - } - } - break; -// line 2330 "Parser.java" - } - } - } - -case 2: - if ( cs == 0 ) { - _goto_targ = 5; - continue _goto; - } - if ( ++p != pe ) { - _goto_targ = 1; - continue _goto; - } -case 4: -case 5: - } - break; } - } - -// line 879 "Parser.rl" - - if (cs >= JSON_first_final && p == pe) { - return result; - } else { - throw unexpectedToken(p, pe); - } - } - - -// line 2360 "Parser.java" -private static byte[] init__JSON_quirks_mode_actions_0() -{ - return new byte [] { - 0, 1, 0 - }; -} - -private static final byte _JSON_quirks_mode_actions[] = init__JSON_quirks_mode_actions_0(); - - -private static byte[] init__JSON_quirks_mode_key_offsets_0() -{ - return new byte [] { - 0, 0, 16, 18, 19, 21, 22, 24, 25, 27, 28 - }; -} - -private static final byte _JSON_quirks_mode_key_offsets[] = init__JSON_quirks_mode_key_offsets_0(); - - -private static char[] init__JSON_quirks_mode_trans_keys_0() -{ - return new char [] { - 13, 32, 34, 45, 47, 73, 78, 91, 102, 110, 116, 123, - 9, 10, 48, 57, 42, 47, 42, 42, 47, 10, 42, 47, - 42, 42, 47, 10, 13, 32, 47, 9, 10, 0 - }; -} - -private static final char _JSON_quirks_mode_trans_keys[] = init__JSON_quirks_mode_trans_keys_0(); - - -private static byte[] init__JSON_quirks_mode_single_lengths_0() -{ - return new byte [] { - 0, 12, 2, 1, 2, 1, 2, 1, 2, 1, 3 - }; -} - -private static final byte _JSON_quirks_mode_single_lengths[] = init__JSON_quirks_mode_single_lengths_0(); - - -private static byte[] init__JSON_quirks_mode_range_lengths_0() -{ - return new byte [] { - 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1 - }; -} - -private static final byte _JSON_quirks_mode_range_lengths[] = init__JSON_quirks_mode_range_lengths_0(); - - -private static byte[] init__JSON_quirks_mode_index_offsets_0() -{ - return new byte [] { - 0, 0, 15, 18, 20, 23, 25, 28, 30, 33, 35 - }; -} - -private static final byte _JSON_quirks_mode_index_offsets[] = init__JSON_quirks_mode_index_offsets_0(); - - -private static byte[] init__JSON_quirks_mode_indicies_0() -{ - return new byte [] { - 0, 0, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, - 0, 2, 1, 4, 5, 1, 6, 4, 6, 7, 4, 7, - 5, 8, 9, 1, 10, 8, 10, 0, 8, 0, 9, 7, - 7, 11, 7, 1, 0 - }; -} - -private static final byte _JSON_quirks_mode_indicies[] = init__JSON_quirks_mode_indicies_0(); - - -private static byte[] init__JSON_quirks_mode_trans_targs_0() -{ - return new byte [] { - 1, 0, 10, 6, 3, 5, 4, 10, 7, 9, 8, 2 - }; -} - -private static final byte _JSON_quirks_mode_trans_targs[] = init__JSON_quirks_mode_trans_targs_0(); - - -private static byte[] init__JSON_quirks_mode_trans_actions_0() -{ - return new byte [] { - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; -} - -private static final byte _JSON_quirks_mode_trans_actions[] = init__JSON_quirks_mode_trans_actions_0(); - - -static final int JSON_quirks_mode_start = 1; -static final int JSON_quirks_mode_first_final = 10; -static final int JSON_quirks_mode_error = 0; - -static final int JSON_quirks_mode_en_main = 1; - - -// line 907 "Parser.rl" - - - public IRubyObject parseQuirksMode() { - int cs = EVIL; - int p, pe; - IRubyObject result = null; - ParserResult res = new ParserResult(); - - -// line 2473 "Parser.java" - { - cs = JSON_quirks_mode_start; - } - -// line 916 "Parser.rl" - p = byteList.begin(); - pe = p + byteList.length(); - -// line 2482 "Parser.java" - { - int _klen; - int _trans = 0; - int _acts; - int _nacts; - int _keys; - int _goto_targ = 0; - - _goto: while (true) { - switch ( _goto_targ ) { - case 0: - if ( p == pe ) { - _goto_targ = 4; - continue _goto; - } - if ( cs == 0 ) { - _goto_targ = 5; - continue _goto; - } -case 1: - _match: do { - _keys = _JSON_quirks_mode_key_offsets[cs]; - _trans = _JSON_quirks_mode_index_offsets[cs]; - _klen = _JSON_quirks_mode_single_lengths[cs]; - if ( _klen > 0 ) { - int _lower = _keys; - int _mid; - int _upper = _keys + _klen - 1; - while (true) { - if ( _upper < _lower ) - break; - - _mid = _lower + ((_upper-_lower) >> 1); - if ( data[p] < _JSON_quirks_mode_trans_keys[_mid] ) - _upper = _mid - 1; - else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid] ) - _lower = _mid + 1; - else { - _trans += (_mid - _keys); - break _match; - } - } - _keys += _klen; - _trans += _klen; - } - - _klen = _JSON_quirks_mode_range_lengths[cs]; - if ( _klen > 0 ) { - int _lower = _keys; - int _mid; - int _upper = _keys + (_klen<<1) - 2; - while (true) { - if ( _upper < _lower ) - break; - - _mid = _lower + (((_upper-_lower) >> 1) & ~1); - if ( data[p] < _JSON_quirks_mode_trans_keys[_mid] ) - _upper = _mid - 2; - else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] ) - _lower = _mid + 2; - else { - _trans += ((_mid - _keys)>>1); - break _match; - } - } - _trans += _klen; - } - } while (false); - - _trans = _JSON_quirks_mode_indicies[_trans]; - cs = _JSON_quirks_mode_trans_targs[_trans]; - - if ( _JSON_quirks_mode_trans_actions[_trans] != 0 ) { - _acts = _JSON_quirks_mode_trans_actions[_trans]; - _nacts = (int) _JSON_quirks_mode_actions[_acts++]; - while ( _nacts-- > 0 ) - { - switch ( _JSON_quirks_mode_actions[_acts++] ) - { - case 0: -// line 893 "Parser.rl" +// line 798 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2570,7 +2269,7 @@ else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] ) } } break; -// line 2575 "Parser.java" +// line 2273 "Parser.java" } } } @@ -2590,9 +2289,9 @@ else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] ) break; } } -// line 919 "Parser.rl" +// line 824 "Parser.rl" - if (cs >= JSON_quirks_mode_first_final && p == pe) { + if (cs >= JSON_first_final && p == pe) { return result; } else { throw unexpectedToken(p, pe); @@ -2600,12 +2299,7 @@ else if ( data[p] > _JSON_quirks_mode_trans_keys[_mid+1] ) } public IRubyObject parse() { - if (parser.quirksMode) { - return parseQuirksMode(); - } else { - return parseStrict(); - } - + return parseImplemetation(); } /** diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index d43c74f99..17ea303fb 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -50,10 +50,9 @@ public class Parser extends RubyObject { private int maxNesting; private boolean allowNaN; private boolean symbolizeNames; - private boolean quirksMode; private RubyClass objectClass; private RubyClass arrayClass; - private RubyHash match_string; + private RubyHash matchString; private static final int DEFAULT_MAX_NESTING = 100; @@ -121,10 +120,6 @@ public class Parser extends RubyObject { *

If set to true, returns symbols for the names (keys) in * a JSON object. Otherwise strings are returned, which is also the default. * - *
:quirks_mode? - *
If set to true, if the parse is in quirks_mode, false - * otherwise. - * *
:create_additions *
If set to false, the Parser doesn't create additions * even if a matching class and create_id was found. This option @@ -136,9 +131,6 @@ public class Parser extends RubyObject { *
:array_class *
Defaults to Array. * - *
:quirks_mode - *
Enables quirks_mode for parser, that is for example parsing single - * JSON values instead of documents is possible. * */ @JRubyMethod(name = "new", required = 1, optional = 1, meta = true) @@ -161,15 +153,20 @@ public class Parser extends RubyObject { this.maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING); this.allowNaN = opts.getBool("allow_nan", false); this.symbolizeNames = opts.getBool("symbolize_names", false); - this.quirksMode = opts.getBool("quirks_mode", false); this.createId = opts.getString("create_id", getCreateId(context)); this.createAdditions = opts.getBool("create_additions", false); this.objectClass = opts.getClass("object_class", runtime.getHash()); this.arrayClass = opts.getClass("array_class", runtime.getArray()); - this.match_string = opts.getHash("match_string"); + this.matchString = opts.getHash("match_string"); + if(symbolizeNames && createAdditions) { + throw runtime.newArgumentError( + "options :symbolize_names and :create_additions cannot be " + + " used in conjunction" + ); + } this.vSource = args[0].convertToString(); - if (!quirksMode) this.vSource = convertEncoding(context, vSource); + this.vSource = convertEncoding(context, vSource); return this; } @@ -180,33 +177,7 @@ public class Parser extends RubyObject { * Returns the source string if no conversion is needed. */ private RubyString convertEncoding(ThreadContext context, RubyString source) { - ByteList bl = source.getByteList(); - int len = bl.length(); - if (len < 2) { - throw Utils.newException(context, Utils.M_PARSER_ERROR, - "A JSON text must at least contain two octets!"); - } - - if (info.encodingsSupported()) { - RubyEncoding encoding = (RubyEncoding)source.encoding(context); - if (encoding != info.ascii8bit.get()) { - return (RubyString)source.encode(context, info.utf8.get()); - } - - String sniffedEncoding = sniffByteList(bl); - if (sniffedEncoding == null) return source; // assume UTF-8 - return reinterpretEncoding(context, source, sniffedEncoding); - } - - String sniffedEncoding = sniffByteList(bl); - if (sniffedEncoding == null) return source; // assume UTF-8 - Ruby runtime = context.getRuntime(); - return (RubyString)info.jsonModule.get(). - callMethod(context, "iconv", - new IRubyObject[] { - runtime.newString("utf-8"), - runtime.newString(sniffedEncoding), - source}); + return (RubyString)source.encode(context, info.utf8.get()); } /** @@ -259,17 +230,6 @@ public class Parser extends RubyObject { return checkAndGetSource().dup(); } - /** - * Parser#quirks_mode?() - * - *

If set to true, if the parse is in quirks_mode, false - * otherwise. - */ - @JRubyMethod(name = "quirks_mode?") - public IRubyObject quirks_mode_p(ThreadContext context) { - return context.getRuntime().newBoolean(quirksMode); - } - public RubyString checkAndGetSource() { if (vSource != null) { return vSource; @@ -393,7 +353,7 @@ public class Parser extends RubyObject { } } action parse_number { - if (pe > fpc + 9 - (parser.quirksMode ? 1 : 0) && + if (pe > fpc + 8 && absSubSequence(fpc, fpc + 9).equals(JSON_MINUS_INFINITY)) { if (parser.allowNaN) { @@ -623,11 +583,11 @@ public class Parser extends RubyObject { %% write exec; if (parser.createAdditions) { - RubyHash match_string = parser.match_string; - if (match_string != null) { + RubyHash matchString = parser.matchString; + if (matchString != null) { final IRubyObject[] memoArray = { result, null }; try { - match_string.visitAll(new RubyHash.Visitor() { + matchString.visitAll(new RubyHash.Visitor() { @Override public void visit(IRubyObject pattern, IRubyObject klass) { if (pattern.callMethod(context, "===", memoArray[0]).isTrue()) { @@ -648,7 +608,7 @@ public class Parser extends RubyObject { } if (cs >= JSON_string_first_final && result != null) { - if (info.encodingsSupported() && result instanceof RubyString) { + if (result instanceof RubyString) { ((RubyString)result).force_encoding(context, info.utf8.get()); } res.update(result, p + 1); @@ -835,60 +795,6 @@ public class Parser extends RubyObject { write data; - action parse_object { - currentNesting = 1; - parseObject(res, fpc, pe); - if (res.result == null) { - fhold; - fbreak; - } else { - result = res.result; - fexec res.p; - } - } - - action parse_array { - currentNesting = 1; - parseArray(res, fpc, pe); - if (res.result == null) { - fhold; - fbreak; - } else { - result = res.result; - fexec res.p; - } - } - - main := ignore* - ( begin_object >parse_object - | begin_array >parse_array ) - ignore*; - }%% - - public IRubyObject parseStrict() { - int cs = EVIL; - int p, pe; - IRubyObject result = null; - ParserResult res = new ParserResult(); - - %% write init; - p = byteList.begin(); - pe = p + byteList.length(); - %% write exec; - - if (cs >= JSON_first_final && p == pe) { - return result; - } else { - throw unexpectedToken(p, pe); - } - } - - %%{ - machine JSON_quirks_mode; - include JSON_common; - - write data; - action parse_value { parseValue(res, fpc, pe); if (res.result == null) { @@ -905,7 +811,7 @@ public class Parser extends RubyObject { ignore*; }%% - public IRubyObject parseQuirksMode() { + public IRubyObject parseImplemetation() { int cs = EVIL; int p, pe; IRubyObject result = null; @@ -916,7 +822,7 @@ public class Parser extends RubyObject { pe = p + byteList.length(); %% write exec; - if (cs >= JSON_quirks_mode_first_final && p == pe) { + if (cs >= JSON_first_final && p == pe) { return result; } else { throw unexpectedToken(p, pe); @@ -924,12 +830,7 @@ public class Parser extends RubyObject { } public IRubyObject parse() { - if (parser.quirksMode) { - return parseQuirksMode(); - } else { - return parseStrict(); - } - + return parseImplemetation(); } /** diff --git a/java/src/json/ext/RuntimeInfo.java b/java/src/json/ext/RuntimeInfo.java index ceaca5bad..2323bd942 100644 --- a/java/src/json/ext/RuntimeInfo.java +++ b/java/src/json/ext/RuntimeInfo.java @@ -90,10 +90,6 @@ public static RuntimeInfo forRuntime(Ruby runtime) { } } - public boolean encodingsSupported() { - return utf8 != null && utf8.get() != null; - } - public RubyEncoding getEncoding(ThreadContext context, String name) { synchronized (encodings) { WeakReference encoding = encodings.get(name); diff --git a/json.gemspec b/json.gemspec index a9493ff60a417c5cd266723aa9a2249adf5029ed..e6b4afdc469d0c8417a4abbbe5ccf541af774e2d 100644 GIT binary patch delta 49 zcmcbk^i65QWJVS= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2016-02-25" + s.date = "2016-06-02" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.md"] - s.files = ["./tests/test_helper.rb", ".gitignore", ".travis.yml", "CHANGES", "Gemfile", "README-json-jruby.markdown", "README.md", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/obsolete_fail1.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/json_addition_test.rb", "tests/json_common_interface_test.rb", "tests/json_encoding_test.rb", "tests/json_ext_parser_test.rb", "tests/json_fixtures_test.rb", "tests/json_generator_test.rb", "tests/json_generic_object_test.rb", "tests/json_parser_test.rb", "tests/json_string_matching_test.rb", "tests/test_helper.rb", "tools/fuzz.rb", "tools/server.rb"] + s.files = ["./tests/test_helper.rb", ".gitignore", ".travis.yml", "CHANGES", "Gemfile", "README-json-jruby.markdown", "README.md", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "references/rfc7159.txt", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/obsolete_fail1.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/json_addition_test.rb", "tests/json_common_interface_test.rb", "tests/json_encoding_test.rb", "tests/json_ext_parser_test.rb", "tests/json_fixtures_test.rb", "tests/json_generator_test.rb", "tests/json_generic_object_test.rb", "tests/json_parser_test.rb", "tests/json_string_matching_test.rb", "tests/test_helper.rb", "tools/fuzz.rb", "tools/server.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.md"] diff --git a/lib/json/common.rb b/lib/json/common.rb index c47938f23..209c3e7d7 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -295,13 +295,13 @@ class << self # The global default options for the JSON.load method: # :max_nesting: false # :allow_nan: true - # :quirks_mode: true + # :allow_null: true attr_accessor :load_default_options end self.load_default_options = { :max_nesting => false, :allow_nan => true, - :quirks_mode => true, + :allow_null => true, :create_additions => true, } @@ -328,7 +328,7 @@ def load(source, proc = nil, options = {}) elsif source.respond_to?(:read) source = source.read end - if opts[:quirks_mode] && (source.nil? || source.empty?) + if opts[:allow_null] && (source.nil? || source.empty?) source = 'null' end result = parse(source, opts) @@ -357,13 +357,12 @@ class << self # The global default options for the JSON.dump method: # :max_nesting: false # :allow_nan: true - # :quirks_mode: true + # :allow_null: true attr_accessor :dump_default_options end self.dump_default_options = { :max_nesting => false, :allow_nan => true, - :quirks_mode => true, } # Dumps _obj_ as a JSON string, i.e. calls generate on the object and returns diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index cc8b0fde5..cf4afff91 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -154,8 +154,6 @@ def self.from_state(opts) # * *allow_nan*: true if NaN, Infinity, and -Infinity should be # generated, otherwise an exception is thrown, if these values are # encountered. This options defaults to false. - # * *quirks_mode*: Enables quirks_mode for parser, that is for example - # generating single JSON values instead of documents is possible. def initialize(opts = {}) @indent = '' @space = '' @@ -164,7 +162,6 @@ def initialize(opts = {}) @array_nl = '' @allow_nan = false @ascii_only = false - @quirks_mode = false @buffer_initial_length = 1024 configure opts end @@ -190,10 +187,6 @@ def initialize(opts = {}) # the generated JSON, max_nesting = 0 if no maximum is checked. attr_accessor :max_nesting - # If this attribute is set to true, quirks mode is enabled, otherwise - # it's disabled. - attr_accessor :quirks_mode - # :stopdoc: attr_reader :buffer_initial_length @@ -233,11 +226,6 @@ def ascii_only? @ascii_only end - # Returns true, if quirks mode is enabled. Otherwise returns false. - def quirks_mode? - @quirks_mode - end - # Configure this State instance with the Hash _opts_, and return # itself. def configure(opts) @@ -259,7 +247,6 @@ def configure(opts) @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan) @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only) @depth = opts[:depth] || 0 - @quirks_mode = opts[:quirks_mode] if opts.key?(:quirks_mode) @buffer_initial_length ||= opts[:buffer_initial_length] if !opts.key?(:max_nesting) # defaults to 100 diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index c96fadb11..b2e841b67 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -69,13 +69,9 @@ class Parser < StringScanner # option defaults to false. # * *object_class*: Defaults to Hash # * *array_class*: Defaults to Array - # * *quirks_mode*: Enables quirks_mode for parser, that is for example - # parsing single JSON values instead of documents is possible. def initialize(source, opts = {}) opts ||= {} - unless @quirks_mode = opts[:quirks_mode] - source = convert_encoding source - end + source = convert_encoding source super source if !opts.key?(:max_nesting) # defaults to 100 @max_nesting = 100 @@ -102,10 +98,6 @@ def initialize(source, opts = {}) alias source string - def quirks_mode? - !!@quirks_mode - end - def reset super @current_nesting = 0 @@ -138,10 +130,8 @@ def convert_encoding(source) raise TypeError, "#{source.inspect} is not like a string" end - if defined?(::Encoding) - source = source.encode(::Encoding::UTF_8) - source.force_encoding(::Encoding::ASCII_8BIT) - end + source = source.encode(::Encoding::UTF_8) + source.force_encoding(::Encoding::ASCII_8BIT) source end diff --git a/tests/json_common_interface_test.rb b/tests/json_common_interface_test.rb index 648532851..382c77b1b 100644 --- a/tests/json_common_interface_test.rb +++ b/tests/json_common_interface_test.rb @@ -70,6 +70,12 @@ def test_load_with_options assert JSON.load(json, nil, :allow_nan => true)['foo'].nan? end + def test_load_null + assert_equal nil, JSON.load(nil, nil, :allow_null => true) + assert_raises(TypeError) { JSON.load(nil, nil, :allow_null => false) } + assert_raises(JSON::ParserError) { JSON.load('', nil, :allow_null => false) } + end + def test_dump too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]' assert_equal too_deep, dump(eval(too_deep)) @@ -92,7 +98,6 @@ def test_dump_should_modify_defaults assert_equal max_nesting, JSON.dump_default_options[:max_nesting] end - def test_JSON end end diff --git a/tests/json_generator_test.rb b/tests/json_generator_test.rb index 2bb7e15e9..75e19d911 100644 --- a/tests/json_generator_test.rb +++ b/tests/json_generator_test.rb @@ -135,7 +135,6 @@ def test_pretty_state :array_nl => "\n", :ascii_only => false, :buffer_initial_length => 1024, - :quirks_mode => false, :depth => 0, :indent => " ", :max_nesting => 100, @@ -152,7 +151,6 @@ def test_safe_state :array_nl => "", :ascii_only => false, :buffer_initial_length => 1024, - :quirks_mode => false, :depth => 0, :indent => "", :max_nesting => 100, @@ -169,7 +167,6 @@ def test_fast_state :array_nl => "", :ascii_only => false, :buffer_initial_length => 1024, - :quirks_mode => false, :depth => 0, :indent => "", :max_nesting => 0, diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb index 1123aaba0..a5793f902 100644 --- a/tests/json_parser_test.rb +++ b/tests/json_parser_test.rb @@ -137,7 +137,7 @@ def test_parse_json_primitive_values assert parse('NaN', :allow_nan => true).nan? assert parse('Infinity', :allow_nan => true).infinite? assert parse('-Infinity', :allow_nan => true).infinite? - assert_raise(JSON::ParserError) { parse('[ 1, ]', :quirks_mode => true) } + assert_raise(JSON::ParserError) { parse('[ 1, ]') } end def test_parse_some_strings diff --git a/tests/test_helper.rb b/tests/test_helper.rb index 9d3665d47..752f5f536 100644 --- a/tests/test_helper.rb +++ b/tests/test_helper.rb @@ -17,7 +17,3 @@ require 'byebug' rescue LoadError end -if ENV['START_SIMPLECOV'].to_i == 1 - require 'simplecov' - SimpleCov.start -end From 10d54d93ec145578063947951acd9f1777ea9245 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 2 Jun 2016 21:13:53 +0200 Subject: [PATCH 126/312] Use better name for this feature --- json.gemspec | Bin 4470 -> 4462 bytes json_pure.gemspec | 2 +- lib/json/common.rb | 8 ++++---- tests/json_common_interface_test.rb | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/json.gemspec b/json.gemspec index e6b4afdc469d0c8417a4abbbe5ccf541af774e2d..aa2ea551e2a4c5539b5af907648964f777b05e37 100644 GIT binary patch delta 12 TcmeyS^iFAm2J>bEW;Z?nBNPNa delta 17 YcmaE-^i64l1~W^Dzl;B76=p9!06RJbZ~y=R diff --git a/json_pure.gemspec b/json_pure.gemspec index a93dbf930..5fef9d9ff 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.md"] - s.files = ["./tests/test_helper.rb", ".gitignore", ".travis.yml", "CHANGES", "Gemfile", "README-json-jruby.markdown", "README.md", "Rakefile", "TODO", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "references/rfc7159.txt", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/obsolete_fail1.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/json_addition_test.rb", "tests/json_common_interface_test.rb", "tests/json_encoding_test.rb", "tests/json_ext_parser_test.rb", "tests/json_fixtures_test.rb", "tests/json_generator_test.rb", "tests/json_generic_object_test.rb", "tests/json_parser_test.rb", "tests/json_string_matching_test.rb", "tests/test_helper.rb", "tools/fuzz.rb", "tools/server.rb"] + s.files = ["./tests/test_helper.rb", ".gitignore", ".travis.yml", "CHANGES", "Gemfile", "README-json-jruby.markdown", "README.md", "Rakefile", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "references/rfc7159.txt", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/obsolete_fail1.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/json_addition_test.rb", "tests/json_common_interface_test.rb", "tests/json_encoding_test.rb", "tests/json_ext_parser_test.rb", "tests/json_fixtures_test.rb", "tests/json_generator_test.rb", "tests/json_generic_object_test.rb", "tests/json_parser_test.rb", "tests/json_string_matching_test.rb", "tests/test_helper.rb", "tools/fuzz.rb", "tools/server.rb"] s.homepage = "http://flori.github.com/json" s.licenses = ["Ruby"] s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.md"] diff --git a/lib/json/common.rb b/lib/json/common.rb index 209c3e7d7..f01e7a1ae 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -295,13 +295,13 @@ class << self # The global default options for the JSON.load method: # :max_nesting: false # :allow_nan: true - # :allow_null: true + # :allow_blank: true attr_accessor :load_default_options end self.load_default_options = { :max_nesting => false, :allow_nan => true, - :allow_null => true, + :allow_blank => true, :create_additions => true, } @@ -328,7 +328,7 @@ def load(source, proc = nil, options = {}) elsif source.respond_to?(:read) source = source.read end - if opts[:allow_null] && (source.nil? || source.empty?) + if opts[:allow_blank] && (source.nil? || source.empty?) source = 'null' end result = parse(source, opts) @@ -357,7 +357,7 @@ class << self # The global default options for the JSON.dump method: # :max_nesting: false # :allow_nan: true - # :allow_null: true + # :allow_blank: true attr_accessor :dump_default_options end self.dump_default_options = { diff --git a/tests/json_common_interface_test.rb b/tests/json_common_interface_test.rb index 382c77b1b..a2de037d1 100644 --- a/tests/json_common_interface_test.rb +++ b/tests/json_common_interface_test.rb @@ -71,9 +71,9 @@ def test_load_with_options end def test_load_null - assert_equal nil, JSON.load(nil, nil, :allow_null => true) - assert_raises(TypeError) { JSON.load(nil, nil, :allow_null => false) } - assert_raises(JSON::ParserError) { JSON.load('', nil, :allow_null => false) } + assert_equal nil, JSON.load(nil, nil, :allow_blank => true) + assert_raises(TypeError) { JSON.load(nil, nil, :allow_blank => false) } + assert_raises(JSON::ParserError) { JSON.load('', nil, :allow_blank => false) } end def test_dump From 79074a0de768113364749cb584000b7e97be04e5 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 3 Jun 2016 12:06:53 +0200 Subject: [PATCH 127/312] Test common interface --- lib/json/common.rb | 18 ++++-------------- tests/json_common_interface_test.rb | 24 +++++++++++++++++++++++- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/lib/json/common.rb b/lib/json/common.rb index f01e7a1ae..55908f8b5 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -24,7 +24,7 @@ def [](object, opts = {}) # Set the JSON parser class _parser_ to be used by JSON. def parser=(parser) # :nodoc: @parser = parser - remove_const :Parser if JSON.const_defined_in?(self, :Parser) + remove_const :Parser if const_defined?(:Parser, true) const_set :Parser, parser end @@ -35,8 +35,8 @@ def parser=(parser) # :nodoc: def deep_const_get(path) # :nodoc: path.to_s.split(/::/).inject(Object) do |p, c| case - when c.empty? then p - when JSON.const_defined_in?(p, c) then p.const_get(c) + when c.empty? then p + when p.const_defined?(c, true) then p.const_get(c) else begin p.const_missing(c) @@ -174,7 +174,7 @@ def parse!(source, opts = {}) opts = { :max_nesting => false, :allow_nan => true - }.update(opts) + }.merge(opts) Parser.new(source, opts).parse end @@ -405,16 +405,6 @@ def dump(obj, anIO = nil, limit = nil) def self.iconv(to, from, string) string.encode(to, from) end - - if ::Object.method(:const_defined?).arity == 1 - def self.const_defined_in?(modul, constant) - modul.const_defined?(constant) - end - else - def self.const_defined_in?(modul, constant) - modul.const_defined?(constant, false) - end - end end module ::Kernel diff --git a/tests/json_common_interface_test.rb b/tests/json_common_interface_test.rb index a2de037d1..38136fa91 100644 --- a/tests/json_common_interface_test.rb +++ b/tests/json_common_interface_test.rb @@ -17,37 +17,57 @@ def setup 'i' => 0.001 } @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\ - '"g":"\\"\\u0000\\u001f","h":1.0E3,"i":1.0E-3}' + '"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}' end def test_index + assert_equal @json, JSON[@hash] + assert_equal @hash, JSON[@json] end def test_parser + assert_match /::Parser\z/, JSON.parser.name end def test_generator + assert_match /::Generator\z/, JSON.generator.name end def test_state + assert_match /::Generator::State\z/, JSON.state.name end def test_create_id + assert_equal 'json_class', JSON.create_id + JSON.create_id = 'foo_bar' + assert_equal 'foo_bar', JSON.create_id + ensure + JSON.create_id = 'json_class' + end + + def test_deep_const_get + assert_raises(ArgumentError) { JSON.deep_const_get('Nix::Da') } + assert_equal File::SEPARATOR, JSON.deep_const_get('File::SEPARATOR') end def test_parse + assert_equal [ 1, 2, 3, ], JSON.parse('[ 1, 2, 3 ]') end def test_parse_bang + assert_equal [ 1, NaN, 3, ], JSON.parse!('[ 1, NaN, 3 ]') end def test_generate + assert_equal '[1,2,3]', JSON.generate([ 1, 2, 3 ]) end def test_fast_generate + assert_equal '[1,2,3]', JSON.generate([ 1, 2, 3 ]) end def test_pretty_generate + assert_equal "[\n 1,\n 2,\n 3\n]", JSON.pretty_generate([ 1, 2, 3 ]) end def test_load @@ -99,5 +119,7 @@ def test_dump_should_modify_defaults end def test_JSON + assert_equal @json, JSON(@hash) + assert_equal @hash, JSON(@json) end end From ac0e272c9d2cb3c6d692ecefe2d1d8e5c1201120 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 3 Jun 2016 13:05:23 +0200 Subject: [PATCH 128/312] Only support newer Rubies e. g. Encoding --- lib/json/pure/generator.rb | 148 +++++++++++----------------------- tests/json_encoding_test.rb | 10 +-- tests/json_ext_parser_test.rb | 3 - tests/json_generator_test.rb | 1 - 4 files changed, 48 insertions(+), 114 deletions(-) diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index cf4afff91..98bc369fd 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -38,85 +38,45 @@ module JSON # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with # UTF16 big endian characters as \u????, and return it. - if defined?(::Encoding) - def utf8_to_json(string) # :nodoc: - string = string.dup - string.force_encoding(::Encoding::ASCII_8BIT) - string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] } - string.force_encoding(::Encoding::UTF_8) - string - end - - def utf8_to_json_ascii(string) # :nodoc: - string = string.dup - string.force_encoding(::Encoding::ASCII_8BIT) - string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] } - string.gsub!(/( - (?: - [\xc2-\xdf][\x80-\xbf] | - [\xe0-\xef][\x80-\xbf]{2} | - [\xf0-\xf4][\x80-\xbf]{3} - )+ | - [\x80-\xc1\xf5-\xff] # invalid - )/nx) { |c| - c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'" - s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0] - s.force_encoding(::Encoding::ASCII_8BIT) - s.gsub!(/.{4}/n, '\\\\u\&') - s.force_encoding(::Encoding::UTF_8) - } - string.force_encoding(::Encoding::UTF_8) - string - rescue => e - raise GeneratorError.wrap(e) - end - - def valid_utf8?(string) - encoding = string.encoding - (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) && - string.valid_encoding? - end - module_function :valid_utf8? - else - def utf8_to_json(string) # :nodoc: - string.gsub(/["\\\x0-\x1f]/n) { MAP[$&] } - end + def utf8_to_json(string) # :nodoc: + string = string.dup + string.force_encoding(::Encoding::ASCII_8BIT) + string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] } + string.force_encoding(::Encoding::UTF_8) + string + end - def utf8_to_json_ascii(string) # :nodoc: - string = string.gsub(/["\\\x0-\x1f]/) { MAP[$&] } - string.gsub!(/( - (?: - [\xc2-\xdf][\x80-\xbf] | - [\xe0-\xef][\x80-\xbf]{2} | - [\xf0-\xf4][\x80-\xbf]{3} - )+ | - [\x80-\xc1\xf5-\xff] # invalid - )/nx) { |c| - c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'" - s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0] - s.gsub!(/.{4}/n, '\\\\u\&') - } - string - rescue => e - raise GeneratorError.wrap(e) - end + def utf8_to_json_ascii(string) # :nodoc: + string = string.dup + string.force_encoding(::Encoding::ASCII_8BIT) + string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] } + string.gsub!(/( + (?: + [\xc2-\xdf][\x80-\xbf] | + [\xe0-\xef][\x80-\xbf]{2} | + [\xf0-\xf4][\x80-\xbf]{3} + )+ | + [\x80-\xc1\xf5-\xff] # invalid + )/nx) { |c| + c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'" + s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0] + s.force_encoding(::Encoding::ASCII_8BIT) + s.gsub!(/.{4}/n, '\\\\u\&') + s.force_encoding(::Encoding::UTF_8) + } + string.force_encoding(::Encoding::UTF_8) + string + rescue => e + raise GeneratorError.wrap(e) + end - def valid_utf8?(string) - string =~ - /\A( [\x09\x0a\x0d\x20-\x7e] # ASCII - | [\xc2-\xdf][\x80-\xbf] # non-overlong 2-byte - | \xe0[\xa0-\xbf][\x80-\xbf] # excluding overlongs - | [\xe1-\xec\xee\xef][\x80-\xbf]{2} # straight 3-byte - | \xed[\x80-\x9f][\x80-\xbf] # excluding surrogates - | \xf0[\x90-\xbf][\x80-\xbf]{2} # planes 1-3 - | [\xf1-\xf3][\x80-\xbf]{3} # planes 4-15 - | \xf4[\x80-\x8f][\x80-\xbf]{2} # plane 16 - )*\z/nx - end + def valid_utf8?(string) + encoding = string.encoding + (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) && + string.valid_encoding? end module_function :utf8_to_json, :utf8_to_json_ascii, :valid_utf8? - module Pure module Generator # This class is used to create State instances, that are use to hold data @@ -426,34 +386,20 @@ def to_json(state = nil, *) end module String - if defined?(::Encoding) - # This string should be encoded with UTF-8 A call to this method - # returns a JSON string encoded with UTF16 big endian characters as - # \u????. - def to_json(state = nil, *args) - state = State.from_state(state) - if encoding == ::Encoding::UTF_8 - string = self - else - string = encode(::Encoding::UTF_8) - end - if state.ascii_only? - '"' << JSON.utf8_to_json_ascii(string) << '"' - else - '"' << JSON.utf8_to_json(string) << '"' - end + # This string should be encoded with UTF-8 A call to this method + # returns a JSON string encoded with UTF16 big endian characters as + # \u????. + def to_json(state = nil, *args) + state = State.from_state(state) + if encoding == ::Encoding::UTF_8 + string = self + else + string = encode(::Encoding::UTF_8) end - else - # This string should be encoded with UTF-8 A call to this method - # returns a JSON string encoded with UTF16 big endian characters as - # \u????. - def to_json(state = nil, *args) - state = State.from_state(state) - if state.ascii_only? - '"' << JSON.utf8_to_json_ascii(self) << '"' - else - '"' << JSON.utf8_to_json(self) << '"' - end + if state.ascii_only? + '"' << JSON.utf8_to_json_ascii(string) << '"' + else + '"' << JSON.utf8_to_json(string) << '"' end end diff --git a/tests/json_encoding_test.rb b/tests/json_encoding_test.rb index c220f90c7..f8b88d2fa 100644 --- a/tests/json_encoding_test.rb +++ b/tests/json_encoding_test.rb @@ -34,15 +34,7 @@ def test_parse def test_generate assert_equal @generated, JSON.generate(@parsed, :ascii_only => true) - if defined?(::Encoding) - assert_equal @generated, JSON.generate(@utf_16_data, :ascii_only => true) - else - # XXX checking of correct utf8 data is not as strict (yet?) without - # :ascii_only - assert_raises(JSON::GeneratorError) do - JSON.generate(@utf_16_data, :ascii_only => true) - end - end + assert_equal @generated, JSON.generate(@utf_16_data, :ascii_only => true) end def test_unicode diff --git a/tests/json_ext_parser_test.rb b/tests/json_ext_parser_test.rb index da3bdc156..ade97843e 100644 --- a/tests/json_ext_parser_test.rb +++ b/tests/json_ext_parser_test.rb @@ -1,7 +1,4 @@ require 'test_helper' -require 'stringio' -require 'tempfile' -require 'ostruct' class JSONExtParserTest < Test::Unit::TestCase if defined?(JSON::Ext::Parser) diff --git a/tests/json_generator_test.rb b/tests/json_generator_test.rb index 75e19d911..708747163 100644 --- a/tests/json_generator_test.rb +++ b/tests/json_generator_test.rb @@ -372,6 +372,5 @@ def to_s; self; end assert_nothing_raised(SystemStackError) do assert_equal '["foo"]', JSON.generate([s.new('foo')]) end - end end From 7f6b0e3766a83a05aa7bf8351be5e3b478d5b7a6 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 3 Jun 2016 13:39:17 +0200 Subject: [PATCH 129/312] Force ASCII 8bit to be UTF-8 and hope for the best --- ext/json/ext/parser/parser.c | 162 +++++++++++++++++----------------- ext/json/ext/parser/parser.rl | 16 ++-- 2 files changed, 93 insertions(+), 85 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index c63a4621c..5b2e61c52 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -68,9 +68,8 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) } #ifdef HAVE_RUBY_ENCODING_H -static VALUE CEncoding_UTF_8; - -static ID i_encode; +static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8; +static ID i_encoding, i_encode; #else static ID i_iconv; #endif @@ -84,11 +83,11 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_match_string, i_aset, i_aref, i_leftshift; -#line 110 "parser.rl" +#line 109 "parser.rl" -#line 92 "parser.c" +#line 91 "parser.c" static const int JSON_object_start = 1; static const int JSON_object_first_final = 27; static const int JSON_object_error = 0; @@ -96,7 +95,7 @@ static const int JSON_object_error = 0; static const int JSON_object_en_main = 1; -#line 151 "parser.rl" +#line 150 "parser.rl" static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -112,14 +111,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class); -#line 116 "parser.c" +#line 115 "parser.c" { cs = JSON_object_start; } -#line 166 "parser.rl" +#line 165 "parser.rl" -#line 123 "parser.c" +#line 122 "parser.c" { if ( p == pe ) goto _test_eof; @@ -147,7 +146,7 @@ case 2: goto st2; goto st0; tr2: -#line 133 "parser.rl" +#line 132 "parser.rl" { char *np; json->parsing_name = 1; @@ -160,7 +159,7 @@ case 2: if ( ++p == pe ) goto _test_eof3; case 3: -#line 164 "parser.c" +#line 163 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -227,7 +226,7 @@ case 8: goto st8; goto st0; tr11: -#line 118 "parser.rl" +#line 117 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v); @@ -247,7 +246,7 @@ case 8: if ( ++p == pe ) goto _test_eof9; case 9: -#line 251 "parser.c" +#line 250 "parser.c" switch( (*p) ) { case 13: goto st9; case 32: goto st9; @@ -336,14 +335,14 @@ case 18: goto st9; goto st18; tr4: -#line 141 "parser.rl" +#line 140 "parser.rl" { p--; {p++; cs = 27; goto _out;} } goto st27; st27: if ( ++p == pe ) goto _test_eof27; case 27: -#line 347 "parser.c" +#line 346 "parser.c" goto st0; st19: if ( ++p == pe ) @@ -441,7 +440,7 @@ case 26: _out: {} } -#line 167 "parser.rl" +#line 166 "parser.rl" if (cs >= JSON_object_first_final) { if (json->create_additions) { @@ -466,7 +465,7 @@ case 26: -#line 470 "parser.c" +#line 469 "parser.c" static const int JSON_value_start = 1; static const int JSON_value_first_final = 29; static const int JSON_value_error = 0; @@ -474,7 +473,7 @@ static const int JSON_value_error = 0; static const int JSON_value_en_main = 1; -#line 271 "parser.rl" +#line 270 "parser.rl" static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -482,14 +481,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 486 "parser.c" +#line 485 "parser.c" { cs = JSON_value_start; } -#line 278 "parser.rl" +#line 277 "parser.rl" -#line 493 "parser.c" +#line 492 "parser.c" { if ( p == pe ) goto _test_eof; @@ -523,14 +522,14 @@ case 1: cs = 0; goto _out; tr2: -#line 219 "parser.rl" +#line 218 "parser.rl" { char *np = JSON_parse_string(json, p, pe, result); if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } goto st29; tr3: -#line 224 "parser.rl" +#line 223 "parser.rl" { char *np; if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) { @@ -550,7 +549,7 @@ cs = 0; } goto st29; tr7: -#line 242 "parser.rl" +#line 241 "parser.rl" { char *np; json->current_nesting++; @@ -560,7 +559,7 @@ cs = 0; } goto st29; tr11: -#line 250 "parser.rl" +#line 249 "parser.rl" { char *np; json->current_nesting++; @@ -570,7 +569,7 @@ cs = 0; } goto st29; tr25: -#line 212 "parser.rl" +#line 211 "parser.rl" { if (json->allow_nan) { *result = CInfinity; @@ -580,7 +579,7 @@ cs = 0; } goto st29; tr27: -#line 205 "parser.rl" +#line 204 "parser.rl" { if (json->allow_nan) { *result = CNaN; @@ -590,19 +589,19 @@ cs = 0; } goto st29; tr31: -#line 199 "parser.rl" +#line 198 "parser.rl" { *result = Qfalse; } goto st29; tr34: -#line 196 "parser.rl" +#line 195 "parser.rl" { *result = Qnil; } goto st29; tr37: -#line 202 "parser.rl" +#line 201 "parser.rl" { *result = Qtrue; } @@ -611,9 +610,9 @@ cs = 0; if ( ++p == pe ) goto _test_eof29; case 29: -#line 258 "parser.rl" +#line 257 "parser.rl" { p--; {p++; cs = 29; goto _out;} } -#line 617 "parser.c" +#line 616 "parser.c" switch( (*p) ) { case 13: goto st29; case 32: goto st29; @@ -854,7 +853,7 @@ case 28: _out: {} } -#line 279 "parser.rl" +#line 278 "parser.rl" if (cs >= JSON_value_first_final) { return p; @@ -864,7 +863,7 @@ case 28: } -#line 868 "parser.c" +#line 867 "parser.c" static const int JSON_integer_start = 1; static const int JSON_integer_first_final = 3; static const int JSON_integer_error = 0; @@ -872,7 +871,7 @@ static const int JSON_integer_error = 0; static const int JSON_integer_en_main = 1; -#line 295 "parser.rl" +#line 294 "parser.rl" static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -880,15 +879,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res int cs = EVIL; -#line 884 "parser.c" +#line 883 "parser.c" { cs = JSON_integer_start; } -#line 302 "parser.rl" +#line 301 "parser.rl" json->memo = p; -#line 892 "parser.c" +#line 891 "parser.c" { if ( p == pe ) goto _test_eof; @@ -922,14 +921,14 @@ case 3: goto st0; goto tr4; tr4: -#line 292 "parser.rl" +#line 291 "parser.rl" { p--; {p++; cs = 4; goto _out;} } goto st4; st4: if ( ++p == pe ) goto _test_eof4; case 4: -#line 933 "parser.c" +#line 932 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -948,7 +947,7 @@ case 5: _out: {} } -#line 304 "parser.rl" +#line 303 "parser.rl" if (cs >= JSON_integer_first_final) { long len = p - json->memo; @@ -963,7 +962,7 @@ case 5: } -#line 967 "parser.c" +#line 966 "parser.c" static const int JSON_float_start = 1; static const int JSON_float_first_final = 8; static const int JSON_float_error = 0; @@ -971,7 +970,7 @@ static const int JSON_float_error = 0; static const int JSON_float_en_main = 1; -#line 329 "parser.rl" +#line 328 "parser.rl" static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -979,15 +978,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 983 "parser.c" +#line 982 "parser.c" { cs = JSON_float_start; } -#line 336 "parser.rl" +#line 335 "parser.rl" json->memo = p; -#line 991 "parser.c" +#line 990 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1045,14 +1044,14 @@ case 8: goto st0; goto tr9; tr9: -#line 323 "parser.rl" +#line 322 "parser.rl" { p--; {p++; cs = 9; goto _out;} } goto st9; st9: if ( ++p == pe ) goto _test_eof9; case 9: -#line 1056 "parser.c" +#line 1055 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -1113,7 +1112,7 @@ case 7: _out: {} } -#line 338 "parser.rl" +#line 337 "parser.rl" if (cs >= JSON_float_first_final) { long len = p - json->memo; @@ -1129,7 +1128,7 @@ case 7: -#line 1133 "parser.c" +#line 1132 "parser.c" static const int JSON_array_start = 1; static const int JSON_array_first_final = 17; static const int JSON_array_error = 0; @@ -1137,7 +1136,7 @@ static const int JSON_array_error = 0; static const int JSON_array_en_main = 1; -#line 381 "parser.rl" +#line 380 "parser.rl" static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -1151,14 +1150,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); -#line 1155 "parser.c" +#line 1154 "parser.c" { cs = JSON_array_start; } -#line 394 "parser.rl" +#line 393 "parser.rl" -#line 1162 "parser.c" +#line 1161 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1197,7 +1196,7 @@ case 2: goto st2; goto st0; tr2: -#line 358 "parser.rl" +#line 357 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v); @@ -1217,7 +1216,7 @@ case 2: if ( ++p == pe ) goto _test_eof3; case 3: -#line 1221 "parser.c" +#line 1220 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -1317,14 +1316,14 @@ case 12: goto st3; goto st12; tr4: -#line 373 "parser.rl" +#line 372 "parser.rl" { p--; {p++; cs = 17; goto _out;} } goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: -#line 1328 "parser.c" +#line 1327 "parser.c" goto st0; st13: if ( ++p == pe ) @@ -1380,7 +1379,7 @@ case 16: _out: {} } -#line 395 "parser.rl" +#line 394 "parser.rl" if(cs >= JSON_array_first_final) { return p + 1; @@ -1461,7 +1460,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1465 "parser.c" +#line 1464 "parser.c" static const int JSON_string_start = 1; static const int JSON_string_first_final = 8; static const int JSON_string_error = 0; @@ -1469,7 +1468,7 @@ static const int JSON_string_error = 0; static const int JSON_string_en_main = 1; -#line 494 "parser.rl" +#line 493 "parser.rl" static int @@ -1491,15 +1490,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = rb_str_buf_new(0); -#line 1495 "parser.c" +#line 1494 "parser.c" { cs = JSON_string_start; } -#line 515 "parser.rl" +#line 514 "parser.rl" json->memo = p; -#line 1503 "parser.c" +#line 1502 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1524,7 +1523,7 @@ case 2: goto st0; goto st2; tr2: -#line 480 "parser.rl" +#line 479 "parser.rl" { *result = json_string_unescape(*result, json->memo + 1, p); if (NIL_P(*result)) { @@ -1535,14 +1534,14 @@ case 2: {p = (( p + 1))-1;} } } -#line 491 "parser.rl" +#line 490 "parser.rl" { p--; {p++; cs = 8; goto _out;} } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: -#line 1546 "parser.c" +#line 1545 "parser.c" goto st0; st3: if ( ++p == pe ) @@ -1618,7 +1617,7 @@ case 7: _out: {} } -#line 517 "parser.rl" +#line 516 "parser.rl" if (json->create_additions && RTEST(match_string = json->match_string)) { VALUE klass; @@ -1656,9 +1655,12 @@ case 7: static VALUE convert_encoding(VALUE source) { #ifdef HAVE_RUBY_ENCODING_H - { - source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); - } + VALUE encoding = rb_funcall(source, i_encoding, 0); + if (encoding == CEncoding_ASCII_8BIT) { + FORCE_UTF8(source); + } else { + source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); + } #endif return source; } @@ -1784,7 +1786,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1788 "parser.c" +#line 1790 "parser.c" static const int JSON_start = 1; static const int JSON_first_final = 10; static const int JSON_error = 0; @@ -1792,7 +1794,7 @@ static const int JSON_error = 0; static const int JSON_en_main = 1; -#line 696 "parser.rl" +#line 698 "parser.rl" /* @@ -1809,16 +1811,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -#line 1813 "parser.c" +#line 1815 "parser.c" { cs = JSON_start; } -#line 712 "parser.rl" +#line 714 "parser.rl" p = json->source; pe = p + json->len; -#line 1822 "parser.c" +#line 1824 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1852,7 +1854,7 @@ case 1: cs = 0; goto _out; tr2: -#line 688 "parser.rl" +#line 690 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1862,7 +1864,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1866 "parser.c" +#line 1868 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1951,7 +1953,7 @@ case 9: _out: {} } -#line 715 "parser.rl" +#line 717 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -2051,6 +2053,8 @@ void Init_parser(void) i_leftshift = rb_intern("<<"); #ifdef HAVE_RUBY_ENCODING_H CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8")); + CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit")); + i_encoding = rb_intern("encoding"); i_encode = rb_intern("encode"); #else i_iconv = rb_intern("iconv"); diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index 6f7330790..f3933cb5d 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -66,9 +66,8 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) } #ifdef HAVE_RUBY_ENCODING_H -static VALUE CEncoding_UTF_8; - -static ID i_encode; +static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8; +static ID i_encoding, i_encode; #else static ID i_iconv; #endif @@ -551,9 +550,12 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu static VALUE convert_encoding(VALUE source) { #ifdef HAVE_RUBY_ENCODING_H - { - source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); - } + VALUE encoding = rb_funcall(source, i_encoding, 0); + if (encoding == CEncoding_ASCII_8BIT) { + FORCE_UTF8(source); + } else { + source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); + } #endif return source; } @@ -811,6 +813,8 @@ void Init_parser(void) i_leftshift = rb_intern("<<"); #ifdef HAVE_RUBY_ENCODING_H CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8")); + CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit")); + i_encoding = rb_intern("encoding"); i_encode = rb_intern("encode"); #else i_iconv = rb_intern("iconv"); From cf466b8d4e4afe9af313e5c8bea4e97ef3170637 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 3 Jun 2016 13:54:40 +0200 Subject: [PATCH 130/312] Treat ASCII_8BIT as UTF-8 by default --- java/src/json/ext/GeneratorState.java | 18 ---- java/src/json/ext/Parser.java | 150 +++++++++++++------------- java/src/json/ext/Parser.rl | 8 +- json.gemspec | Bin 4462 -> 4462 bytes json_pure.gemspec | 2 +- lib/json/pure/parser.rb | 6 +- tests/json_encoding_test.rb | 8 +- 7 files changed, 95 insertions(+), 97 deletions(-) diff --git a/java/src/json/ext/GeneratorState.java b/java/src/json/ext/GeneratorState.java index f43087bf9..44a931132 100644 --- a/java/src/json/ext/GeneratorState.java +++ b/java/src/json/ext/GeneratorState.java @@ -364,17 +364,6 @@ public RubyBoolean ascii_only_p(ThreadContext context) { return context.getRuntime().newBoolean(asciiOnly); } - @JRubyMethod(name="quirks_mode") - public RubyBoolean quirks_mode_get(ThreadContext context) { - return context.getRuntime().newBoolean(quirksMode); - } - - @JRubyMethod(name="quirks_mode=") - public IRubyObject quirks_mode_set(IRubyObject quirks_mode) { - quirksMode = quirks_mode.isTrue(); - return quirks_mode.getRuntime().newBoolean(quirksMode); - } - @JRubyMethod(name="buffer_initial_length") public RubyInteger buffer_initial_length_get(ThreadContext context) { return context.getRuntime().newFixnum(bufferInitialLength); @@ -387,11 +376,6 @@ public IRubyObject buffer_initial_length_set(IRubyObject buffer_initial_length) return buffer_initial_length; } - @JRubyMethod(name="quirks_mode?") - public RubyBoolean quirks_mode_p(ThreadContext context) { - return context.getRuntime().newBoolean(quirksMode); - } - public int getDepth() { return depth; } @@ -446,7 +430,6 @@ public IRubyObject configure(ThreadContext context, IRubyObject vOpts) { maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING); allowNaN = opts.getBool("allow_nan", DEFAULT_ALLOW_NAN); asciiOnly = opts.getBool("ascii_only", DEFAULT_ASCII_ONLY); - quirksMode = opts.getBool("quirks_mode", DEFAULT_QUIRKS_MODE); bufferInitialLength = opts.getInt("buffer_initial_length", DEFAULT_BUFFER_INITIAL_LENGTH); depth = opts.getInt("depth", 0); @@ -473,7 +456,6 @@ public RubyHash to_h(ThreadContext context) { result.op_aset(context, runtime.newSymbol("array_nl"), array_nl_get(context)); result.op_aset(context, runtime.newSymbol("allow_nan"), allow_nan_p(context)); result.op_aset(context, runtime.newSymbol("ascii_only"), ascii_only_p(context)); - result.op_aset(context, runtime.newSymbol("quirks_mode"), quirks_mode_p(context)); result.op_aset(context, runtime.newSymbol("max_nesting"), max_nesting_get(context)); result.op_aset(context, runtime.newSymbol("depth"), depth_get(context)); result.op_aset(context, runtime.newSymbol("buffer_initial_length"), buffer_initial_length_get(context)); diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index 57053e9f8..8c338402b 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -179,7 +179,13 @@ public IRubyObject initialize(ThreadContext context, IRubyObject[] args) { * Returns the source string if no conversion is needed. */ private RubyString convertEncoding(ThreadContext context, RubyString source) { - return (RubyString)source.encode(context, info.utf8.get()); + RubyEncoding encoding = (RubyEncoding)source.encoding(context); + if (encoding == info.ascii8bit.get()) { + source.force_encoding(context, info.utf8.get()); + } else { + source = (RubyString) source.encode(context, info.utf8.get()); + } + return source; } /** @@ -298,11 +304,11 @@ private Ruby getRuntime() { } -// line 324 "Parser.rl" +// line 330 "Parser.rl" -// line 306 "Parser.java" +// line 312 "Parser.java" private static byte[] init__JSON_value_actions_0() { return new byte [] { @@ -416,7 +422,7 @@ private static byte[] init__JSON_value_from_state_actions_0() static final int JSON_value_en_main = 1; -// line 430 "Parser.rl" +// line 436 "Parser.rl" void parseValue(ParserResult res, int p, int pe) { @@ -424,14 +430,14 @@ void parseValue(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 428 "Parser.java" +// line 434 "Parser.java" { cs = JSON_value_start; } -// line 437 "Parser.rl" +// line 443 "Parser.rl" -// line 435 "Parser.java" +// line 441 "Parser.java" { int _klen; int _trans = 0; @@ -457,13 +463,13 @@ void parseValue(ParserResult res, int p, int pe) { while ( _nacts-- > 0 ) { switch ( _JSON_value_actions[_acts++] ) { case 9: -// line 415 "Parser.rl" +// line 421 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 467 "Parser.java" +// line 473 "Parser.java" } } @@ -526,25 +532,25 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) switch ( _JSON_value_actions[_acts++] ) { case 0: -// line 332 "Parser.rl" +// line 338 "Parser.rl" { result = getRuntime().getNil(); } break; case 1: -// line 335 "Parser.rl" +// line 341 "Parser.rl" { result = getRuntime().getFalse(); } break; case 2: -// line 338 "Parser.rl" +// line 344 "Parser.rl" { result = getRuntime().getTrue(); } break; case 3: -// line 341 "Parser.rl" +// line 347 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_NAN); @@ -554,7 +560,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 4: -// line 348 "Parser.rl" +// line 354 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_INFINITY); @@ -564,7 +570,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 5: -// line 355 "Parser.rl" +// line 361 "Parser.rl" { if (pe > p + 8 && absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) { @@ -593,7 +599,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 6: -// line 381 "Parser.rl" +// line 387 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -606,7 +612,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 7: -// line 391 "Parser.rl" +// line 397 "Parser.rl" { currentNesting++; parseArray(res, p, pe); @@ -621,7 +627,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 8: -// line 403 "Parser.rl" +// line 409 "Parser.rl" { currentNesting++; parseObject(res, p, pe); @@ -635,7 +641,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } } break; -// line 639 "Parser.java" +// line 645 "Parser.java" } } } @@ -655,7 +661,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) break; } } -// line 438 "Parser.rl" +// line 444 "Parser.rl" if (cs >= JSON_value_first_final && result != null) { res.update(result, p); @@ -665,7 +671,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } -// line 669 "Parser.java" +// line 675 "Parser.java" private static byte[] init__JSON_integer_actions_0() { return new byte [] { @@ -764,7 +770,7 @@ private static byte[] init__JSON_integer_trans_actions_0() static final int JSON_integer_en_main = 1; -// line 457 "Parser.rl" +// line 463 "Parser.rl" void parseInteger(ParserResult res, int p, int pe) { @@ -782,15 +788,15 @@ int parseIntegerInternal(int p, int pe) { int cs = EVIL; -// line 786 "Parser.java" +// line 792 "Parser.java" { cs = JSON_integer_start; } -// line 474 "Parser.rl" +// line 480 "Parser.rl" int memo = p; -// line 794 "Parser.java" +// line 800 "Parser.java" { int _klen; int _trans = 0; @@ -871,13 +877,13 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) switch ( _JSON_integer_actions[_acts++] ) { case 0: -// line 451 "Parser.rl" +// line 457 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 881 "Parser.java" +// line 887 "Parser.java" } } } @@ -897,7 +903,7 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) break; } } -// line 476 "Parser.rl" +// line 482 "Parser.rl" if (cs < JSON_integer_first_final) { return -1; @@ -919,7 +925,7 @@ RubyInteger bytesToInum(Ruby runtime, ByteList num) { } -// line 923 "Parser.java" +// line 929 "Parser.java" private static byte[] init__JSON_float_actions_0() { return new byte [] { @@ -1021,7 +1027,7 @@ private static byte[] init__JSON_float_trans_actions_0() static final int JSON_float_en_main = 1; -// line 511 "Parser.rl" +// line 517 "Parser.rl" void parseFloat(ParserResult res, int p, int pe) { @@ -1039,15 +1045,15 @@ int parseFloatInternal(int p, int pe) { int cs = EVIL; -// line 1043 "Parser.java" +// line 1049 "Parser.java" { cs = JSON_float_start; } -// line 528 "Parser.rl" +// line 534 "Parser.rl" int memo = p; -// line 1051 "Parser.java" +// line 1057 "Parser.java" { int _klen; int _trans = 0; @@ -1128,13 +1134,13 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) switch ( _JSON_float_actions[_acts++] ) { case 0: -// line 502 "Parser.rl" +// line 508 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1138 "Parser.java" +// line 1144 "Parser.java" } } } @@ -1154,7 +1160,7 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) break; } } -// line 530 "Parser.rl" +// line 536 "Parser.rl" if (cs < JSON_float_first_final) { return -1; @@ -1170,7 +1176,7 @@ RubyFloat createFloat(int p, int new_p) { } -// line 1174 "Parser.java" +// line 1180 "Parser.java" private static byte[] init__JSON_string_actions_0() { return new byte [] { @@ -1272,7 +1278,7 @@ private static byte[] init__JSON_string_trans_actions_0() static final int JSON_string_en_main = 1; -// line 575 "Parser.rl" +// line 581 "Parser.rl" void parseString(ParserResult res, int p, int pe) { @@ -1280,15 +1286,15 @@ void parseString(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 1284 "Parser.java" +// line 1290 "Parser.java" { cs = JSON_string_start; } -// line 582 "Parser.rl" +// line 588 "Parser.rl" int memo = p; -// line 1292 "Parser.java" +// line 1298 "Parser.java" { int _klen; int _trans = 0; @@ -1369,7 +1375,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) switch ( _JSON_string_actions[_acts++] ) { case 0: -// line 550 "Parser.rl" +// line 556 "Parser.rl" { int offset = byteList.begin(); ByteList decoded = decoder.decode(byteList, memo + 1 - offset, @@ -1384,13 +1390,13 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) } break; case 1: -// line 563 "Parser.rl" +// line 569 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1394 "Parser.java" +// line 1400 "Parser.java" } } } @@ -1410,7 +1416,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) break; } } -// line 584 "Parser.rl" +// line 590 "Parser.rl" if (parser.createAdditions) { RubyHash matchString = parser.matchString; @@ -1448,7 +1454,7 @@ public void visit(IRubyObject pattern, IRubyObject klass) { } -// line 1452 "Parser.java" +// line 1458 "Parser.java" private static byte[] init__JSON_array_actions_0() { return new byte [] { @@ -1561,7 +1567,7 @@ private static byte[] init__JSON_array_trans_actions_0() static final int JSON_array_en_main = 1; -// line 657 "Parser.rl" +// line 663 "Parser.rl" void parseArray(ParserResult res, int p, int pe) { @@ -1581,14 +1587,14 @@ void parseArray(ParserResult res, int p, int pe) { } -// line 1585 "Parser.java" +// line 1591 "Parser.java" { cs = JSON_array_start; } -// line 676 "Parser.rl" +// line 682 "Parser.rl" -// line 1592 "Parser.java" +// line 1598 "Parser.java" { int _klen; int _trans = 0; @@ -1669,7 +1675,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) switch ( _JSON_array_actions[_acts++] ) { case 0: -// line 626 "Parser.rl" +// line 632 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1686,13 +1692,13 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } break; case 1: -// line 641 "Parser.rl" +// line 647 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1696 "Parser.java" +// line 1702 "Parser.java" } } } @@ -1712,7 +1718,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) break; } } -// line 677 "Parser.rl" +// line 683 "Parser.rl" if (cs >= JSON_array_first_final) { res.update(result, p + 1); @@ -1722,7 +1728,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } -// line 1726 "Parser.java" +// line 1732 "Parser.java" private static byte[] init__JSON_object_actions_0() { return new byte [] { @@ -1845,7 +1851,7 @@ private static byte[] init__JSON_object_trans_actions_0() static final int JSON_object_en_main = 1; -// line 736 "Parser.rl" +// line 742 "Parser.rl" void parseObject(ParserResult res, int p, int pe) { @@ -1870,14 +1876,14 @@ void parseObject(ParserResult res, int p, int pe) { } -// line 1874 "Parser.java" +// line 1880 "Parser.java" { cs = JSON_object_start; } -// line 760 "Parser.rl" +// line 766 "Parser.rl" -// line 1881 "Parser.java" +// line 1887 "Parser.java" { int _klen; int _trans = 0; @@ -1958,7 +1964,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) switch ( _JSON_object_actions[_acts++] ) { case 0: -// line 691 "Parser.rl" +// line 697 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1975,7 +1981,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 1: -// line 706 "Parser.rl" +// line 712 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -1995,13 +2001,13 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 2: -// line 724 "Parser.rl" +// line 730 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 2005 "Parser.java" +// line 2011 "Parser.java" } } } @@ -2021,7 +2027,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) break; } } -// line 761 "Parser.rl" +// line 767 "Parser.rl" if (cs < JSON_object_first_final) { res.update(null, p + 1); @@ -2054,7 +2060,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } -// line 2058 "Parser.java" +// line 2064 "Parser.java" private static byte[] init__JSON_actions_0() { return new byte [] { @@ -2157,7 +2163,7 @@ private static byte[] init__JSON_trans_actions_0() static final int JSON_en_main = 1; -// line 812 "Parser.rl" +// line 818 "Parser.rl" public IRubyObject parseImplemetation() { @@ -2167,16 +2173,16 @@ public IRubyObject parseImplemetation() { ParserResult res = new ParserResult(); -// line 2171 "Parser.java" +// line 2177 "Parser.java" { cs = JSON_start; } -// line 821 "Parser.rl" +// line 827 "Parser.rl" p = byteList.begin(); pe = p + byteList.length(); -// line 2180 "Parser.java" +// line 2186 "Parser.java" { int _klen; int _trans = 0; @@ -2257,7 +2263,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) switch ( _JSON_actions[_acts++] ) { case 0: -// line 798 "Parser.rl" +// line 804 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2269,7 +2275,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) } } break; -// line 2273 "Parser.java" +// line 2279 "Parser.java" } } } @@ -2289,7 +2295,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) break; } } -// line 824 "Parser.rl" +// line 830 "Parser.rl" if (cs >= JSON_first_final && p == pe) { return result; diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 17ea303fb..28247eaeb 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -177,7 +177,13 @@ public class Parser extends RubyObject { * Returns the source string if no conversion is needed. */ private RubyString convertEncoding(ThreadContext context, RubyString source) { - return (RubyString)source.encode(context, info.utf8.get()); + RubyEncoding encoding = (RubyEncoding)source.encoding(context); + if (encoding == info.ascii8bit.get()) { + source.force_encoding(context, info.utf8.get()); + } else { + source = (RubyString) source.encode(context, info.utf8.get()); + } + return source; } /** diff --git a/json.gemspec b/json.gemspec index aa2ea551e2a4c5539b5af907648964f777b05e37..0acfa15c9b01461a7d3412a04e915d1316e4f268 100644 GIT binary patch delta 14 WcmaE-^iFBRG)6|_&C?mL^8)}dYz55# delta 14 WcmaE-^iFBRG)6|F&C?mL^8)}dW(CXu diff --git a/json_pure.gemspec b/json_pure.gemspec index 5fef9d9ff..8bb45c298 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2016-06-02" + s.date = "2016-06-03" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.md"] diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index b2e841b67..f02f4086b 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -130,8 +130,10 @@ def convert_encoding(source) raise TypeError, "#{source.inspect} is not like a string" end - source = source.encode(::Encoding::UTF_8) - source.force_encoding(::Encoding::ASCII_8BIT) + if source.encoding != ::Encoding::ASCII_8BIT + source = source.encode(::Encoding::UTF_8) + source.force_encoding(::Encoding::ASCII_8BIT) + end source end diff --git a/tests/json_encoding_test.rb b/tests/json_encoding_test.rb index f8b88d2fa..d983e1264 100644 --- a/tests/json_encoding_test.rb +++ b/tests/json_encoding_test.rb @@ -5,9 +5,10 @@ class JSONEncodingTest < Test::Unit::TestCase include JSON def setup - @utf_8 = '"© ≠ €!"' - @parsed = "© ≠ €!" - @generated = '"\u00a9 \u2260 \u20ac!"' + @utf_8 = '"© ≠ €!"' + @ascii_8bit = @utf_8.dup.force_encoding('ascii-8bit') + @parsed = "© ≠ €!" + @generated = '"\u00a9 \u2260 \u20ac!"' if String.method_defined?(:encode) @utf_16_data = @parsed.encode('utf-16be', 'utf-8') @utf_16be = @utf_8.encode('utf-16be', 'utf-8') @@ -25,6 +26,7 @@ def setup end def test_parse + assert_equal @parsed, JSON.parse(@ascii_8bit) assert_equal @parsed, JSON.parse(@utf_8) assert_equal @parsed, JSON.parse(@utf_16be) assert_equal @parsed, JSON.parse(@utf_16le) From fe01c3602a011525de627aaf880ea380bb7e6e7d Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 3 Jun 2016 19:49:35 +0200 Subject: [PATCH 131/312] Move simplecov to test_helper.rb --- lib/json/ext.rb | 6 ------ lib/json/pure.rb | 10 ++-------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/lib/json/ext.rb b/lib/json/ext.rb index c5f813181..7264a857f 100644 --- a/lib/json/ext.rb +++ b/lib/json/ext.rb @@ -1,9 +1,3 @@ -if ENV['SIMPLECOV_COVERAGE'].to_i == 1 - require 'simplecov' - SimpleCov.start do - add_filter "/tests/" - end -end require 'json/common' module JSON diff --git a/lib/json/pure.rb b/lib/json/pure.rb index b68668b2c..53178b360 100644 --- a/lib/json/pure.rb +++ b/lib/json/pure.rb @@ -1,17 +1,11 @@ -if ENV['SIMPLECOV_COVERAGE'].to_i == 1 - require 'simplecov' - SimpleCov.start do - add_filter "/tests/" - end -end require 'json/common' -require 'json/pure/parser' -require 'json/pure/generator' module JSON # This module holds all the modules/classes that implement JSON's # functionality in pure ruby. module Pure + require 'json/pure/parser' + require 'json/pure/generator' $DEBUG and warn "Using Pure library for JSON." JSON.parser = Parser JSON.generator = Generator From 817098cc16d1b3a76c57de743ffc9b7f5171be21 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 10:37:22 +0100 Subject: [PATCH 132/312] Move dependencies into gemspec files --- Rakefile | 4 ++-- json-java.gemspec | 6 +++--- json.gemspec | Bin 4462 -> 4456 bytes json_pure.gemspec | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Rakefile b/Rakefile index 4aa311e57..89d278481 100644 --- a/Rakefile +++ b/Rakefile @@ -84,7 +84,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.require_path = 'lib' s.add_development_dependency 'rake' - s.add_development_dependency 'test-unit', '~> 2.0' + s.add_development_dependency 'test-unit' s.extra_rdoc_files << 'README.md' s.rdoc_options << @@ -121,7 +121,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.require_path = 'lib' s.add_development_dependency 'rake' - s.add_development_dependency 'test-unit', '~> 2.0' + s.add_development_dependency 'test-unit' s.extra_rdoc_files << 'README.md' s.rdoc_options << diff --git a/json-java.gemspec b/json-java.gemspec index 1524b1f9a..e691a3edd 100644 --- a/json-java.gemspec +++ b/json-java.gemspec @@ -20,14 +20,14 @@ spec = Gem::Specification.new do |s| if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, ["~> 2.0"]) + s.add_development_dependency(%q, [">= 0"]) else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 2.0"]) + s.add_dependency(%q, [">= 0"]) end else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 2.0"]) + s.add_dependency(%q, [">= 0"]) end end diff --git a/json.gemspec b/json.gemspec index 0acfa15c9b01461a7d3412a04e915d1316e4f268..39ecd4f7089917d175920be05721377b480a6f51 100644 GIT binary patch delta 49 ycmaE-^g?OFG)6}A&C?mb@-f@lDomazkO-!~3nU8x`36d{np_GBsd*_}APfMcMh^!7 delta 55 zcmaE%^iFBRG)6|_&C?mb^0C(0DH!QZ?iWaevOWtWi-5%plwvix6ckePQn)}E01cE7 A<^TWy diff --git a/json_pure.gemspec b/json_pure.gemspec index 8bb45c298..cff006e2a 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2016-06-03" + s.date = "2016-06-07" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.md"] @@ -25,13 +25,13 @@ Gem::Specification.new do |s| if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, ["~> 2.0"]) + s.add_development_dependency(%q, [">= 0"]) else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 2.0"]) + s.add_dependency(%q, [">= 0"]) end else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 2.0"]) + s.add_dependency(%q, [">= 0"]) end end From 073120714efbda55d42190ee9e3989afc568ec48 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 25 Feb 2016 11:35:16 +0100 Subject: [PATCH 133/312] Use ~> 2.0 test-unit that runs on 1.8 rubies as well --- Rakefile | 4 ++-- json-java.gemspec | 6 +++--- json.gemspec | Bin 4456 -> 4462 bytes json_pure.gemspec | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Rakefile b/Rakefile index 89d278481..4aa311e57 100644 --- a/Rakefile +++ b/Rakefile @@ -84,7 +84,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.require_path = 'lib' s.add_development_dependency 'rake' - s.add_development_dependency 'test-unit' + s.add_development_dependency 'test-unit', '~> 2.0' s.extra_rdoc_files << 'README.md' s.rdoc_options << @@ -121,7 +121,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.require_path = 'lib' s.add_development_dependency 'rake' - s.add_development_dependency 'test-unit' + s.add_development_dependency 'test-unit', '~> 2.0' s.extra_rdoc_files << 'README.md' s.rdoc_options << diff --git a/json-java.gemspec b/json-java.gemspec index e691a3edd..1524b1f9a 100644 --- a/json-java.gemspec +++ b/json-java.gemspec @@ -20,14 +20,14 @@ spec = Gem::Specification.new do |s| if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 2.0"]) else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end end diff --git a/json.gemspec b/json.gemspec index 39ecd4f7089917d175920be05721377b480a6f51..ca023f7860900caf7e37acefa1c514451f2bc4f0 100644 GIT binary patch delta 48 scmaE%^iF9*j{s|(or00x= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 2.0"]) else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end else s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end end From 9a530b2df58365bb3049f37de05fa5ae9f791644 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 2 Jun 2016 11:53:19 +0200 Subject: [PATCH 134/312] Allow usage of simplecov with START_SIMPLECOV=1 --- Gemfile | 2 ++ tests/test_helper.rb | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/Gemfile b/Gemfile index 71fac4735..51ff10afc 100644 --- a/Gemfile +++ b/Gemfile @@ -5,3 +5,5 @@ source 'https://rubygems.org' gemspec :name => 'json' gemspec :name => 'json_pure' gemspec :name => 'json-java' + +gem 'simplecov' diff --git a/tests/test_helper.rb b/tests/test_helper.rb index 752f5f536..9d3665d47 100644 --- a/tests/test_helper.rb +++ b/tests/test_helper.rb @@ -17,3 +17,7 @@ require 'byebug' rescue LoadError end +if ENV['START_SIMPLECOV'].to_i == 1 + require 'simplecov' + SimpleCov.start +end From 15464b8081c64cc3da3df0593b9f0fb38e1423a3 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 7 Jun 2016 12:46:21 +0200 Subject: [PATCH 135/312] Update rubies to test on --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e1ebedae1..a81733be7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,13 +4,11 @@ language: ruby # Specify which ruby versions you wish to run your tests on, each version will be used rvm: - - 1.8.7 - - 1.9.2 - 1.9.3 - 2.0.0 - 2.1 - 2.2 - - 2.3.0 + - 2.3.1 - ree - ruby-head matrix: From 98aa312dc9aa9b7dd66cf282d6eaf22eb94360fd Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 7 Jun 2016 12:52:23 +0200 Subject: [PATCH 136/312] Update rubies to test on --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a81733be7..a8f907136 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,6 @@ rvm: - 2.1 - 2.2 - 2.3.1 - - ree - ruby-head matrix: include: From 391edb01f8122b4e229a2d7c78529a4e080abc1a Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 19 Oct 2015 10:53:16 -0700 Subject: [PATCH 137/312] resize strings after parsing The parser uses `rb_str_buf_new` to allocate new strings. `rb_str_buf_new` [has a minimum size of 128 and is not an embedded string](https://github.com/ruby/ruby/blob/9949407fd90c1c5bfe332141c75db995a9b867aa/string.c#L1119-L1135). This causes applications that parse JS to allocate extra memory when parsing short strings. For a real-world example, we can use the mime-types gem. The mime-types gem stores all mime types inside a JSON file and parses them when you require the gem. Here is a sample program: ```ruby require 'objspace' require 'mime-types' GC.start GC.start p ObjectSpace.memsize_of_all String ``` The example program loads the mime-types gem and outputs the total space used by all strings. Here are the results of the program before and after this patch: ** Before ** ``` [aaron@TC json (memuse)]$ ruby test.rb 5497494 [aaron@TC json (memuse)]$ ``` ** After ** ``` [aaron@TC json (memuse)]$ ruby -I lib:ext test.rb 3335862 [aaron@TC json (memuse)]$ ``` This change results in a ~40% reduction of memory use for strings in the mime-types gem. Thanks @matthewd for finding the problem, and @nobu for the patch! --- ext/json/ext/parser/parser.rl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index f3933cb5d..157b00122 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -527,6 +527,8 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu if (json->symbolize_names && json->parsing_name) { *result = rb_str_intern(*result); + } else { + rb_str_resize(*result, RSTRING_LEN(*result)); } if (cs >= JSON_string_first_final) { return p + 1; From 4aae95f41b6b972245d15e52c46dbd5f278ff2c2 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 3 Mar 2016 14:49:15 -0800 Subject: [PATCH 138/312] regenerate parser --- ext/json/ext/parser/parser.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 5b2e61c52..ea95e71d0 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1632,6 +1632,8 @@ case 7: if (json->symbolize_names && json->parsing_name) { *result = rb_str_intern(*result); + } else { + rb_str_resize(*result, RSTRING_LEN(*result)); } if (cs >= JSON_string_first_final) { return p + 1; From 8e16a607f9abbd24dba508ba5c92877410cecfd7 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 21 Jun 2016 09:34:16 +0200 Subject: [PATCH 139/312] Adapt to ruby integer unification --- ext/json/ext/generator/generator.c | 39 +++++++++++++++++++++++++++--- ext/json/ext/generator/generator.h | 7 ++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 2a3db2965..8cc0c270b 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -7,7 +7,13 @@ static ID i_encoding, i_encode; #endif static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject, - mHash, mArray, mFixnum, mBignum, mFloat, mString, mString_Extend, + mHash, mArray, +#ifdef RUBY_INTEGER_UNIFICATION + mInteger, +#else + mFixnum, mBignum, +#endif + mFloat, mString, mString_Extend, mTrueClass, mFalseClass, mNilClass, eGeneratorError, eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE, i_SAFE_STATE_PROTOTYPE; @@ -342,6 +348,18 @@ static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) { GENERATE_JSON(array); } +#ifdef RUBY_INTEGER_UNIFICATION +/* + * call-seq: to_json(*) + * + * Returns a JSON string representation for this Integer number. + */ +static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self) +{ + GENERATE_JSON(integer); +} + +#else /* * call-seq: to_json(*) * @@ -361,6 +379,7 @@ static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self) { GENERATE_JSON(bignum); } +#endif /* * call-seq: to_json(*) @@ -822,6 +841,15 @@ static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_S fbuffer_append_str(buffer, tmp); } +#ifdef RUBY_INTEGER_UNIFICATION +static void generate_json_integer(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) +{ + if (FIXNUM_P(obj)) + generate_json_fixnum(buffer, Vstate, state, obj); + else + generate_json_bignum(buffer, Vstate, state, obj); +} +#endif static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) { double value = RFLOAT_VALUE(obj); @@ -855,9 +883,9 @@ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *s generate_json_false(buffer, Vstate, state, obj); } else if (obj == Qtrue) { generate_json_true(buffer, Vstate, state, obj); - } else if (klass == rb_cFixnum) { + } else if (FIXNUM_P(obj)) { generate_json_fixnum(buffer, Vstate, state, obj); - } else if (klass == rb_cBignum) { + } else if (RB_TYPE_P(obj, T_BIGNUM)) { generate_json_bignum(buffer, Vstate, state, obj); } else if (klass == rb_cFloat) { generate_json_float(buffer, Vstate, state, obj); @@ -1353,10 +1381,15 @@ void Init_generator(void) rb_define_method(mHash, "to_json", mHash_to_json, -1); mArray = rb_define_module_under(mGeneratorMethods, "Array"); rb_define_method(mArray, "to_json", mArray_to_json, -1); +#ifdef RUBY_INTEGER_UNIFICATION + mInteger = rb_define_module_under(mGeneratorMethods, "Integer"); + rb_define_method(mInteger, "to_json", mInteger_to_json, -1); +#else mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum"); rb_define_method(mFixnum, "to_json", mFixnum_to_json, -1); mBignum = rb_define_module_under(mGeneratorMethods, "Bignum"); rb_define_method(mBignum, "to_json", mBignum_to_json, -1); +#endif mFloat = rb_define_module_under(mGeneratorMethods, "Float"); rb_define_method(mFloat, "to_json", mFloat_to_json, -1); mString = rb_define_module_under(mGeneratorMethods, "String"); diff --git a/ext/json/ext/generator/generator.h b/ext/json/ext/generator/generator.h index 7432f2682..900b4d58f 100644 --- a/ext/json/ext/generator/generator.h +++ b/ext/json/ext/generator/generator.h @@ -98,8 +98,12 @@ typedef struct JSON_Generator_StateStruct { static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self); static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self); +#ifdef RUBY_INTEGER_UNIFICATION +static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self); +#else static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self); static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self); +#endif static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self); static VALUE mString_included_s(VALUE self, VALUE modul); static VALUE mString_to_json(int argc, VALUE *argv, VALUE self); @@ -121,6 +125,9 @@ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_S static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); +#ifdef RUBY_INTEGER_UNIFICATION +static void generate_json_integer(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); +#endif static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); From 6b5364c5765d48d77f6c6af323af4f8763867b5e Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 21 Jun 2016 10:11:37 +0200 Subject: [PATCH 140/312] Easy diffing --- tools/diff.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100755 tools/diff.sh diff --git a/tools/diff.sh b/tools/diff.sh new file mode 100755 index 000000000..3fd582955 --- /dev/null +++ b/tools/diff.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +files=`find ext -name '*.[ch]' -o -name parser.rl` + +for f in $files +do + echo $f + b=`basename $f` + g=`find ../ruby/ext/json -name $b` + diff -u $f $g | less +done From e16dab51937894c674c07660cc0916a08af2e165 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 21 Jun 2016 10:12:06 +0200 Subject: [PATCH 141/312] Merge more changes from ruby core --- ext/json/ext/parser/extconf.rb | 3 + ext/json/ext/parser/parser.c | 205 ++++++++++++++++++--------------- ext/json/ext/parser/parser.rl | 59 ++++++---- json.gemspec | Bin 4462 -> 5410 bytes json_pure.gemspec | 42 +++---- 5 files changed, 171 insertions(+), 138 deletions(-) diff --git a/ext/json/ext/parser/extconf.rb b/ext/json/ext/parser/extconf.rb index ae4f861c7..f7360d46b 100644 --- a/ext/json/ext/parser/extconf.rb +++ b/ext/json/ext/parser/extconf.rb @@ -1,3 +1,6 @@ +# frozen_string_literal: false require 'mkmf' +have_func("rb_enc_raise", "ruby.h") + create_makefile 'json/ext/parser' diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 5b2e61c52..8d8380818 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -3,6 +3,28 @@ #include "../fbuffer/fbuffer.h" #include "parser.h" +#if defined HAVE_RUBY_ENCODING_H +# define EXC_ENCODING rb_utf8_encoding(), +# ifndef HAVE_RB_ENC_RAISE +static void +enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...) +{ + va_list args; + VALUE mesg; + + va_start(args, fmt); + mesg = rb_enc_vsprintf(enc, fmt, args); + va_end(args); + + rb_exc_raise(rb_exc_new3(exc, mesg)); +} +# define rb_enc_raise enc_raise +# endif +#else +# define EXC_ENCODING /* nothing */ +# define rb_enc_raise rb_raise +#endif + /* unicode */ static const char digit_values[256] = { @@ -67,13 +89,6 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) return len; } -#ifdef HAVE_RUBY_ENCODING_H -static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8; -static ID i_encoding, i_encode; -#else -static ID i_iconv; -#endif - static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static VALUE CNaN, CInfinity, CMinusInfinity; @@ -83,11 +98,11 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_match_string, i_aset, i_aref, i_leftshift; -#line 109 "parser.rl" +#line 124 "parser.rl" -#line 91 "parser.c" +#line 106 "parser.c" static const int JSON_object_start = 1; static const int JSON_object_first_final = 27; static const int JSON_object_error = 0; @@ -95,7 +110,7 @@ static const int JSON_object_error = 0; static const int JSON_object_en_main = 1; -#line 150 "parser.rl" +#line 165 "parser.rl" static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -111,14 +126,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class); -#line 115 "parser.c" +#line 130 "parser.c" { cs = JSON_object_start; } -#line 165 "parser.rl" +#line 180 "parser.rl" -#line 122 "parser.c" +#line 137 "parser.c" { if ( p == pe ) goto _test_eof; @@ -146,7 +161,7 @@ case 2: goto st2; goto st0; tr2: -#line 132 "parser.rl" +#line 147 "parser.rl" { char *np; json->parsing_name = 1; @@ -159,7 +174,7 @@ case 2: if ( ++p == pe ) goto _test_eof3; case 3: -#line 163 "parser.c" +#line 178 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -226,7 +241,7 @@ case 8: goto st8; goto st0; tr11: -#line 117 "parser.rl" +#line 132 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v); @@ -246,7 +261,7 @@ case 8: if ( ++p == pe ) goto _test_eof9; case 9: -#line 250 "parser.c" +#line 265 "parser.c" switch( (*p) ) { case 13: goto st9; case 32: goto st9; @@ -335,14 +350,14 @@ case 18: goto st9; goto st18; tr4: -#line 140 "parser.rl" +#line 155 "parser.rl" { p--; {p++; cs = 27; goto _out;} } goto st27; st27: if ( ++p == pe ) goto _test_eof27; case 27: -#line 346 "parser.c" +#line 361 "parser.c" goto st0; st19: if ( ++p == pe ) @@ -440,7 +455,7 @@ case 26: _out: {} } -#line 166 "parser.rl" +#line 181 "parser.rl" if (cs >= JSON_object_first_final) { if (json->create_additions) { @@ -465,7 +480,7 @@ case 26: -#line 469 "parser.c" +#line 484 "parser.c" static const int JSON_value_start = 1; static const int JSON_value_first_final = 29; static const int JSON_value_error = 0; @@ -473,7 +488,7 @@ static const int JSON_value_error = 0; static const int JSON_value_en_main = 1; -#line 270 "parser.rl" +#line 285 "parser.rl" static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -481,14 +496,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 485 "parser.c" +#line 500 "parser.c" { cs = JSON_value_start; } -#line 277 "parser.rl" +#line 292 "parser.rl" -#line 492 "parser.c" +#line 507 "parser.c" { if ( p == pe ) goto _test_eof; @@ -522,14 +537,14 @@ case 1: cs = 0; goto _out; tr2: -#line 218 "parser.rl" +#line 233 "parser.rl" { char *np = JSON_parse_string(json, p, pe, result); if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } goto st29; tr3: -#line 223 "parser.rl" +#line 238 "parser.rl" { char *np; if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) { @@ -538,7 +553,7 @@ cs = 0; {p = (( p + 10))-1;} p--; {p++; cs = 29; goto _out;} } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); } } np = JSON_parse_float(json, p, pe, result); @@ -549,7 +564,7 @@ cs = 0; } goto st29; tr7: -#line 241 "parser.rl" +#line 256 "parser.rl" { char *np; json->current_nesting++; @@ -559,7 +574,7 @@ cs = 0; } goto st29; tr11: -#line 249 "parser.rl" +#line 264 "parser.rl" { char *np; json->current_nesting++; @@ -569,39 +584,39 @@ cs = 0; } goto st29; tr25: -#line 211 "parser.rl" +#line 226 "parser.rl" { if (json->allow_nan) { *result = CInfinity; } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); } } goto st29; tr27: -#line 204 "parser.rl" +#line 219 "parser.rl" { if (json->allow_nan) { *result = CNaN; } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); } } goto st29; tr31: -#line 198 "parser.rl" +#line 213 "parser.rl" { *result = Qfalse; } goto st29; tr34: -#line 195 "parser.rl" +#line 210 "parser.rl" { *result = Qnil; } goto st29; tr37: -#line 201 "parser.rl" +#line 216 "parser.rl" { *result = Qtrue; } @@ -610,9 +625,9 @@ cs = 0; if ( ++p == pe ) goto _test_eof29; case 29: -#line 257 "parser.rl" +#line 272 "parser.rl" { p--; {p++; cs = 29; goto _out;} } -#line 616 "parser.c" +#line 631 "parser.c" switch( (*p) ) { case 13: goto st29; case 32: goto st29; @@ -853,7 +868,7 @@ case 28: _out: {} } -#line 278 "parser.rl" +#line 293 "parser.rl" if (cs >= JSON_value_first_final) { return p; @@ -863,7 +878,7 @@ case 28: } -#line 867 "parser.c" +#line 882 "parser.c" static const int JSON_integer_start = 1; static const int JSON_integer_first_final = 3; static const int JSON_integer_error = 0; @@ -871,7 +886,7 @@ static const int JSON_integer_error = 0; static const int JSON_integer_en_main = 1; -#line 294 "parser.rl" +#line 309 "parser.rl" static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -879,15 +894,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res int cs = EVIL; -#line 883 "parser.c" +#line 898 "parser.c" { cs = JSON_integer_start; } -#line 301 "parser.rl" +#line 316 "parser.rl" json->memo = p; -#line 891 "parser.c" +#line 906 "parser.c" { if ( p == pe ) goto _test_eof; @@ -921,14 +936,14 @@ case 3: goto st0; goto tr4; tr4: -#line 291 "parser.rl" +#line 306 "parser.rl" { p--; {p++; cs = 4; goto _out;} } goto st4; st4: if ( ++p == pe ) goto _test_eof4; case 4: -#line 932 "parser.c" +#line 947 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -947,7 +962,7 @@ case 5: _out: {} } -#line 303 "parser.rl" +#line 318 "parser.rl" if (cs >= JSON_integer_first_final) { long len = p - json->memo; @@ -962,7 +977,7 @@ case 5: } -#line 966 "parser.c" +#line 981 "parser.c" static const int JSON_float_start = 1; static const int JSON_float_first_final = 8; static const int JSON_float_error = 0; @@ -970,7 +985,7 @@ static const int JSON_float_error = 0; static const int JSON_float_en_main = 1; -#line 328 "parser.rl" +#line 343 "parser.rl" static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -978,15 +993,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 982 "parser.c" +#line 997 "parser.c" { cs = JSON_float_start; } -#line 335 "parser.rl" +#line 350 "parser.rl" json->memo = p; -#line 990 "parser.c" +#line 1005 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1044,14 +1059,14 @@ case 8: goto st0; goto tr9; tr9: -#line 322 "parser.rl" +#line 337 "parser.rl" { p--; {p++; cs = 9; goto _out;} } goto st9; st9: if ( ++p == pe ) goto _test_eof9; case 9: -#line 1055 "parser.c" +#line 1070 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -1112,7 +1127,7 @@ case 7: _out: {} } -#line 337 "parser.rl" +#line 352 "parser.rl" if (cs >= JSON_float_first_final) { long len = p - json->memo; @@ -1128,7 +1143,7 @@ case 7: -#line 1132 "parser.c" +#line 1147 "parser.c" static const int JSON_array_start = 1; static const int JSON_array_first_final = 17; static const int JSON_array_error = 0; @@ -1136,7 +1151,7 @@ static const int JSON_array_error = 0; static const int JSON_array_en_main = 1; -#line 380 "parser.rl" +#line 395 "parser.rl" static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -1150,14 +1165,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); -#line 1154 "parser.c" +#line 1169 "parser.c" { cs = JSON_array_start; } -#line 393 "parser.rl" +#line 408 "parser.rl" -#line 1161 "parser.c" +#line 1176 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1196,7 +1211,7 @@ case 2: goto st2; goto st0; tr2: -#line 357 "parser.rl" +#line 372 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v); @@ -1216,7 +1231,7 @@ case 2: if ( ++p == pe ) goto _test_eof3; case 3: -#line 1220 "parser.c" +#line 1235 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -1316,14 +1331,14 @@ case 12: goto st3; goto st12; tr4: -#line 372 "parser.rl" +#line 387 "parser.rl" { p--; {p++; cs = 17; goto _out;} } goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: -#line 1327 "parser.c" +#line 1342 "parser.c" goto st0; st13: if ( ++p == pe ) @@ -1379,12 +1394,12 @@ case 16: _out: {} } -#line 394 "parser.rl" +#line 409 "parser.rl" if(cs >= JSON_array_first_final) { return p + 1; } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); return NULL; } } @@ -1460,7 +1475,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1464 "parser.c" +#line 1479 "parser.c" static const int JSON_string_start = 1; static const int JSON_string_first_final = 8; static const int JSON_string_error = 0; @@ -1468,7 +1483,7 @@ static const int JSON_string_error = 0; static const int JSON_string_en_main = 1; -#line 493 "parser.rl" +#line 508 "parser.rl" static int @@ -1490,15 +1505,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = rb_str_buf_new(0); -#line 1494 "parser.c" +#line 1509 "parser.c" { cs = JSON_string_start; } -#line 514 "parser.rl" +#line 529 "parser.rl" json->memo = p; -#line 1502 "parser.c" +#line 1517 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1523,7 +1538,7 @@ case 2: goto st0; goto st2; tr2: -#line 479 "parser.rl" +#line 494 "parser.rl" { *result = json_string_unescape(*result, json->memo + 1, p); if (NIL_P(*result)) { @@ -1534,14 +1549,14 @@ case 2: {p = (( p + 1))-1;} } } -#line 490 "parser.rl" +#line 505 "parser.rl" { p--; {p++; cs = 8; goto _out;} } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: -#line 1545 "parser.c" +#line 1560 "parser.c" goto st0; st3: if ( ++p == pe ) @@ -1617,7 +1632,7 @@ case 7: _out: {} } -#line 516 "parser.rl" +#line 531 "parser.rl" if (json->create_additions && RTEST(match_string = json->match_string)) { VALUE klass; @@ -1655,11 +1670,11 @@ case 7: static VALUE convert_encoding(VALUE source) { #ifdef HAVE_RUBY_ENCODING_H - VALUE encoding = rb_funcall(source, i_encoding, 0); - if (encoding == CEncoding_ASCII_8BIT) { + rb_encoding *enc = rb_enc_get(source); + if (enc == rb_ascii8bit_encoding()) { FORCE_UTF8(source); } else { - source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); + source = rb_str_conv_enc(source, NULL, rb_utf8_encoding()); } #endif return source; @@ -1700,12 +1715,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) if (json->Vsource) { rb_raise(rb_eTypeError, "already initialized instance"); } +#ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH + rb_scan_args(argc, argv, "1:", &source, &opts); +#else rb_scan_args(argc, argv, "11", &source, &opts); +#endif if (!NIL_P(opts)) { +#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash"); if (NIL_P(opts)) { rb_raise(rb_eArgError, "opts needs to be like a hash"); } else { +#endif VALUE tmp = ID2SYM(i_max_nesting); if (option_given_p(opts, tmp)) { VALUE max_nesting = rb_hash_aref(opts, tmp); @@ -1766,7 +1787,9 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->match_string = Qnil; } +#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH } +#endif } else { json->max_nesting = 100; json->allow_nan = 0; @@ -1786,7 +1809,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1790 "parser.c" +#line 1813 "parser.c" static const int JSON_start = 1; static const int JSON_first_final = 10; static const int JSON_error = 0; @@ -1794,7 +1817,7 @@ static const int JSON_error = 0; static const int JSON_en_main = 1; -#line 698 "parser.rl" +#line 721 "parser.rl" /* @@ -1811,16 +1834,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -#line 1815 "parser.c" +#line 1838 "parser.c" { cs = JSON_start; } -#line 714 "parser.rl" +#line 737 "parser.rl" p = json->source; pe = p + json->len; -#line 1824 "parser.c" +#line 1847 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1854,7 +1877,7 @@ case 1: cs = 0; goto _out; tr2: -#line 690 "parser.rl" +#line 713 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1864,7 +1887,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1868 "parser.c" +#line 1891 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1953,7 +1976,7 @@ case 9: _out: {} } -#line 717 "parser.rl" +#line 740 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -2051,14 +2074,6 @@ void Init_parser(void) i_aset = rb_intern("[]="); i_aref = rb_intern("[]"); i_leftshift = rb_intern("<<"); -#ifdef HAVE_RUBY_ENCODING_H - CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8")); - CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit")); - i_encoding = rb_intern("encoding"); - i_encode = rb_intern("encode"); -#else - i_iconv = rb_intern("iconv"); -#endif } /* diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index f3933cb5d..04d1b47f1 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -1,6 +1,28 @@ #include "../fbuffer/fbuffer.h" #include "parser.h" +#if defined HAVE_RUBY_ENCODING_H +# define EXC_ENCODING rb_utf8_encoding(), +# ifndef HAVE_RB_ENC_RAISE +static void +enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...) +{ + va_list args; + VALUE mesg; + + va_start(args, fmt); + mesg = rb_enc_vsprintf(enc, fmt, args); + va_end(args); + + rb_exc_raise(rb_exc_new3(exc, mesg)); +} +# define rb_enc_raise enc_raise +# endif +#else +# define EXC_ENCODING /* nothing */ +# define rb_enc_raise rb_raise +#endif + /* unicode */ static const char digit_values[256] = { @@ -65,13 +87,6 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) return len; } -#ifdef HAVE_RUBY_ENCODING_H -static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8; -static ID i_encoding, i_encode; -#else -static ID i_iconv; -#endif - static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static VALUE CNaN, CInfinity, CMinusInfinity; @@ -205,14 +220,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu if (json->allow_nan) { *result = CNaN; } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); } } action parse_infinity { if (json->allow_nan) { *result = CInfinity; } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); } } action parse_string { @@ -228,7 +243,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu fexec p + 10; fhold; fbreak; } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); } } np = JSON_parse_float(json, fpc, pe, result); @@ -395,7 +410,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul if(cs >= JSON_array_first_final) { return p + 1; } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); return NULL; } } @@ -550,11 +565,11 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu static VALUE convert_encoding(VALUE source) { #ifdef HAVE_RUBY_ENCODING_H - VALUE encoding = rb_funcall(source, i_encoding, 0); - if (encoding == CEncoding_ASCII_8BIT) { + rb_encoding *enc = rb_enc_get(source); + if (enc == rb_ascii8bit_encoding()) { FORCE_UTF8(source); } else { - source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8); + source = rb_str_conv_enc(source, NULL, rb_utf8_encoding()); } #endif return source; @@ -595,12 +610,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) if (json->Vsource) { rb_raise(rb_eTypeError, "already initialized instance"); } +#ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH + rb_scan_args(argc, argv, "1:", &source, &opts); +#else rb_scan_args(argc, argv, "11", &source, &opts); +#endif if (!NIL_P(opts)) { +#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash"); if (NIL_P(opts)) { rb_raise(rb_eArgError, "opts needs to be like a hash"); } else { +#endif VALUE tmp = ID2SYM(i_max_nesting); if (option_given_p(opts, tmp)) { VALUE max_nesting = rb_hash_aref(opts, tmp); @@ -661,7 +682,9 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->match_string = Qnil; } +#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH } +#endif } else { json->max_nesting = 100; json->allow_nan = 0; @@ -811,14 +834,6 @@ void Init_parser(void) i_aset = rb_intern("[]="); i_aref = rb_intern("[]"); i_leftshift = rb_intern("<<"); -#ifdef HAVE_RUBY_ENCODING_H - CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8")); - CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit")); - i_encoding = rb_intern("encoding"); - i_encode = rb_intern("encode"); -#else - i_iconv = rb_intern("iconv"); -#endif } /* diff --git a/json.gemspec b/json.gemspec index ca023f7860900caf7e37acefa1c514451f2bc4f0..71982d956bad20f0888f738dd5cc986a19b4fe59 100644 GIT binary patch literal 5410 zcmb7IZFAc;4BqGb3Z8qrHoIC%yfkfdOSY~}v+UM(7kB-#%jswdvYAMtN>Ztv>+QD> zpe$L6Es4qH#UUO7AOHdcp0M#xV+L6$BazKdSYhJvD_Yxo!n7%7C+tScj7_`)?|`Xd zwql8x)ihWdpXfe)m_r7N8>#5OP-d~GWzJshrR9*5;(>}}7{nrhQkARoH}5{2dui0hZUCNdKpSm;2Mb7YP#B;U8Wr^B z!iae$RefYyL{WD_d#f~QK;QoH=Htcrw6TIwM4}oir9xv0(eVw%otJWT8_92V#3K7G zt!a(l!UJAk&abAIpFTFYV_0y!XPo@(HLn3Our!fHu=EzDrMIQzN*ZZaIqhq56nw6D zs(tSkAa4*_j*DkS9OE5c|MeDKz)dtnkV96x1@&t&+~9EefxEl0^)4?QR$v3})OH<@ z{i?bKt-l7Af4Vhn!-jNQb5qSYY+7>Lb|TY;CrLZXZ}=VewF)a5Nb6P^S9lg*p@3b@m0|F(5&SdBHV z<)Urdl_=-4T@{%TDO_f;9M)iJ6lU#r;ONE@eoocj#q0kVk!<_VCOGtvM}-xub~A90 z*0CJqg@PS4tdll0+fiGs`aFvKnV3iTI7s<}&~AZ3NvUz!!zRQ`-$SOtJ3tP|F+CVq zhF~MD2P3snMQC~ucrE9BQt-`%kAPldD44@C?~yU6gkGgH*=O$_Q=ltSjDuFOt$l?l ztedh`i|TDQr;9L&uJ{4*;*3ZcHeg#+|@ktHZS8@3A z@WpG-EKTEDln;?uEDdU*{TQEJhX)U<_%6_)3uxj3`q>3^@c~K}0N-9Wzv{uz?$oajMYU@~-7=PiAn0 zbL<^eysXl?NU@7v(U8JQziiJr9?G|StPfo00M|4y+8+1NySAQ2)x#sRfDGX@k=hM7 zWkqf3c|(EW~k-FYnnD#y7eW^GOWoEcl|O10xg|vCK9QVRB9K+e*5l7 zNq&=<4oDm6o+Iy7M?QJPhCdA%$V8<=&Q4fmv*8Pp?LA_~R?`!9Ym{W;=pZ^^x|%Lo zE~YI83p*lwL=Q8Npt)6=-V!CVNKb#*&?vb!&DIkjCWt3@$&}84adXGL5bJm7Vl%b-HdTF1ei>bmN}^CTeiwFkacY(q8&LS6Xn%-fJ%J zYCPrEg)=@ld_FwDpJN|X3MSE_qzq7CALqg_{Ne16$<-wjMVSLR?oz}!0oPO^%sEJx z4I$av$nOOO7dh>ckpsV#SnVi<8fzAK7dL9wRn@^$HrPYU*%bwyNgeV3{)a)pu;q{{E0S@!AddUA1fNn)%P#}?<5{>XJ; zBNQ@)MKrhGzSAqUvdS(?(sYXjpJ`s0QFI4Tl4K*1*|f?s{6y;C(R@c^RgV-(kj~MK zEmjIBZt}iuXQk9WMM=QcN^94ny7)crJlGneTEqY9@M071wO_B-uJ-F0S<8Wt#_~L` zyXThQ^O4cXYJ|O6TKH2K`w>4*gCh|ejg%-cyUORyy!#%V4}c>eHQ%E;0evqLY?y~F zPw?9hDPFnRVXlFPL;1@M=77ao!6$b&6&`-r@#{)jQNV@FRKVE8YMf5*;GqI|y)!zy zf`$6qihM2e?#svAMsyzFDdVb(!tM9CtTe0(aiF_asoSS{9q}|BO~ow51FPUob8VoB zqG7SXOr$&?k>6iCrKp5^yE&0+q44N^BQ|?LO<=5YKZwe7b|uFoQ+ewOzj< zvn-~nGeun?VcH6;i=XvvLh;+~5UmDktLTQ7NMbd;h26Mab+@)A+3Fs%ZN;I@m~rP% zYpT9g)GIXL497ban32ws|nBEFHus0}&_D1E<-mnPmZ4CzoH{LE0-RWW+>Ug)r2l^=M@7jN#4)&ud z7Se*wcmh3Y4YBHj7ZwQvk)j@jW>WOP?X@g~w-c~ODd+%>ay*OUg4<+H4?Ec)!RDph zDwX4CtG<41(&hvhBu+^Zc~Uf21(bZ|h|k>G@?+0_ibyJtqC@YBsS2bF zOX5<_!o?;JYi&5{=hE{amAN6dx=T6fcG7a-mbuzFNK_{t+^ulRp3#18M@Mo$d2;Ls zt`~SVv(J$2?r1zdjF3V<-e;{LGKJqmoWeciswB>d&%{2kzn4#b{QQeXs`Tn9l3quj zZ}y$}hnG=yhLsf7t^M~E{heV@uZG;f);9mc;<{?kicHZ+YpaQKeR*eWU5fp7FjIT< F?>`V4@xA~6 diff --git a/json_pure.gemspec b/json_pure.gemspec index c2fb15fe9..3b3726bd1 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -2,36 +2,36 @@ # stub: json_pure 2.0.0 ruby lib Gem::Specification.new do |s| - s.name = "json_pure" + s.name = "json_pure".freeze s.version = "2.0.0" - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.require_paths = ["lib"] - s.authors = ["Florian Frank"] - s.date = "2016-06-07" - s.description = "This is a JSON implementation in pure Ruby." - s.email = "flori@ping.de" - s.extra_rdoc_files = ["README.md"] - s.files = ["./tests/test_helper.rb", ".gitignore", ".travis.yml", "CHANGES", "Gemfile", "README-json-jruby.markdown", "README.md", "Rakefile", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "references/rfc7159.txt", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/obsolete_fail1.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/json_addition_test.rb", "tests/json_common_interface_test.rb", "tests/json_encoding_test.rb", "tests/json_ext_parser_test.rb", "tests/json_fixtures_test.rb", "tests/json_generator_test.rb", "tests/json_generic_object_test.rb", "tests/json_parser_test.rb", "tests/json_string_matching_test.rb", "tests/test_helper.rb", "tools/fuzz.rb", "tools/server.rb"] - s.homepage = "http://flori.github.com/json" - s.licenses = ["Ruby"] - s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.md"] - s.rubygems_version = "2.5.1" - s.summary = "JSON Implementation for Ruby" - s.test_files = ["./tests/test_helper.rb"] + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["Florian Frank".freeze] + s.date = "2016-06-21" + s.description = "This is a JSON implementation in pure Ruby.".freeze + s.email = "flori@ping.de".freeze + s.extra_rdoc_files = ["README.md".freeze] + s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES".freeze, "Gemfile".freeze, "README-json-jruby.markdown".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] + s.homepage = "http://flori.github.com/json".freeze + s.licenses = ["Ruby".freeze] + s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] + s.rubygems_version = "2.6.4".freeze + s.summary = "JSON Implementation for Ruby".freeze + s.test_files = ["./tests/test_helper.rb".freeze] if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, ["~> 2.0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, ["~> 2.0"]) else - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 2.0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, ["~> 2.0"]) end else - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 2.0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, ["~> 2.0"]) end end From 797ce5386e3919b33831c01561b381a475757f8a Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 19 Oct 2015 10:53:16 -0700 Subject: [PATCH 142/312] resize strings after parsing The parser uses `rb_str_buf_new` to allocate new strings. `rb_str_buf_new` [has a minimum size of 128 and is not an embedded string](https://github.com/ruby/ruby/blob/9949407fd90c1c5bfe332141c75db995a9b867aa/string.c#L1119-L1135). This causes applications that parse JS to allocate extra memory when parsing short strings. For a real-world example, we can use the mime-types gem. The mime-types gem stores all mime types inside a JSON file and parses them when you require the gem. Here is a sample program: ```ruby require 'objspace' require 'mime-types' GC.start GC.start p ObjectSpace.memsize_of_all String ``` The example program loads the mime-types gem and outputs the total space used by all strings. Here are the results of the program before and after this patch: ** Before ** ``` [aaron@TC json (memuse)]$ ruby test.rb 5497494 [aaron@TC json (memuse)]$ ``` ** After ** ``` [aaron@TC json (memuse)]$ ruby -I lib:ext test.rb 3335862 [aaron@TC json (memuse)]$ ``` This change results in a ~40% reduction of memory use for strings in the mime-types gem. Thanks @matthewd for finding the problem, and @nobu for the patch! --- ext/json/ext/parser/parser.rl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index 04d1b47f1..f47928119 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -542,6 +542,8 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu if (json->symbolize_names && json->parsing_name) { *result = rb_str_intern(*result); + } else { + rb_str_resize(*result, RSTRING_LEN(*result)); } if (cs >= JSON_string_first_final) { return p + 1; From ad7e997411f8de2184ed4f61b0d207b0ea3e76ef Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 3 Mar 2016 14:49:15 -0800 Subject: [PATCH 143/312] regenerate parser --- ext/json/ext/parser/parser.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 8d8380818..7e32ef071 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1647,6 +1647,8 @@ case 7: if (json->symbolize_names && json->parsing_name) { *result = rb_str_intern(*result); + } else { + rb_str_resize(*result, RSTRING_LEN(*result)); } if (cs >= JSON_string_first_final) { return p + 1; From a33422799cc104acf8eb7884c4613a714ccc5da3 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 24 Apr 2016 02:21:20 +0900 Subject: [PATCH 144/312] Append newline at EOF --- lib/json/add/complex.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/add/complex.rb b/lib/json/add/complex.rb index 2723f6010..3d653bb50 100644 --- a/lib/json/add/complex.rb +++ b/lib/json/add/complex.rb @@ -25,4 +25,4 @@ def as_json(*) def to_json(*) as_json.to_json end -end \ No newline at end of file +end From 253c61548214effb11fbfd2a256578fe16d8e2bc Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 24 Apr 2016 02:17:49 +0900 Subject: [PATCH 145/312] Remove useless methods Remove useless overriding methods, [] and []=, which are same as OpenStruct. --- lib/json/generic_object.rb | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/json/generic_object.rb b/lib/json/generic_object.rb index 8b8fd53be..3a14f0ea7 100644 --- a/lib/json/generic_object.rb +++ b/lib/json/generic_object.rb @@ -47,14 +47,6 @@ def to_hash table end - def [](name) - table[name.to_sym] - end - - def []=(name, value) - __send__ "#{name}=", value - end - def |(other) self.class[other.to_hash.merge(to_hash)] end From 16bd77f50d055dd85acf4e11296141c5e984b350 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 24 Apr 2016 02:10:53 +0900 Subject: [PATCH 146/312] Use assert_raise consistently --- tests/json_addition_test.rb | 4 +-- tests/json_common_interface_test.rb | 4 +-- tests/json_fixtures_test.rb | 2 +- tests/json_generator_test.rb | 34 ++++++++++---------- tests/json_parser_test.rb | 50 ++++++++++++++--------------- 5 files changed, 47 insertions(+), 47 deletions(-) diff --git a/tests/json_addition_test.rb b/tests/json_addition_test.rb index 128f34a41..cb0765910 100644 --- a/tests/json_addition_test.rb +++ b/tests/json_addition_test.rb @@ -108,7 +108,7 @@ def test_extended_json_fail2 c = C.new assert !C.json_creatable? json = generate(c) - assert_raises(ArgumentError, NameError) { parse(json, :create_additions => true) } + assert_raise(ArgumentError, NameError) { parse(json, :create_additions => true) } end def test_raw_strings @@ -147,7 +147,7 @@ def test_core assert_equal s, JSON(JSON(s), :create_additions => true) struct = Struct.new :foo, :bar s = struct.new 4711, 'foot' - assert_raises(JSONError) { JSON(s) } + assert_raise(JSONError) { JSON(s) } begin raise TypeError, "test me" rescue TypeError => e diff --git a/tests/json_common_interface_test.rb b/tests/json_common_interface_test.rb index 38136fa91..30c54c84b 100644 --- a/tests/json_common_interface_test.rb +++ b/tests/json_common_interface_test.rb @@ -100,8 +100,8 @@ def test_dump too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]' assert_equal too_deep, dump(eval(too_deep)) assert_kind_of String, Marshal.dump(eval(too_deep)) - assert_raises(ArgumentError) { dump(eval(too_deep), 100) } - assert_raises(ArgumentError) { Marshal.dump(eval(too_deep), 100) } + assert_raise(ArgumentError) { dump(eval(too_deep), 100) } + assert_raise(ArgumentError) { Marshal.dump(eval(too_deep), 100) } assert_equal too_deep, dump(eval(too_deep), 101) assert_kind_of String, Marshal.dump(eval(too_deep), 101) output = StringIO.new diff --git a/tests/json_fixtures_test.rb b/tests/json_fixtures_test.rb index 6681b8d82..041998302 100644 --- a/tests/json_fixtures_test.rb +++ b/tests/json_fixtures_test.rb @@ -22,7 +22,7 @@ def test_passing def test_failing for name, source in @failed - assert_raises(JSON::ParserError, JSON::NestingError, + assert_raise(JSON::ParserError, JSON::NestingError, "Did not fail for fixture '#{name}': #{source.inspect}") do JSON.parse(source) end diff --git a/tests/json_generator_test.rb b/tests/json_generator_test.rb index 708747163..18b08337f 100644 --- a/tests/json_generator_test.rb +++ b/tests/json_generator_test.rb @@ -118,12 +118,12 @@ def test_states assert s[:check_circular?] h = { 1=>2 } h[3] = h - assert_raises(JSON::NestingError) { generate(h) } - assert_raises(JSON::NestingError) { generate(h, s) } + assert_raise(JSON::NestingError) { generate(h) } + assert_raise(JSON::NestingError) { generate(h, s) } s = JSON.state.new a = [ 1, 2 ] a << a - assert_raises(JSON::NestingError) { generate(a, s) } + assert_raise(JSON::NestingError) { generate(a, s) } assert s.check_circular? assert s[:check_circular?] end @@ -177,34 +177,34 @@ def test_fast_state end def test_allow_nan - assert_raises(GeneratorError) { generate([JSON::NaN]) } + assert_raise(GeneratorError) { generate([JSON::NaN]) } assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true) - assert_raises(GeneratorError) { fast_generate([JSON::NaN]) } - assert_raises(GeneratorError) { pretty_generate([JSON::NaN]) } + assert_raise(GeneratorError) { fast_generate([JSON::NaN]) } + assert_raise(GeneratorError) { pretty_generate([JSON::NaN]) } assert_equal "[\n NaN\n]", pretty_generate([JSON::NaN], :allow_nan => true) - assert_raises(GeneratorError) { generate([JSON::Infinity]) } + assert_raise(GeneratorError) { generate([JSON::Infinity]) } assert_equal '[Infinity]', generate([JSON::Infinity], :allow_nan => true) - assert_raises(GeneratorError) { fast_generate([JSON::Infinity]) } - assert_raises(GeneratorError) { pretty_generate([JSON::Infinity]) } + assert_raise(GeneratorError) { fast_generate([JSON::Infinity]) } + assert_raise(GeneratorError) { pretty_generate([JSON::Infinity]) } assert_equal "[\n Infinity\n]", pretty_generate([JSON::Infinity], :allow_nan => true) - assert_raises(GeneratorError) { generate([JSON::MinusInfinity]) } + assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) } assert_equal '[-Infinity]', generate([JSON::MinusInfinity], :allow_nan => true) - assert_raises(GeneratorError) { fast_generate([JSON::MinusInfinity]) } - assert_raises(GeneratorError) { pretty_generate([JSON::MinusInfinity]) } + assert_raise(GeneratorError) { fast_generate([JSON::MinusInfinity]) } + assert_raise(GeneratorError) { pretty_generate([JSON::MinusInfinity]) } assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true) end def test_depth ary = []; ary << ary assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth - assert_raises(JSON::NestingError) { generate(ary) } + assert_raise(JSON::NestingError) { generate(ary) } assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth - assert_raises(JSON::NestingError) { JSON.pretty_generate(ary) } + assert_raise(JSON::NestingError) { JSON.pretty_generate(ary) } assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth s = JSON.state.new assert_equal 0, s.depth - assert_raises(JSON::NestingError) { ary.to_json(s) } + assert_raise(JSON::NestingError) { ary.to_json(s) } assert_equal 100, s.depth end @@ -330,8 +330,8 @@ def test_json_generate def test_nesting too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]' too_deep_ary = eval too_deep - assert_raises(JSON::NestingError) { generate too_deep_ary } - assert_raises(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 } + assert_raise(JSON::NestingError) { generate too_deep_ary } + assert_raise(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 } ok = generate too_deep_ary, :max_nesting => 101 assert_equal too_deep, ok ok = generate too_deep_ary, :max_nesting => nil diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb index a5793f902..d2b0fd1ff 100644 --- a/tests/json_parser_test.rb +++ b/tests/json_parser_test.rb @@ -52,7 +52,7 @@ def test_parse_simple_objects assert_equal({ "a" => nil }, parse('{"a":null}')) assert_equal({ "a" => false }, parse('{ "a" : false } ')) assert_equal({ "a" => false }, parse('{"a":false}')) - assert_raises(JSON::ParserError) { parse('{false}') } + assert_raise(JSON::ParserError) { parse('{false}') } assert_equal({ "a" => true }, parse('{"a":true}')) assert_equal({ "a" => true }, parse(' { "a" : true } ')) assert_equal({ "a" => -23 }, parse(' { "a" : -23 } ')) @@ -64,10 +64,10 @@ def test_parse_simple_objects end def test_parse_numbers - assert_raises(JSON::ParserError) { parse('+23.2') } - assert_raises(JSON::ParserError) { parse('+23') } - assert_raises(JSON::ParserError) { parse('.23') } - assert_raises(JSON::ParserError) { parse('023') } + assert_raise(JSON::ParserError) { parse('+23.2') } + assert_raise(JSON::ParserError) { parse('+23') } + assert_raise(JSON::ParserError) { parse('.23') } + assert_raise(JSON::ParserError) { parse('023') } assert_equal 23, parse('23') assert_equal -23, parse('-23') assert_equal_float 3.141, parse('3.141') @@ -78,11 +78,11 @@ def test_parse_numbers assert_equal_float 3.141, parse('3141.0E-3') assert_equal_float -3.141, parse('-3141.0e-3') assert_equal_float -3.141, parse('-3141e-3') - assert_raises(ParserError) { parse('NaN') } + assert_raise(ParserError) { parse('NaN') } assert parse('NaN', :allow_nan => true).nan? - assert_raises(ParserError) { parse('Infinity') } + assert_raise(ParserError) { parse('Infinity') } assert_equal 1.0/0, parse('Infinity', :allow_nan => true) - assert_raises(ParserError) { parse('-Infinity') } + assert_raise(ParserError) { parse('-Infinity') } assert_equal -1.0/0, parse('-Infinity', :allow_nan => true) end @@ -165,19 +165,19 @@ def test_parse_big_integers end def test_some_wrong_inputs - assert_raises(ParserError) { parse('[] bla') } - assert_raises(ParserError) { parse('[] 1') } - assert_raises(ParserError) { parse('[] []') } - assert_raises(ParserError) { parse('[] {}') } - assert_raises(ParserError) { parse('{} []') } - assert_raises(ParserError) { parse('{} {}') } - assert_raises(ParserError) { parse('[NULL]') } - assert_raises(ParserError) { parse('[FALSE]') } - assert_raises(ParserError) { parse('[TRUE]') } - assert_raises(ParserError) { parse('[07] ') } - assert_raises(ParserError) { parse('[0a]') } - assert_raises(ParserError) { parse('[1.]') } - assert_raises(ParserError) { parse(' ') } + assert_raise(ParserError) { parse('[] bla') } + assert_raise(ParserError) { parse('[] 1') } + assert_raise(ParserError) { parse('[] []') } + assert_raise(ParserError) { parse('[] {}') } + assert_raise(ParserError) { parse('{} []') } + assert_raise(ParserError) { parse('{} {}') } + assert_raise(ParserError) { parse('[NULL]') } + assert_raise(ParserError) { parse('[FALSE]') } + assert_raise(ParserError) { parse('[TRUE]') } + assert_raise(ParserError) { parse('[07] ') } + assert_raise(ParserError) { parse('[0a]') } + assert_raise(ParserError) { parse('[1.]') } + assert_raise(ParserError) { parse(' ') } end def test_symbolize_names @@ -212,7 +212,7 @@ def test_parse_comments * comment */ } EOT - assert_raises(ParserError) { parse(json) } + assert_raise(ParserError) { parse(json) } json = < 100 } + assert_raise(JSON::NestingError) { parse too_deep } + assert_raise(JSON::NestingError) { parse too_deep, :max_nesting => 100 } ok = parse too_deep, :max_nesting => 101 assert_equal too_deep_ary, ok ok = parse too_deep, :max_nesting => nil From 963e815cb1c3c9989192b2459da9a93518522807 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 24 Apr 2016 01:52:15 +0900 Subject: [PATCH 147/312] Use enum Use `enum` instead of `static const int` to get rid of unused-const-variable warnings. --- Rakefile | 1 + ext/json/ext/parser/parser.c | 65 +++++++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/Rakefile b/Rakefile index 4aa311e57..4448d2e67 100644 --- a/Rakefile +++ b/Rakefile @@ -361,6 +361,7 @@ else sh "ragel -x parser.rl | #{RAGEL_CODEGEN} -G2" end src = File.read("parser.c").gsub(/[ \t]+$/, '') + src.gsub!(/^static const int (JSON_.*=.*);$/, 'enum {\1};') File.open("parser.c", "w") {|f| f.print src} end end diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 7e32ef071..b1260b315 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -102,12 +102,19 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, +<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 106 "parser.c" static const int JSON_object_start = 1; static const int JSON_object_first_final = 27; static const int JSON_object_error = 0; +======= +#line 92 "parser.c" +enum {JSON_object_start = 1}; +enum {JSON_object_first_final = 27}; +enum {JSON_object_error = 0}; +>>>>>>> Use enum -static const int JSON_object_en_main = 1; +enum {JSON_object_en_main = 1}; #line 165 "parser.rl" @@ -480,12 +487,19 @@ case 26: +<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 484 "parser.c" static const int JSON_value_start = 1; static const int JSON_value_first_final = 29; static const int JSON_value_error = 0; +======= +#line 470 "parser.c" +enum {JSON_value_start = 1}; +enum {JSON_value_first_final = 29}; +enum {JSON_value_error = 0}; +>>>>>>> Use enum -static const int JSON_value_en_main = 1; +enum {JSON_value_en_main = 1}; #line 285 "parser.rl" @@ -878,12 +892,19 @@ case 28: } +<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 882 "parser.c" static const int JSON_integer_start = 1; static const int JSON_integer_first_final = 3; static const int JSON_integer_error = 0; +======= +#line 868 "parser.c" +enum {JSON_integer_start = 1}; +enum {JSON_integer_first_final = 3}; +enum {JSON_integer_error = 0}; +>>>>>>> Use enum -static const int JSON_integer_en_main = 1; +enum {JSON_integer_en_main = 1}; #line 309 "parser.rl" @@ -977,12 +998,19 @@ case 5: } +<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 981 "parser.c" static const int JSON_float_start = 1; static const int JSON_float_first_final = 8; static const int JSON_float_error = 0; +======= +#line 967 "parser.c" +enum {JSON_float_start = 1}; +enum {JSON_float_first_final = 8}; +enum {JSON_float_error = 0}; +>>>>>>> Use enum -static const int JSON_float_en_main = 1; +enum {JSON_float_en_main = 1}; #line 343 "parser.rl" @@ -1143,12 +1171,19 @@ case 7: +<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 1147 "parser.c" static const int JSON_array_start = 1; static const int JSON_array_first_final = 17; static const int JSON_array_error = 0; +======= +#line 1133 "parser.c" +enum {JSON_array_start = 1}; +enum {JSON_array_first_final = 17}; +enum {JSON_array_error = 0}; +>>>>>>> Use enum -static const int JSON_array_en_main = 1; +enum {JSON_array_en_main = 1}; #line 395 "parser.rl" @@ -1475,12 +1510,19 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } +<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 1479 "parser.c" static const int JSON_string_start = 1; static const int JSON_string_first_final = 8; static const int JSON_string_error = 0; +======= +#line 1465 "parser.c" +enum {JSON_string_start = 1}; +enum {JSON_string_first_final = 8}; +enum {JSON_string_error = 0}; +>>>>>>> Use enum -static const int JSON_string_en_main = 1; +enum {JSON_string_en_main = 1}; #line 508 "parser.rl" @@ -1811,12 +1853,19 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } +<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 1813 "parser.c" static const int JSON_start = 1; static const int JSON_first_final = 10; static const int JSON_error = 0; - -static const int JSON_en_main = 1; +======= +#line 1788 "parser.c" +enum {JSON_start = 1}; +enum {JSON_first_final = 10}; +enum {JSON_error = 0}; +>>>>>>> Use enum + +enum {JSON_en_main = 1}; #line 721 "parser.rl" From a20bc3c5fcd0e93b85803e685b527ac1ea14c1be Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 24 Apr 2016 01:37:39 +0900 Subject: [PATCH 148/312] Remove unnecessary conversion StringValue does the conversion. --- ext/json/ext/parser/parser.c | 33 ++++++++++++++++++++++++++++++++- ext/json/ext/parser/parser.rl | 1 - 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index b1260b315..afa28646d 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1842,7 +1842,6 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) json->object_class = Qnil; json->array_class = Qnil; } - source = rb_convert_type(source, T_STRING, "String", "to_str"); source = convert_encoding(StringValue(source)); json->current_nesting = 0; StringValue(source); @@ -1853,6 +1852,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } +<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b <<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 1813 "parser.c" static const int JSON_start = 1; @@ -1860,6 +1860,9 @@ static const int JSON_first_final = 10; static const int JSON_error = 0; ======= #line 1788 "parser.c" +======= +#line 1787 "parser.c" +>>>>>>> Remove unnecessary conversion enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1868,7 +1871,11 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; +<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b #line 721 "parser.rl" +======= +#line 695 "parser.rl" +>>>>>>> Remove unnecessary conversion /* @@ -1885,16 +1892,28 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; +<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b #line 1838 "parser.c" +======= +#line 1812 "parser.c" +>>>>>>> Remove unnecessary conversion { cs = JSON_start; } +<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b #line 737 "parser.rl" p = json->source; pe = p + json->len; #line 1847 "parser.c" +======= +#line 711 "parser.rl" + p = json->source; + pe = p + json->len; + +#line 1821 "parser.c" +>>>>>>> Remove unnecessary conversion { if ( p == pe ) goto _test_eof; @@ -1928,7 +1947,11 @@ case 1: cs = 0; goto _out; tr2: +<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b #line 713 "parser.rl" +======= +#line 687 "parser.rl" +>>>>>>> Remove unnecessary conversion { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1938,7 +1961,11 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: +<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b #line 1891 "parser.c" +======= +#line 1865 "parser.c" +>>>>>>> Remove unnecessary conversion switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2027,7 +2054,11 @@ case 9: _out: {} } +<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b #line 740 "parser.rl" +======= +#line 714 "parser.rl" +>>>>>>> Remove unnecessary conversion if (cs >= JSON_first_final && p == pe) { return result; diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index f47928119..0c65a09d4 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -695,7 +695,6 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) json->object_class = Qnil; json->array_class = Qnil; } - source = rb_convert_type(source, T_STRING, "String", "to_str"); source = convert_encoding(StringValue(source)); json->current_nesting = 0; StringValue(source); From 0a49b1f7d5bccfa324cdc74ba6f899f3925a7830 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 24 Apr 2016 01:47:49 +0900 Subject: [PATCH 149/312] Use rb_encoding Use rb_encoding functions to convert encodings. --- ext/json/ext/parser/mkmf.log | 60 ++++++++++++++++++++++ ext/json/ext/parser/parser.c | 97 +++--------------------------------- 2 files changed, 68 insertions(+), 89 deletions(-) create mode 100644 ext/json/ext/parser/mkmf.log diff --git a/ext/json/ext/parser/mkmf.log b/ext/json/ext/parser/mkmf.log new file mode 100644 index 000000000..e725db5fc --- /dev/null +++ b/ext/json/ext/parser/mkmf.log @@ -0,0 +1,60 @@ +have_func: checking for rb_enc_raise() in ruby.h... -------------------- yes + +"gcc -o conftest -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/x86_64-darwin15 -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/ruby/backward -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/readline/include -I/usr/local/opt/libksba/include -I/usr/local/opt/openssl/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/flori/.rvm/rubies/ruby-2.3.1/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -L. -fstack-protector -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -lruby.2.3.0 -lpthread -ldl -lobjc " +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return 0; +6: } +/* end */ + +"gcc -o conftest -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/x86_64-darwin15 -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/ruby/backward -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/readline/include -I/usr/local/opt/libksba/include -I/usr/local/opt/openssl/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/flori/.rvm/rubies/ruby-2.3.1/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -L. -fstack-protector -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -lruby.2.3.0 -lpthread -ldl -lobjc " +conftest.c:15:57: error: use of undeclared identifier 'rb_enc_raise' +int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_enc_raise; return !p; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: printf("%p", &t); +11: } +12: +13: return 0; +14: } +15: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_enc_raise; return !p; } +/* end */ + +"gcc -o conftest -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/x86_64-darwin15 -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/ruby/backward -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/readline/include -I/usr/local/opt/libksba/include -I/usr/local/opt/openssl/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/flori/.rvm/rubies/ruby-2.3.1/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -L. -fstack-protector -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -lruby.2.3.0 -lpthread -ldl -lobjc " +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: printf("%p", &t); +11: } +12: +13: return 0; +14: } +15: extern void rb_enc_raise(); +16: int t(void) { rb_enc_raise(); return 0; } +/* end */ + +-------------------- + diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index afa28646d..269c9cacb 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -102,17 +102,10 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, -<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 106 "parser.c" -static const int JSON_object_start = 1; -static const int JSON_object_first_final = 27; -static const int JSON_object_error = 0; -======= -#line 92 "parser.c" enum {JSON_object_start = 1}; enum {JSON_object_first_final = 27}; enum {JSON_object_error = 0}; ->>>>>>> Use enum enum {JSON_object_en_main = 1}; @@ -487,17 +480,10 @@ case 26: -<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 484 "parser.c" -static const int JSON_value_start = 1; -static const int JSON_value_first_final = 29; -static const int JSON_value_error = 0; -======= -#line 470 "parser.c" enum {JSON_value_start = 1}; enum {JSON_value_first_final = 29}; enum {JSON_value_error = 0}; ->>>>>>> Use enum enum {JSON_value_en_main = 1}; @@ -892,17 +878,10 @@ case 28: } -<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 882 "parser.c" -static const int JSON_integer_start = 1; -static const int JSON_integer_first_final = 3; -static const int JSON_integer_error = 0; -======= -#line 868 "parser.c" enum {JSON_integer_start = 1}; enum {JSON_integer_first_final = 3}; enum {JSON_integer_error = 0}; ->>>>>>> Use enum enum {JSON_integer_en_main = 1}; @@ -998,17 +977,10 @@ case 5: } -<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 981 "parser.c" -static const int JSON_float_start = 1; -static const int JSON_float_first_final = 8; -static const int JSON_float_error = 0; -======= -#line 967 "parser.c" enum {JSON_float_start = 1}; enum {JSON_float_first_final = 8}; enum {JSON_float_error = 0}; ->>>>>>> Use enum enum {JSON_float_en_main = 1}; @@ -1171,17 +1143,10 @@ case 7: -<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 1147 "parser.c" -static const int JSON_array_start = 1; -static const int JSON_array_first_final = 17; -static const int JSON_array_error = 0; -======= -#line 1133 "parser.c" enum {JSON_array_start = 1}; enum {JSON_array_first_final = 17}; enum {JSON_array_error = 0}; ->>>>>>> Use enum enum {JSON_array_en_main = 1}; @@ -1510,17 +1475,10 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 #line 1479 "parser.c" -static const int JSON_string_start = 1; -static const int JSON_string_first_final = 8; -static const int JSON_string_error = 0; -======= -#line 1465 "parser.c" enum {JSON_string_start = 1}; enum {JSON_string_first_final = 8}; enum {JSON_string_error = 0}; ->>>>>>> Use enum enum {JSON_string_en_main = 1}; @@ -1852,30 +1810,15 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b -<<<<<<< dad1dad53ad48946bf2a8de60b8fb419e1180bf0 -#line 1813 "parser.c" -static const int JSON_start = 1; -static const int JSON_first_final = 10; -static const int JSON_error = 0; -======= -#line 1788 "parser.c" -======= -#line 1787 "parser.c" ->>>>>>> Remove unnecessary conversion +#line 1814 "parser.c" enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; ->>>>>>> Use enum enum {JSON_en_main = 1}; -<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b -#line 721 "parser.rl" -======= -#line 695 "parser.rl" ->>>>>>> Remove unnecessary conversion +#line 722 "parser.rl" /* @@ -1892,28 +1835,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b -#line 1838 "parser.c" -======= -#line 1812 "parser.c" ->>>>>>> Remove unnecessary conversion +#line 1839 "parser.c" { cs = JSON_start; } -<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b -#line 737 "parser.rl" +#line 738 "parser.rl" p = json->source; pe = p + json->len; -#line 1847 "parser.c" -======= -#line 711 "parser.rl" - p = json->source; - pe = p + json->len; - -#line 1821 "parser.c" ->>>>>>> Remove unnecessary conversion +#line 1848 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1947,11 +1878,7 @@ case 1: cs = 0; goto _out; tr2: -<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b -#line 713 "parser.rl" -======= -#line 687 "parser.rl" ->>>>>>> Remove unnecessary conversion +#line 714 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1961,11 +1888,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b -#line 1891 "parser.c" -======= -#line 1865 "parser.c" ->>>>>>> Remove unnecessary conversion +#line 1892 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2054,11 +1977,7 @@ case 9: _out: {} } -<<<<<<< 949543418c0888d7deba00a93e08b7f56637ce9b -#line 740 "parser.rl" -======= -#line 714 "parser.rl" ->>>>>>> Remove unnecessary conversion +#line 741 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; From 2d475160b490389060d66980465bb7220b2363e7 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 24 Apr 2016 02:04:34 +0900 Subject: [PATCH 150/312] Exception encoding Raise with messages in UTF-8 encoding. --- ext/json/ext/parser/parser.c | 34 +++++++++++++++++++++++++++++++++- ext/json/ext/parser/parser.rl | 2 +- tests/json_parser_test.rb | 10 ++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 269c9cacb..a99b73bb7 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1810,7 +1810,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } +<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 1814 "parser.c" +======= +#line 1801 "parser.c" +>>>>>>> Exception encoding enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1818,7 +1822,11 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; +<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 722 "parser.rl" +======= +#line 709 "parser.rl" +>>>>>>> Exception encoding /* @@ -1835,16 +1843,28 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; +<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 1839 "parser.c" +======= +#line 1826 "parser.c" +>>>>>>> Exception encoding { cs = JSON_start; } +<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 738 "parser.rl" p = json->source; pe = p + json->len; #line 1848 "parser.c" +======= +#line 725 "parser.rl" + p = json->source; + pe = p + json->len; + +#line 1835 "parser.c" +>>>>>>> Exception encoding { if ( p == pe ) goto _test_eof; @@ -1878,7 +1898,11 @@ case 1: cs = 0; goto _out; tr2: +<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 714 "parser.rl" +======= +#line 701 "parser.rl" +>>>>>>> Exception encoding { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1888,7 +1912,11 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: +<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 1892 "parser.c" +======= +#line 1879 "parser.c" +>>>>>>> Exception encoding switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1977,12 +2005,16 @@ case 9: _out: {} } +<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 741 "parser.rl" +======= +#line 728 "parser.rl" +>>>>>>> Exception encoding if (cs >= JSON_first_final && p == pe) { return result; } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); return Qnil; } } diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index 0c65a09d4..eac3e6cf1 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -742,7 +742,7 @@ static VALUE cParser_parse(VALUE self) if (cs >= JSON_first_final && p == pe) { return result; } else { - rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); return Qnil; } } diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb index d2b0fd1ff..1d1987b6d 100644 --- a/tests/json_parser_test.rb +++ b/tests/json_parser_test.rb @@ -19,6 +19,16 @@ def test_argument_encoding assert_equal Encoding::UTF_16, source.encoding end if defined?(Encoding::UTF_16) + def test_error_message_encoding + bug10705 = '[ruby-core:67386] [Bug #10705]' + json = ".\"\xE2\x88\x9A\"".force_encoding(Encoding::UTF_8) + e = assert_raise(JSON::ParserError) { + JSON::Ext::Parser.new(json).parse + } + assert_equal(Encoding::UTF_8, e.message.encoding, bug10705) + assert_include(e.message, json, bug10705) + end if defined?(Encoding::UTF_8) and defined?(JSON::Ext::Parser) + def test_parsing parser = JSON::Parser.new('"test"') assert_equal 'test', parser.parse From 236d43ed1aaa2eeae346d2f6b2304c32b62b8823 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 24 Apr 2016 02:08:30 +0900 Subject: [PATCH 151/312] Optional hash in rb_scan_args Use ':' in rb_scan_args to get optional hash, which available since ruby 2.1. --- ext/json/ext/parser/parser.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index a99b73bb7..f3e250273 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1810,11 +1810,15 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } +<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c <<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 1814 "parser.c" ======= #line 1801 "parser.c" >>>>>>> Exception encoding +======= +#line 1809 "parser.c" +>>>>>>> Optional hash in rb_scan_args enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1822,11 +1826,15 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; +<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c <<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 722 "parser.rl" ======= #line 709 "parser.rl" >>>>>>> Exception encoding +======= +#line 717 "parser.rl" +>>>>>>> Optional hash in rb_scan_args /* @@ -1843,15 +1851,20 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; +<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c <<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 1839 "parser.c" ======= #line 1826 "parser.c" >>>>>>> Exception encoding +======= +#line 1834 "parser.c" +>>>>>>> Optional hash in rb_scan_args { cs = JSON_start; } +<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c <<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 738 "parser.rl" p = json->source; @@ -1865,6 +1878,13 @@ static VALUE cParser_parse(VALUE self) #line 1835 "parser.c" >>>>>>> Exception encoding +======= +#line 733 "parser.rl" + p = json->source; + pe = p + json->len; + +#line 1843 "parser.c" +>>>>>>> Optional hash in rb_scan_args { if ( p == pe ) goto _test_eof; @@ -1898,11 +1918,15 @@ case 1: cs = 0; goto _out; tr2: +<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c <<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 714 "parser.rl" ======= #line 701 "parser.rl" >>>>>>> Exception encoding +======= +#line 709 "parser.rl" +>>>>>>> Optional hash in rb_scan_args { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1912,11 +1936,15 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: +<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c <<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 1892 "parser.c" ======= #line 1879 "parser.c" >>>>>>> Exception encoding +======= +#line 1887 "parser.c" +>>>>>>> Optional hash in rb_scan_args switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2005,11 +2033,15 @@ case 9: _out: {} } +<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c <<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 741 "parser.rl" ======= #line 728 "parser.rl" >>>>>>> Exception encoding +======= +#line 736 "parser.rl" +>>>>>>> Optional hash in rb_scan_args if (cs >= JSON_first_final && p == pe) { return result; From 1e5684ff2cbde8be819eac1e50e0edbfd120d77b Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 24 Apr 2016 02:31:53 +0900 Subject: [PATCH 152/312] Add frozen_string_literal: false When you change this to true, you may need to add more tests. --- lib/json.rb | 1 + lib/json/add/bigdecimal.rb | 1 + lib/json/add/complex.rb | 1 + lib/json/add/core.rb | 1 + lib/json/add/date.rb | 1 + lib/json/add/date_time.rb | 1 + lib/json/add/exception.rb | 1 + lib/json/add/ostruct.rb | 1 + lib/json/add/range.rb | 1 + lib/json/add/rational.rb | 1 + lib/json/add/regexp.rb | 1 + lib/json/add/struct.rb | 1 + lib/json/add/symbol.rb | 1 + lib/json/add/time.rb | 1 + lib/json/common.rb | 1 + lib/json/generic_object.rb | 1 + lib/json/pure/generator.rb | 1 + lib/json/pure/parser.rb | 1 + lib/json/version.rb | 1 + tests/json_addition_test.rb | 1 + tests/json_common_interface_test.rb | 1 + tests/json_encoding_test.rb | 1 + tests/json_ext_parser_test.rb | 1 + tests/json_fixtures_test.rb | 1 + tests/json_generic_object_test.rb | 1 + tests/json_parser_test.rb | 1 + tests/json_string_matching_test.rb | 1 + 27 files changed, 27 insertions(+) diff --git a/lib/json.rb b/lib/json.rb index 24aa385c9..b5a691241 100644 --- a/lib/json.rb +++ b/lib/json.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false require 'json/common' ## diff --git a/lib/json/add/bigdecimal.rb b/lib/json/add/bigdecimal.rb index 0ef69f12e..539daeeaf 100644 --- a/lib/json/add/bigdecimal.rb +++ b/lib/json/add/bigdecimal.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/add/complex.rb b/lib/json/add/complex.rb index 3d653bb50..28ef734da 100644 --- a/lib/json/add/complex.rb +++ b/lib/json/add/complex.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/add/core.rb b/lib/json/add/core.rb index 77d9dc0b2..bfb017c46 100644 --- a/lib/json/add/core.rb +++ b/lib/json/add/core.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false # This file requires the implementations of ruby core's custom objects for # serialisation/deserialisation. diff --git a/lib/json/add/date.rb b/lib/json/add/date.rb index 458d9eba9..25523561a 100644 --- a/lib/json/add/date.rb +++ b/lib/json/add/date.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/add/date_time.rb b/lib/json/add/date_time.rb index a1009cf5d..38b0e86ab 100644 --- a/lib/json/add/date_time.rb +++ b/lib/json/add/date_time.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/add/exception.rb b/lib/json/add/exception.rb index f4b150d23..a107e5b3c 100644 --- a/lib/json/add/exception.rb +++ b/lib/json/add/exception.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/add/ostruct.rb b/lib/json/add/ostruct.rb index a62f92f59..7c1391005 100644 --- a/lib/json/add/ostruct.rb +++ b/lib/json/add/ostruct.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/add/range.rb b/lib/json/add/range.rb index 0df382c60..93529fb1c 100644 --- a/lib/json/add/range.rb +++ b/lib/json/add/range.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/add/rational.rb b/lib/json/add/rational.rb index ee39c20e8..356940b22 100644 --- a/lib/json/add/rational.rb +++ b/lib/json/add/rational.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/add/regexp.rb b/lib/json/add/regexp.rb index 9adf06c8f..a93866b05 100644 --- a/lib/json/add/regexp.rb +++ b/lib/json/add/regexp.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/add/struct.rb b/lib/json/add/struct.rb index e1e24800d..e8395ed42 100644 --- a/lib/json/add/struct.rb +++ b/lib/json/add/struct.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/add/symbol.rb b/lib/json/add/symbol.rb index 6df77cab0..74b13a423 100644 --- a/lib/json/add/symbol.rb +++ b/lib/json/add/symbol.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/add/time.rb b/lib/json/add/time.rb index 122750828..b73acc408 100644 --- a/lib/json/add/time.rb +++ b/lib/json/add/time.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end diff --git a/lib/json/common.rb b/lib/json/common.rb index 55908f8b5..b53041b98 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false require 'json/version' require 'json/generic_object' diff --git a/lib/json/generic_object.rb b/lib/json/generic_object.rb index 3a14f0ea7..6c8f03997 100644 --- a/lib/json/generic_object.rb +++ b/lib/json/generic_object.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false require 'ostruct' module JSON diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index 98bc369fd..ccb6fe422 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false module JSON MAP = { "\x0" => '\u0000', diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index f02f4086b..b907236bc 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false require 'strscan' module JSON diff --git a/lib/json/version.rb b/lib/json/version.rb index b91ccd708..b4d1b3b5a 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false module JSON # JSON version VERSION = '2.0.0' diff --git a/tests/json_addition_test.rb b/tests/json_addition_test.rb index cb0765910..a028e0f08 100644 --- a/tests/json_addition_test.rb +++ b/tests/json_addition_test.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false require 'test_helper' require 'json/add/core' require 'json/add/complex' diff --git a/tests/json_common_interface_test.rb b/tests/json_common_interface_test.rb index 30c54c84b..b2051d4c5 100644 --- a/tests/json_common_interface_test.rb +++ b/tests/json_common_interface_test.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false require 'test_helper' require 'stringio' require 'tempfile' diff --git a/tests/json_encoding_test.rb b/tests/json_encoding_test.rb index d983e1264..29ae02e56 100644 --- a/tests/json_encoding_test.rb +++ b/tests/json_encoding_test.rb @@ -1,4 +1,5 @@ # encoding: utf-8 +#frozen_string_literal: false require 'test_helper' class JSONEncodingTest < Test::Unit::TestCase diff --git a/tests/json_ext_parser_test.rb b/tests/json_ext_parser_test.rb index ade97843e..c5a030ea8 100644 --- a/tests/json_ext_parser_test.rb +++ b/tests/json_ext_parser_test.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false require 'test_helper' class JSONExtParserTest < Test::Unit::TestCase diff --git a/tests/json_fixtures_test.rb b/tests/json_fixtures_test.rb index 041998302..01954fe70 100644 --- a/tests/json_fixtures_test.rb +++ b/tests/json_fixtures_test.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false require 'test_helper' class JSONFixturesTest < Test::Unit::TestCase diff --git a/tests/json_generic_object_test.rb b/tests/json_generic_object_test.rb index 171fdb853..82742dcd6 100644 --- a/tests/json_generic_object_test.rb +++ b/tests/json_generic_object_test.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false require 'test_helper' class JSONGenericObjectTest < Test::Unit::TestCase diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb index 1d1987b6d..5120f0963 100644 --- a/tests/json_parser_test.rb +++ b/tests/json_parser_test.rb @@ -1,4 +1,5 @@ # encoding: utf-8 +# frozen_string_literal: false require 'test_helper' require 'stringio' diff --git a/tests/json_string_matching_test.rb b/tests/json_string_matching_test.rb index 7fec8417f..5d55dc31b 100644 --- a/tests/json_string_matching_test.rb +++ b/tests/json_string_matching_test.rb @@ -1,3 +1,4 @@ +#frozen_string_literal: false require 'test_helper' require 'time' From 29c918ad9e16f3b67780a141353df05c029eb1eb Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 9 Jun 2016 17:42:22 +0200 Subject: [PATCH 153/312] Support 1.9 ruby's OpenStruct --- lib/json/generic_object.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/json/generic_object.rb b/lib/json/generic_object.rb index 6c8f03997..108309db2 100644 --- a/lib/json/generic_object.rb +++ b/lib/json/generic_object.rb @@ -48,6 +48,14 @@ def to_hash table end + def [](name) + __send__(name) + end unless method_defined?(:[]) + + def []=(name, value) + __send__("#{name}=", value) + end unless method_defined?(:[]=) + def |(other) self.class[other.to_hash.merge(to_hash)] end From e96a29e9bb261410a53b63acf26a9ec780b5199c Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 21 Jun 2016 10:52:31 +0200 Subject: [PATCH 154/312] Fix some merge problems --- ext/json/ext/parser/mkmf.log | 60 -------------------------------- ext/json/ext/parser/parser.c | 64 ----------------------------------- json.gemspec | Bin 5410 -> 4479 bytes json_pure.gemspec | 40 +++++++++++----------- lib/json/version.rb | 1 - 5 files changed, 20 insertions(+), 145 deletions(-) delete mode 100644 ext/json/ext/parser/mkmf.log diff --git a/ext/json/ext/parser/mkmf.log b/ext/json/ext/parser/mkmf.log deleted file mode 100644 index e725db5fc..000000000 --- a/ext/json/ext/parser/mkmf.log +++ /dev/null @@ -1,60 +0,0 @@ -have_func: checking for rb_enc_raise() in ruby.h... -------------------- yes - -"gcc -o conftest -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/x86_64-darwin15 -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/ruby/backward -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/readline/include -I/usr/local/opt/libksba/include -I/usr/local/opt/openssl/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/flori/.rvm/rubies/ruby-2.3.1/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -L. -fstack-protector -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -lruby.2.3.0 -lpthread -ldl -lobjc " -checked program was: -/* begin */ -1: #include "ruby.h" -2: -3: int main(int argc, char **argv) -4: { -5: return 0; -6: } -/* end */ - -"gcc -o conftest -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/x86_64-darwin15 -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/ruby/backward -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/readline/include -I/usr/local/opt/libksba/include -I/usr/local/opt/openssl/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/flori/.rvm/rubies/ruby-2.3.1/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -L. -fstack-protector -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -lruby.2.3.0 -lpthread -ldl -lobjc " -conftest.c:15:57: error: use of undeclared identifier 'rb_enc_raise' -int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_enc_raise; return !p; } - ^ -1 error generated. -checked program was: -/* begin */ - 1: #include "ruby.h" - 2: - 3: #include - 4: - 5: /*top*/ - 6: extern int t(void); - 7: int main(int argc, char **argv) - 8: { - 9: if (argc > 1000000) { -10: printf("%p", &t); -11: } -12: -13: return 0; -14: } -15: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_enc_raise; return !p; } -/* end */ - -"gcc -o conftest -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/x86_64-darwin15 -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0/ruby/backward -I/Users/flori/.rvm/rubies/ruby-2.3.1/include/ruby-2.3.0 -I. -I/usr/local/opt/libyaml/include -I/usr/local/opt/readline/include -I/usr/local/opt/libksba/include -I/usr/local/opt/openssl/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens -fno-common -pipe conftest.c -L. -L/Users/flori/.rvm/rubies/ruby-2.3.1/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -L. -fstack-protector -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -lruby.2.3.0 -lpthread -ldl -lobjc " -checked program was: -/* begin */ - 1: #include "ruby.h" - 2: - 3: #include - 4: - 5: /*top*/ - 6: extern int t(void); - 7: int main(int argc, char **argv) - 8: { - 9: if (argc > 1000000) { -10: printf("%p", &t); -11: } -12: -13: return 0; -14: } -15: extern void rb_enc_raise(); -16: int t(void) { rb_enc_raise(); return 0; } -/* end */ - --------------------- - diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index f3e250273..a65d17d96 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1810,15 +1810,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c -<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 1814 "parser.c" -======= -#line 1801 "parser.c" ->>>>>>> Exception encoding -======= -#line 1809 "parser.c" ->>>>>>> Optional hash in rb_scan_args enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1826,15 +1818,7 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; -<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c -<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 722 "parser.rl" -======= -#line 709 "parser.rl" ->>>>>>> Exception encoding -======= -#line 717 "parser.rl" ->>>>>>> Optional hash in rb_scan_args /* @@ -1851,40 +1835,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c -<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 1839 "parser.c" -======= -#line 1826 "parser.c" ->>>>>>> Exception encoding -======= -#line 1834 "parser.c" ->>>>>>> Optional hash in rb_scan_args { cs = JSON_start; } -<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c -<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 738 "parser.rl" p = json->source; pe = p + json->len; #line 1848 "parser.c" -======= -#line 725 "parser.rl" - p = json->source; - pe = p + json->len; - -#line 1835 "parser.c" ->>>>>>> Exception encoding -======= -#line 733 "parser.rl" - p = json->source; - pe = p + json->len; - -#line 1843 "parser.c" ->>>>>>> Optional hash in rb_scan_args { if ( p == pe ) goto _test_eof; @@ -1918,15 +1878,7 @@ case 1: cs = 0; goto _out; tr2: -<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c -<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 714 "parser.rl" -======= -#line 701 "parser.rl" ->>>>>>> Exception encoding -======= -#line 709 "parser.rl" ->>>>>>> Optional hash in rb_scan_args { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1936,15 +1888,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c -<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 1892 "parser.c" -======= -#line 1879 "parser.c" ->>>>>>> Exception encoding -======= -#line 1887 "parser.c" ->>>>>>> Optional hash in rb_scan_args switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2033,15 +1977,7 @@ case 9: _out: {} } -<<<<<<< 066bc5c70082f719951f398f4e20894571f8986c -<<<<<<< 2e06c964fceb550203659db23971459bc9d35054 #line 741 "parser.rl" -======= -#line 728 "parser.rl" ->>>>>>> Exception encoding -======= -#line 736 "parser.rl" ->>>>>>> Optional hash in rb_scan_args if (cs >= JSON_first_final && p == pe) { return result; diff --git a/json.gemspec b/json.gemspec index 71982d956bad20f0888f738dd5cc986a19b4fe59..54bae4d5e5f70d5ba93060abe01210e28b39c059 100644 GIT binary patch literal 4479 zcmb7I+iu)85bd+Sg4m!)Tx2DC8|PxwX>)O07fn)l)4UXcz?DY3v?Wp@DQ7nb`t6+| zCGAb3Q^2vMIYZ7>L!R7YZx4(>5y>)9#0HcGNdbQB#iUC&mm z5VH=0rHu)X>0u5MG`C9ATdHIp>Ddok8WqD~jQjv?4TcKnm;S0+Y z`)0l!FlHjjOJHYgM7Bpxatqp^A_<+ZqXQ?_@VOQmvV>fpLurz=qBC>l6-tnnj64`U zKVwIuLnd-Gqrp^4W{Fk5veUt>&NeM26}Jn6Zu~RCM2$WACHe7k0-}Is0>W1MMW8)z&9v z$wdL)>ecy+*Kg0GGHaC9NEBNz*0|rv0*VSWwicO)=E91(R2tkH?s_Xsv?>dFef9f` zcNgbVdc;!GcJ%1YjHz?R*VGkJ$@NX9zQ{F7PLL|Ufp*!)^Q-CQ`*$S9YH@6FPU(+a z2ev{XGgw9o>+L(eN-L}Esv=FdSn#>#rHP{(fQlqriOgqpp5rId{EZfS8tZywP=R!g zZf&tvKyjP*T{~-~?kP$Gw$@tv9yP@uaOcj}h#L+6r^kzJe9(TgUc1_FW@IA=LK@49 zqUoM%e#>K{)Aa~@xw7!5F!lp}oCZfCHX12WV)m6U+IjaqI&T3-KxV#2bqe}cq}VWb zTb|;#A5whpW{0@~9uDO%H<$w!8wH=-{Zx4PZpW``X+;T_GFJg(Q>$@0y@tCA;PuYw z>|2=P@amJ(nJ^?zD2aU_EK_hL?*o;wx=w8$gzY}>-4M@nJbe0t(lCc*)wkWS zA+suHsy9V_Az|7|tc#!ZT|)8O?h&mAYNzOimPivdyN3O^U3GW1CfWKPvunkn?U-@r zPiLyRRWvI!;0(t*6_{A(>67D=XOUf6>N9_k9c&E;1~=X<5#8w$9O`(t#0UB)oA26xpAPn; zDG}0w&Up$0YAvxEf|nKv1CgQug?3U5z}>Yhgm)8gKq=?|j&eMUlakwXK@WS`Ai?&f z+$vR=I1_mu8FyRrg1r9vwauf`z^HL-lE|~9g({)qbH{`h)>fx+?6?YD@)z|i!j!w? z*K?KvuSn9g+yU?L%`T2rD1Yy9G;BP!!uq@aHfY3-F%xkVj;h zCs9MwOkE;}SP{8$7B07mS!cs>L6@&Pxy>h{ulpR7t}7iW?x?I?fJAj7#{CLs>=Etf zc66-wqi4&G@p^%$H-`-A@1Dl};|MwR{X^CnB2)N*BpKX7p(-Mw_)K&J8-DfR$IriL zZtv>+QD> zpe$L6Es4qH#UUO7AOHdcp0M#xV+L6$BazKdSYhJvD_Yxo!n7%7C+tScj7_`)?|`Xd zwql8x)ihWdpXfe)m_r7N8>#5OP-d~GWzJshrR9*5;(>}}7{nrhQkARoH}5{2dui0hZUCNdKpSm;2Mb7YP#B;U8Wr^B z!iae$RefYyL{WD_d#f~QK;QoH=Htcrw6TIwM4}oir9xv0(eVw%otJWT8_92V#3K7G zt!a(l!UJAk&abAIpFTFYV_0y!XPo@(HLn3Our!fHu=EzDrMIQzN*ZZaIqhq56nw6D zs(tSkAa4*_j*DkS9OE5c|MeDKz)dtnkV96x1@&t&+~9EefxEl0^)4?QR$v3})OH<@ z{i?bKt-l7Af4Vhn!-jNQb5qSYY+7>Lb|TY;CrLZXZ}=VewF)a5Nb6P^S9lg*p@3b@m0|F(5&SdBHV z<)Urdl_=-4T@{%TDO_f;9M)iJ6lU#r;ONE@eoocj#q0kVk!<_VCOGtvM}-xub~A90 z*0CJqg@PS4tdll0+fiGs`aFvKnV3iTI7s<}&~AZ3NvUz!!zRQ`-$SOtJ3tP|F+CVq zhF~MD2P3snMQC~ucrE9BQt-`%kAPldD44@C?~yU6gkGgH*=O$_Q=ltSjDuFOt$l?l ztedh`i|TDQr;9L&uJ{4*;*3ZcHeg#+|@ktHZS8@3A z@WpG-EKTEDln;?uEDdU*{TQEJhX)U<_%6_)3uxj3`q>3^@c~K}0N-9Wzv{uz?$oajMYU@~-7=PiAn0 zbL<^eysXl?NU@7v(U8JQziiJr9?G|StPfo00M|4y+8+1NySAQ2)x#sRfDGX@k=hM7 zWk= 0".freeze) if s.respond_to? :required_rubygems_version= - s.require_paths = ["lib".freeze] - s.authors = ["Florian Frank".freeze] + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] + s.authors = ["Florian Frank"] s.date = "2016-06-21" - s.description = "This is a JSON implementation in pure Ruby.".freeze - s.email = "flori@ping.de".freeze - s.extra_rdoc_files = ["README.md".freeze] - s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES".freeze, "Gemfile".freeze, "README-json-jruby.markdown".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] - s.homepage = "http://flori.github.com/json".freeze - s.licenses = ["Ruby".freeze] - s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] - s.rubygems_version = "2.6.4".freeze - s.summary = "JSON Implementation for Ruby".freeze - s.test_files = ["./tests/test_helper.rb".freeze] + s.description = "This is a JSON implementation in pure Ruby." + s.email = "flori@ping.de" + s.extra_rdoc_files = ["README.md"] + s.files = ["./tests/test_helper.rb", ".gitignore", ".travis.yml", "CHANGES", "Gemfile", "README-json-jruby.markdown", "README.md", "Rakefile", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "references/rfc7159.txt", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/obsolete_fail1.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/json_addition_test.rb", "tests/json_common_interface_test.rb", "tests/json_encoding_test.rb", "tests/json_ext_parser_test.rb", "tests/json_fixtures_test.rb", "tests/json_generator_test.rb", "tests/json_generic_object_test.rb", "tests/json_parser_test.rb", "tests/json_string_matching_test.rb", "tests/test_helper.rb", "tools/diff.sh", "tools/fuzz.rb", "tools/server.rb"] + s.homepage = "http://flori.github.com/json" + s.licenses = ["Ruby"] + s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.md"] + s.rubygems_version = "2.5.1" + s.summary = "JSON Implementation for Ruby" + s.test_files = ["./tests/test_helper.rb"] if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_development_dependency(%q.freeze, [">= 0"]) - s.add_development_dependency(%q.freeze, ["~> 2.0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 2.0"]) else - s.add_dependency(%q.freeze, [">= 0"]) - s.add_dependency(%q.freeze, ["~> 2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end else - s.add_dependency(%q.freeze, [">= 0"]) - s.add_dependency(%q.freeze, ["~> 2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end end diff --git a/lib/json/version.rb b/lib/json/version.rb index b4d1b3b5a..b91ccd708 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,4 +1,3 @@ -#frozen_string_literal: false module JSON # JSON version VERSION = '2.0.0' From 734cf19249cd64c4f732b55bbba28a09e0f48942 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 21 Jun 2016 12:41:32 +0200 Subject: [PATCH 155/312] Make it interactive --- tools/diff.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/diff.sh b/tools/diff.sh index 3fd582955..89385b038 100755 --- a/tools/diff.sh +++ b/tools/diff.sh @@ -4,8 +4,15 @@ files=`find ext -name '*.[ch]' -o -name parser.rl` for f in $files do - echo $f b=`basename $f` g=`find ../ruby/ext/json -name $b` - diff -u $f $g | less + d=`diff -u $f $g` + test -z "$d" && continue + echo "$d" + read -p "Edit diff of $b? " a + case $a in + [yY]*) + vimdiff $f $g + ;; + esac done From bd325ab769b20a54b5a94873bcdd9df1881eb00d Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 21 Jun 2016 15:03:34 +0200 Subject: [PATCH 156/312] Add ruby version requirement to gemspec --- Rakefile | 1 + json.gemspec | Bin 4479 -> 4538 bytes 2 files changed, 1 insertion(+) diff --git a/Rakefile b/Rakefile index 4448d2e67..093db66f5 100644 --- a/Rakefile +++ b/Rakefile @@ -132,6 +132,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.email = "flori@ping.de" s.homepage = "http://flori.github.com/#{PKG_NAME}" s.license = 'Ruby' + s.required_ruby_version = '~> 2.0' end desc 'Creates a json.gemspec file' diff --git a/json.gemspec b/json.gemspec index 54bae4d5e5f70d5ba93060abe01210e28b39c059..3a22e8bdd71b261a32c6742a1049ec1c789b37ff 100644 GIT binary patch delta 37 scmeybv`cw|8b42JVQFSjYD#=jX;S6H4~iUhb_zy%21=Tn75L+s01o&JqyPW_ delta 12 Tcmdm`{9kE<8vo`*{zxVOA~ghJ From 836412021432846b7fadfb63ecf80882fdf5ae9c Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 21 Jun 2016 15:04:04 +0200 Subject: [PATCH 157/312] Stop testing on 1.9.3 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a8f907136..49f95293b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,6 @@ language: ruby # Specify which ruby versions you wish to run your tests on, each version will be used rvm: - - 1.9.3 - 2.0.0 - 2.1 - 2.2 From 2bc78c62afa5534bec1cfa14511f2ad37320f5ee Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Wed, 22 Jun 2016 09:59:49 +0200 Subject: [PATCH 158/312] And stay there --- Rakefile | 1 + json.gemspec | Bin 4538 -> 4538 bytes json_pure.gemspec | 2 +- lib/json/version.rb | 1 + tests/json_parser_test.rb | 1 - 5 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Rakefile b/Rakefile index 093db66f5..958dfa682 100644 --- a/Rakefile +++ b/Rakefile @@ -157,6 +157,7 @@ task :version do puts m File.open(File.join('lib', 'json', 'version.rb'), 'w') do |v| v.puts <= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] - s.date = "2016-06-21" + s.date = "2016-06-22" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.md"] diff --git a/lib/json/version.rb b/lib/json/version.rb index b91ccd708..520a8ad3b 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: false module JSON # JSON version VERSION = '2.0.0' diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb index 5120f0963..c1c2779b9 100644 --- a/tests/json_parser_test.rb +++ b/tests/json_parser_test.rb @@ -1,6 +1,5 @@ # encoding: utf-8 # frozen_string_literal: false - require 'test_helper' require 'stringio' require 'tempfile' From 1c2901905c938ffd19620cc6a06cbb2b34d8ba05 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 1 Jul 2016 11:26:43 +0200 Subject: [PATCH 159/312] Add to CHANGES --- CHANGES | 7 +++++-- json.gemspec | Bin 4538 -> 5476 bytes json_pure.gemspec | 42 +++++++++++++++++++++--------------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/CHANGES b/CHANGES index cb0019e2a..925b13034 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ -2015-09-11 (1.8.5) +2015-09-11 (2.0.0) + * Now complies to newest JSON RFC 7159. + * Implements compatibiliy to ruby 2.4 integer unification. + * Drops support for old rubies whose life has ended, that is rubies < 2.0. + Also see https://www.ruby-lang.org/en/news/2014/07/01/eol-for-1-8-7-and-1-9-2/ * There were still some mentions of dual GPL licensing in the source, but JSON has just the Ruby license that itself includes an explicit dual-licensing clause that allows covered software to be distributed under the terms of @@ -6,7 +10,6 @@ however a GPL compatible license according to the Free Software Foundation. I changed these mentions to be consistent with the Ruby license setting in the gemspec files which were already correct now. ----------- (1.8.4) Skipped. 2015-06-01 (1.8.3) * Fix potential memory leak, thx to nobu. 2015-01-08 (1.8.2) diff --git a/json.gemspec b/json.gemspec index 452a2ac378061f4b1ae6119baa857620f333c230..595d3e07225c172a2b39272575f20e3c0e17db57 100644 GIT binary patch literal 5476 zcmb7IZFAc;4BqGb3Z8qrHoIDKyfkTZOSi5~v+mYp7kB-#>*;6-vYAMtN>Zua>+QD> zpe$L6Es4$L#UUO7AOHdc9sieIi5EK201rNjoSP>LbFx;K3NDa%u=e7 z_%@MB@Ql4xJiBYdB5v$ar<0?T@#J(oIU3pR5$I5foUB8q{je08;WuZ0&aSVRNb>~f zG}e5K6XAxuhyH-fnn+~qwO7fqEFtA0A!aeD^IMJq;YHAfRNG6vTi)I0|7!D7Hfmva zBB2AgiHV9@S`IlW9;ir$K`as|Rk^u%_2&JBmqu;u7U1~?w9)o=u!JNBg#lWjQ9*AZ zj96q+)kmg96m>7Ow@#A=^z|RFt}ZWTjTMX{64h8K6&h2Bj&CXMyp*fENPej!7TND; zO>6uP9`O2jaWi{&ebwNOVZrg9aq_d*yavd?(nJ=)%3GS2-j3 z_PslRyg_I=E}j>0jCXkR*IRZ0x6u$m4q5FM)UU;Gi^Jsy?(W9cyS#8%fi1XG+f6+7 ztLhrG{svh7>DI6f8`5pVO*P}NX~|vNiA)=wB<(1_<@emzD%|Gn-`58I654#g+q~E~{Ms9nklH2`|#$v1116UW6E@&g#rC;W^;1ZQj&3z@1L}x2;>lYHV;V z7wy`vL^+@BrpSy);awKXVGU+RVb*>Fj&3aB7gYUSy#9|7$*%uwfaow2!DDw zm?0}z(2yA{Xvhu(8VXE{ago*$1k^1ASVytj!4H&X+UcuIJQh`E?m%P)RLn!@M^{sX z0o2N1TTFw1eq5Cv`%(4V-T_vZi+-$&a#%0%ofV|qgiHF+Wkp)w+iV&s6YWPLjy>Ic z`IqZ)@%8Hir&v514J%HAQZ~d(nL^GNc22M~CO`9i+rm>vyDa7&y3xL=suE`yCd$aGds6c71a^=0qU$8#6OEj92S)TV zuIE|x`OFeBgwsrGKj54l6F8?EnA( literal 4538 zcmb7HZExE)5Z>qf3c|(EW~ima>ua!d>r0w-Slc1)`ei5tS~}TGBvK`*)Gmts_T7<^ z{3g*|&@|LNN8THG%Ae7PLV{5;|W;M^3Eab1gJv3AsLp(j;p|XXeT)lprk`xi@-t z&Q3Z$crtjY|QC0ikpw9`IbTutA+e@9}h7RN2lDgBY# zfvr%;43^QtdizeV(#k5ksz}pK7JROGY2xSxpd!guBJ)|D=XgY#ztLh(V_lC7Dv-|6 zttHk9C~otzgDuXjOr zSFlijTTyIe-kp5RZAAA0-ZHMbDBS%{s#?RQ5F5JND$Vw3KVzO{@l4D!ys%2%Zmumf zRn#n&eG^k`UVU=96NcmoC9w~LWeTq3eV{T{*QxD;aJ$cY7sUGP=B!NSL+~>*9NTmry+0J)(6(?G#zeSG@xX=Im{_L;xPavK%{6uq3sj{aQ7?=;avwDPzpMLtsL*-q~tbT&|ohcB-nnG zTcrvUXClud<6diCkk?UWSq z{`-vR^61#p!hPO}1odHb>Z34qiS%Pdyv#ZGW}DM>?zy#Gst?klPsDup=_|c-IzHXS zU>6`!oj7&B!Z~|D>$w#jVgBfewj;}4;F-}eL*~4varZRBT--foogp%XXDi9z77A4n zf5kB|89Xbidp~~uMI-Hcb{`3}qvD?^kMwhB8f9l(OJUvIrU=b!C=Bc@^FJ(Zss^pd Y42^WQT8B5M_r}(zIBW+qbwt1a0Xen{LI3~& diff --git a/json_pure.gemspec b/json_pure.gemspec index 2ea9b44d6..880fdcfaa 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -2,36 +2,36 @@ # stub: json_pure 2.0.0 ruby lib Gem::Specification.new do |s| - s.name = "json_pure" + s.name = "json_pure".freeze s.version = "2.0.0" - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.require_paths = ["lib"] - s.authors = ["Florian Frank"] - s.date = "2016-06-22" - s.description = "This is a JSON implementation in pure Ruby." - s.email = "flori@ping.de" - s.extra_rdoc_files = ["README.md"] - s.files = ["./tests/test_helper.rb", ".gitignore", ".travis.yml", "CHANGES", "Gemfile", "README-json-jruby.markdown", "README.md", "Rakefile", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json-java.gemspec", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "references/rfc7159.txt", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/obsolete_fail1.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/json_addition_test.rb", "tests/json_common_interface_test.rb", "tests/json_encoding_test.rb", "tests/json_ext_parser_test.rb", "tests/json_fixtures_test.rb", "tests/json_generator_test.rb", "tests/json_generic_object_test.rb", "tests/json_parser_test.rb", "tests/json_string_matching_test.rb", "tests/test_helper.rb", "tools/diff.sh", "tools/fuzz.rb", "tools/server.rb"] - s.homepage = "http://flori.github.com/json" - s.licenses = ["Ruby"] - s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.md"] - s.rubygems_version = "2.5.1" - s.summary = "JSON Implementation for Ruby" - s.test_files = ["./tests/test_helper.rb"] + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["Florian Frank".freeze] + s.date = "2016-07-01" + s.description = "This is a JSON implementation in pure Ruby.".freeze + s.email = "flori@ping.de".freeze + s.extra_rdoc_files = ["README.md".freeze] + s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES".freeze, "Gemfile".freeze, "README-json-jruby.markdown".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] + s.homepage = "http://flori.github.com/json".freeze + s.licenses = ["Ruby".freeze] + s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] + s.rubygems_version = "2.6.4".freeze + s.summary = "JSON Implementation for Ruby".freeze + s.test_files = ["./tests/test_helper.rb".freeze] if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, ["~> 2.0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, ["~> 2.0"]) else - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 2.0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, ["~> 2.0"]) end else - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 2.0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, ["~> 2.0"]) end end From d5115edb0ea309620e09c9970a5add4bbb2abac4 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Wed, 23 Dec 2015 21:55:42 +1100 Subject: [PATCH 160/312] RB_GC_GUARD to protect from premature GC https://github.com/ruby/ruby/blob/trunk/doc/extension.rdoc#appendix-e-rb_gc_guard-to-protect-from-premature-gc --- ext/json/ext/generator/generator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 8cc0c270b..2b56721b2 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -222,6 +222,7 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string) unicode_escape_to_buffer(buffer, buf, (UTF16)((ch & halfMask) + UNI_SUR_LOW_START)); } } + RB_GC_GUARD(string); } /* Converts string to a JSON string in FBuffer buffer, where only the From 4219871ff5ac9752fce7b8b23296e9aeae8e42ff Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 1 Jul 2016 16:00:10 +0200 Subject: [PATCH 161/312] Stores current nesting on stack --- ext/json/ext/parser/parser.c | 127 ++++++++++++++++------------------ ext/json/ext/parser/parser.h | 7 +- ext/json/ext/parser/parser.rl | 29 ++++---- 3 files changed, 76 insertions(+), 87 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index a65d17d96..975a26769 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -113,14 +113,14 @@ enum {JSON_object_en_main = 1}; #line 165 "parser.rl" -static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result) +static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) { int cs = EVIL; VALUE last_name = Qnil; VALUE object_class = json->object_class; - if (json->max_nesting && json->current_nesting > json->max_nesting) { - rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting); + if (json->max_nesting && current_nesting > json->max_nesting) { + rb_raise(eNestingError, "nesting of %d is too deep", current_nesting); } *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class); @@ -244,7 +244,7 @@ case 8: #line 132 "parser.rl" { VALUE v = Qnil; - char *np = JSON_parse_value(json, p, pe, &v); + char *np = JSON_parse_value(json, p, pe, &v, current_nesting); if (np == NULL) { p--; {p++; cs = 9; goto _out;} } else { @@ -488,10 +488,10 @@ enum {JSON_value_error = 0}; enum {JSON_value_en_main = 1}; -#line 285 "parser.rl" +#line 281 "parser.rl" -static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result) +static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) { int cs = EVIL; @@ -501,7 +501,7 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul cs = JSON_value_start; } -#line 292 "parser.rl" +#line 288 "parser.rl" #line 507 "parser.c" { @@ -567,19 +567,15 @@ cs = 0; #line 256 "parser.rl" { char *np; - json->current_nesting++; - np = JSON_parse_array(json, p, pe, result); - json->current_nesting--; + np = JSON_parse_array(json, p, pe, result, current_nesting + 1); if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } goto st29; tr11: -#line 264 "parser.rl" +#line 262 "parser.rl" { char *np; - json->current_nesting++; - np = JSON_parse_object(json, p, pe, result); - json->current_nesting--; + np = JSON_parse_object(json, p, pe, result, current_nesting + 1); if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } goto st29; @@ -625,9 +621,9 @@ cs = 0; if ( ++p == pe ) goto _test_eof29; case 29: -#line 272 "parser.rl" +#line 268 "parser.rl" { p--; {p++; cs = 29; goto _out;} } -#line 631 "parser.c" +#line 627 "parser.c" switch( (*p) ) { case 13: goto st29; case 32: goto st29; @@ -868,7 +864,7 @@ case 28: _out: {} } -#line 293 "parser.rl" +#line 289 "parser.rl" if (cs >= JSON_value_first_final) { return p; @@ -878,7 +874,7 @@ case 28: } -#line 882 "parser.c" +#line 878 "parser.c" enum {JSON_integer_start = 1}; enum {JSON_integer_first_final = 3}; enum {JSON_integer_error = 0}; @@ -886,7 +882,7 @@ enum {JSON_integer_error = 0}; enum {JSON_integer_en_main = 1}; -#line 309 "parser.rl" +#line 305 "parser.rl" static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -894,15 +890,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res int cs = EVIL; -#line 898 "parser.c" +#line 894 "parser.c" { cs = JSON_integer_start; } -#line 316 "parser.rl" +#line 312 "parser.rl" json->memo = p; -#line 906 "parser.c" +#line 902 "parser.c" { if ( p == pe ) goto _test_eof; @@ -936,14 +932,14 @@ case 3: goto st0; goto tr4; tr4: -#line 306 "parser.rl" +#line 302 "parser.rl" { p--; {p++; cs = 4; goto _out;} } goto st4; st4: if ( ++p == pe ) goto _test_eof4; case 4: -#line 947 "parser.c" +#line 943 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -962,7 +958,7 @@ case 5: _out: {} } -#line 318 "parser.rl" +#line 314 "parser.rl" if (cs >= JSON_integer_first_final) { long len = p - json->memo; @@ -977,7 +973,7 @@ case 5: } -#line 981 "parser.c" +#line 977 "parser.c" enum {JSON_float_start = 1}; enum {JSON_float_first_final = 8}; enum {JSON_float_error = 0}; @@ -985,7 +981,7 @@ enum {JSON_float_error = 0}; enum {JSON_float_en_main = 1}; -#line 343 "parser.rl" +#line 339 "parser.rl" static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -993,15 +989,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 997 "parser.c" +#line 993 "parser.c" { cs = JSON_float_start; } -#line 350 "parser.rl" +#line 346 "parser.rl" json->memo = p; -#line 1005 "parser.c" +#line 1001 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1059,14 +1055,14 @@ case 8: goto st0; goto tr9; tr9: -#line 337 "parser.rl" +#line 333 "parser.rl" { p--; {p++; cs = 9; goto _out;} } goto st9; st9: if ( ++p == pe ) goto _test_eof9; case 9: -#line 1070 "parser.c" +#line 1066 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -1127,7 +1123,7 @@ case 7: _out: {} } -#line 352 "parser.rl" +#line 348 "parser.rl" if (cs >= JSON_float_first_final) { long len = p - json->memo; @@ -1143,7 +1139,7 @@ case 7: -#line 1147 "parser.c" +#line 1143 "parser.c" enum {JSON_array_start = 1}; enum {JSON_array_first_final = 17}; enum {JSON_array_error = 0}; @@ -1151,28 +1147,28 @@ enum {JSON_array_error = 0}; enum {JSON_array_en_main = 1}; -#line 395 "parser.rl" +#line 391 "parser.rl" -static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result) +static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) { int cs = EVIL; VALUE array_class = json->array_class; - if (json->max_nesting && json->current_nesting > json->max_nesting) { - rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting); + if (json->max_nesting && current_nesting > json->max_nesting) { + rb_raise(eNestingError, "nesting of %d is too deep", current_nesting); } *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); -#line 1169 "parser.c" +#line 1165 "parser.c" { cs = JSON_array_start; } -#line 408 "parser.rl" +#line 404 "parser.rl" -#line 1176 "parser.c" +#line 1172 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1211,10 +1207,10 @@ case 2: goto st2; goto st0; tr2: -#line 372 "parser.rl" +#line 368 "parser.rl" { VALUE v = Qnil; - char *np = JSON_parse_value(json, p, pe, &v); + char *np = JSON_parse_value(json, p, pe, &v, current_nesting); if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else { @@ -1231,7 +1227,7 @@ case 2: if ( ++p == pe ) goto _test_eof3; case 3: -#line 1235 "parser.c" +#line 1231 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -1331,14 +1327,14 @@ case 12: goto st3; goto st12; tr4: -#line 387 "parser.rl" +#line 383 "parser.rl" { p--; {p++; cs = 17; goto _out;} } goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: -#line 1342 "parser.c" +#line 1338 "parser.c" goto st0; st13: if ( ++p == pe ) @@ -1394,7 +1390,7 @@ case 16: _out: {} } -#line 409 "parser.rl" +#line 405 "parser.rl" if(cs >= JSON_array_first_final) { return p + 1; @@ -1475,7 +1471,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1479 "parser.c" +#line 1475 "parser.c" enum {JSON_string_start = 1}; enum {JSON_string_first_final = 8}; enum {JSON_string_error = 0}; @@ -1483,7 +1479,7 @@ enum {JSON_string_error = 0}; enum {JSON_string_en_main = 1}; -#line 508 "parser.rl" +#line 504 "parser.rl" static int @@ -1505,15 +1501,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = rb_str_buf_new(0); -#line 1509 "parser.c" +#line 1505 "parser.c" { cs = JSON_string_start; } -#line 529 "parser.rl" +#line 525 "parser.rl" json->memo = p; -#line 1517 "parser.c" +#line 1513 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1538,7 +1534,7 @@ case 2: goto st0; goto st2; tr2: -#line 494 "parser.rl" +#line 490 "parser.rl" { *result = json_string_unescape(*result, json->memo + 1, p); if (NIL_P(*result)) { @@ -1549,14 +1545,14 @@ case 2: {p = (( p + 1))-1;} } } -#line 505 "parser.rl" +#line 501 "parser.rl" { p--; {p++; cs = 8; goto _out;} } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: -#line 1560 "parser.c" +#line 1556 "parser.c" goto st0; st3: if ( ++p == pe ) @@ -1632,7 +1628,7 @@ case 7: _out: {} } -#line 531 "parser.rl" +#line 527 "parser.rl" if (json->create_additions && RTEST(match_string = json->match_string)) { VALUE klass; @@ -1801,7 +1797,6 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) json->array_class = Qnil; } source = convert_encoding(StringValue(source)); - json->current_nesting = 0; StringValue(source); json->len = RSTRING_LEN(source); json->source = RSTRING_PTR(source);; @@ -1810,7 +1805,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1814 "parser.c" +#line 1809 "parser.c" enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1818,7 +1813,7 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; -#line 722 "parser.rl" +#line 717 "parser.rl" /* @@ -1835,16 +1830,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -#line 1839 "parser.c" +#line 1834 "parser.c" { cs = JSON_start; } -#line 738 "parser.rl" +#line 733 "parser.rl" p = json->source; pe = p + json->len; -#line 1848 "parser.c" +#line 1843 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1878,9 +1873,9 @@ case 1: cs = 0; goto _out; tr2: -#line 714 "parser.rl" +#line 709 "parser.rl" { - char *np = JSON_parse_value(json, p, pe, &result); + char *np = JSON_parse_value(json, p, pe, &result, 0); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} } goto st10; @@ -1888,7 +1883,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1892 "parser.c" +#line 1887 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1977,7 +1972,7 @@ case 9: _out: {} } -#line 741 "parser.rl" +#line 736 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; diff --git a/ext/json/ext/parser/parser.h b/ext/json/ext/parser/parser.h index ec26e852b..1d4683196 100644 --- a/ext/json/ext/parser/parser.h +++ b/ext/json/ext/parser/parser.h @@ -34,7 +34,6 @@ typedef struct JSON_ParserStruct { char *memo; VALUE create_id; int max_nesting; - int current_nesting; int allow_nan; int parsing_name; int symbolize_names; @@ -57,11 +56,11 @@ typedef struct JSON_ParserStruct { static UTF32 unescape_unicode(const unsigned char *p); static int convert_UTF32_to_UTF8(char *buf, UTF32 ch); -static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result); -static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result); +static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting); +static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting); static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result); static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result); -static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result); +static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting); static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd); static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result); static VALUE convert_encoding(VALUE source); diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index eac3e6cf1..c67634b8b 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -131,7 +131,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, action parse_value { VALUE v = Qnil; - char *np = JSON_parse_value(json, fpc, pe, &v); + char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting); if (np == NULL) { fhold; fbreak; } else { @@ -164,14 +164,14 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, ) @exit; }%% -static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result) +static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) { int cs = EVIL; VALUE last_name = Qnil; VALUE object_class = json->object_class; - if (json->max_nesting && json->current_nesting > json->max_nesting) { - rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting); + if (json->max_nesting && current_nesting > json->max_nesting) { + rb_raise(eNestingError, "nesting of %d is too deep", current_nesting); } *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class); @@ -255,17 +255,13 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu action parse_array { char *np; - json->current_nesting++; - np = JSON_parse_array(json, fpc, pe, result); - json->current_nesting--; + np = JSON_parse_array(json, fpc, pe, result, current_nesting + 1); if (np == NULL) { fhold; fbreak; } else fexec np; } action parse_object { char *np; - json->current_nesting++; - np = JSON_parse_object(json, fpc, pe, result); - json->current_nesting--; + np = JSON_parse_object(json, fpc, pe, result, current_nesting + 1); if (np == NULL) { fhold; fbreak; } else fexec np; } @@ -284,7 +280,7 @@ main := ignore* ( ) ignore* %*exit; }%% -static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result) +static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) { int cs = EVIL; @@ -371,7 +367,7 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul action parse_value { VALUE v = Qnil; - char *np = JSON_parse_value(json, fpc, pe, &v); + char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting); if (np == NULL) { fhold; fbreak; } else { @@ -394,13 +390,13 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul end_array @exit; }%% -static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result) +static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) { int cs = EVIL; VALUE array_class = json->array_class; - if (json->max_nesting && json->current_nesting > json->max_nesting) { - rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting); + if (json->max_nesting && current_nesting > json->max_nesting) { + rb_raise(eNestingError, "nesting of %d is too deep", current_nesting); } *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); @@ -696,7 +692,6 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) json->array_class = Qnil; } source = convert_encoding(StringValue(source)); - json->current_nesting = 0; StringValue(source); json->len = RSTRING_LEN(source); json->source = RSTRING_PTR(source);; @@ -712,7 +707,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) include JSON_common; action parse_value { - char *np = JSON_parse_value(json, fpc, pe, &result); + char *np = JSON_parse_value(json, fpc, pe, &result, 0); if (np == NULL) { fhold; fbreak; } else fexec np; } From d72335c91f04e7eee2563e6f725a48ade3cce24d Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 1 Jul 2016 16:24:16 +0200 Subject: [PATCH 162/312] Add to CHANGES --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index 925b13034..1dd8082e9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2016-07-01 (2.0.1) + * Add RB_GC_GUARD to avoid possible GC problem via Pete Johns. + * Store current_nesting on stack by Aaron Patterson. 2015-09-11 (2.0.0) * Now complies to newest JSON RFC 7159. * Implements compatibiliy to ruby 2.4 integer unification. From 65297fbae1e92e26fdde886fe156bac322977db2 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 1 Jul 2016 17:17:39 +0200 Subject: [PATCH 163/312] Fix problem when Parser is defined on top level See flori/json#287 --- lib/json/common.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/common.rb b/lib/json/common.rb index b53041b98..7cc852916 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -25,7 +25,7 @@ def [](object, opts = {}) # Set the JSON parser class _parser_ to be used by JSON. def parser=(parser) # :nodoc: @parser = parser - remove_const :Parser if const_defined?(:Parser, true) + remove_const :Parser if const_defined?(:Parser, false) const_set :Parser, parser end From 08f638d44e09450dde0f4eb54c669c54e6082229 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 1 Jul 2016 17:22:35 +0200 Subject: [PATCH 164/312] Use markdown for CHANGES --- CHANGES => CHANGES.md | 247 ++++++++++++++++++++++++++---------------- 1 file changed, 154 insertions(+), 93 deletions(-) rename CHANGES => CHANGES.md (77%) diff --git a/CHANGES b/CHANGES.md similarity index 77% rename from CHANGES rename to CHANGES.md index 1dd8082e9..89326f3c1 100644 --- a/CHANGES +++ b/CHANGES.md @@ -1,7 +1,12 @@ -2016-07-01 (2.0.1) - * Add RB_GC_GUARD to avoid possible GC problem via Pete Johns. - * Store current_nesting on stack by Aaron Patterson. -2015-09-11 (2.0.0) +# Changes + +## 2016-07-01 (2.0.1) + * Fix problem when requiring json\_pure and Parser constant was defiend top + level. + * Add `RB_GC_GUARD` to avoid possible GC problem via Pete Johns. + * Store `current_nesting` on stack by Aaron Patterson. + +## 2015-09-11 (2.0.0) * Now complies to newest JSON RFC 7159. * Implements compatibiliy to ruby 2.4 integer unification. * Drops support for old rubies whose life has ended, that is rubies < 2.0. @@ -13,97 +18,119 @@ however a GPL compatible license according to the Free Software Foundation. I changed these mentions to be consistent with the Ruby license setting in the gemspec files which were already correct now. -2015-06-01 (1.8.3) + +## 2015-06-01 (1.8.3) * Fix potential memory leak, thx to nobu. -2015-01-08 (1.8.2) + +## 2015-01-08 (1.8.2) * Some performance improvements by Vipul A M . * Fix by Jason R. Clark to avoid mutation of - JSON.dump_default_options. + `JSON.dump_default_options`. * More tests by Michael Mac-Vicar and fixing - space_before accessor in generator. + `space_before` accessor in generator. * Performance on Jruby improvemed by Ben Browning . * Some fixes to be compatible with the new Ruby 2.2 by Zachary Scott and SHIBATA Hiroshi . -2013-05-13 (1.8.1) + +## 2013-05-13 (1.8.1) * Remove Rubinius exception since transcoding should be working now. -2013-05-13 (1.8.0) + +## 2013-05-13 (1.8.0) * Fix https://github.com/flori/json/issues/162 reported by Marc-Andre Lafortune . Thanks! * Applied patches by Yui NARUSE to suppress warning with -Wchar-subscripts and better validate UTF-8 strings. * Applied patch by ginriki@github to remove unnecessary if. - * Add load/dump interface to JSON::GenericObject to make - serialize :some_attribute, JSON::GenericObject - work in Rails active models for convenient SomeModel#some_attribute.foo.bar + * Add load/dump interface to `JSON::GenericObject` to make + serialize :some_attribute, `JSON::GenericObject` + work in Rails active models for convenient `SomeModel#some_attribute.foo.bar` access to serialised JSON data. -2013-02-04 (1.7.7) + +## 2013-02-04 (1.7.7) * Security fix for JSON create_additions default value and - JSON::GenericObject. It should not be possible to create additions unless + `JSON::GenericObject`. It should not be possible to create additions unless explicitely requested by setting the create_additions argument to true or - using the JSON.load/dump interface. If JSON::GenericObject is supposed to + using the JSON.load/dump interface. If `JSON::GenericObject` is supposed to be automatically deserialised, this has to be explicitely enabled by setting - JSON::GenericObject.json_creatable = true + JSON::GenericObject.json_creatable = true as well. * Remove useless assert in fbuffer implementation. * Apply patch attached to https://github.com/flori/json/issues#issue/155 provided by John Shahid , Thx! * Add license information to rubygems spec data, reported by Jordi Massaguer Pla . * Improve documentation, thx to Zachary Scott . -2012-11-29 (1.7.6) - * Add GeneratorState#merge alias for JRuby, fix state accessor methods. Thx to + +## 2012-11-29 (1.7.6) + * Add `GeneratorState#merge` alias for JRuby, fix state accessor methods. Thx to jvshahid@github. * Increase hash likeness of state objects. -2012-08-17 (1.7.5) + +## 2012-08-17 (1.7.5) * Fix compilation of extension on older rubies. -2012-07-26 (1.7.4) + +## 2012-07-26 (1.7.4) * Fix compilation problem on AIX, see https://github.com/flori/json/issues/142 -2012-05-12 (1.7.3) + +## 2012-05-12 (1.7.3) * Work around Rubinius encoding issues using iconv for conversion instead. -2012-05-11 (1.7.2) + +## 2012-05-11 (1.7.2) * Fix some encoding issues, that cause problems for the pure and the extension variant in jruby 1.9 mode. -2012-04-28 (1.7.1) + +## 2012-04-28 (1.7.1) * Some small fixes for building -2012-04-28 (1.7.0) - * Add JSON::GenericObject for method access to objects transmitted via JSON. -2012-04-27 (1.6.7) + +## 2012-04-28 (1.7.0) + * Add `JSON::GenericObject` for method access to objects transmitted via JSON. + +## 2012-04-27 (1.6.7) * Fix possible crash when trying to parse nil value. -2012-02-11 (1.6.6) + +## 2012-02-11 (1.6.6) * Propagate src encoding to values made from it (fixes 1.9 mode converting everything to ascii-8bit; harmless for 1.8 mode too) (Thomas E. Enebo ), should fix https://github.com/flori/json/issues#issue/119. * Fix https://github.com/flori/json/issues#issue/124 Thx to Jason Hutchens. * Fix https://github.com/flori/json/issues#issue/117 -2012-01-15 (1.6.5) + +## 2012-01-15 (1.6.5) * Vit Ondruch reported a bug that shows up when using optimisation under GCC 4.7. Thx to him, Bohuslav Kabrda and Yui NARUSE for debugging and developing a patch fix. -2011-12-24 (1.6.4) + +## 2011-12-24 (1.6.4) * Patches that improve speed on JRuby contributed by Charles Oliver Nutter . - * Support object_class/array_class with duck typed hash/array. -2011-12-01 (1.6.3) - * Let JSON.load('') return nil as well to make mysql text columns (default to - '') work better for serialization. -2011-11-21 (1.6.2) + * Support `object_class`/`array_class` with duck typed hash/array. + +## 2011-12-01 (1.6.3) + * Let `JSON.load('')` return nil as well to make mysql text columns (default to + `''`) work better for serialization. + +## 2011-11-21 (1.6.2) * Add support for OpenStruct and BigDecimal. - * Fix bug when parsing nil in quirks_mode. + * Fix bug when parsing nil in `quirks_mode`. * Make JSON.dump and JSON.load methods better cooperate with Rails' serialize - method. Just use: serialize :value, JSON + method. Just use: + serialize :value, JSON * Fix bug with time serialization concerning nanoseconds. Thanks for the patch go to Josh Partlow (jpartlow@github). * Improve parsing speed for JSON numbers (integers and floats) in a similar way to what Evan Phoenix suggested in: https://github.com/flori/json/pull/103 -2011-09-18 (1.6.1) + +## 2011-09-18 (1.6.1) * Using -target 1.5 to force Java bits to compile with 1.5. -2011-09-12 (1.6.0) + +## 2011-09-12 (1.6.0) * Extract utilities (prettifier and GUI-editor) in its own gem json-utils. * Split json/add/core into different files for classes to be serialised. -2011-08-31 (1.5.4) + +## 2011-08-31 (1.5.4) * Fix memory leak when used from multiple JRuby. (Patch by jfirebaugh@github). * Apply patch by Eric Wong that fixes garbage collection problem @@ -111,42 +138,50 @@ * Add :quirks_mode option to parser and generator. * Add support for Rational and Complex number additions via json/add/complex and json/add/rational requires. -2011-06-20 (1.5.3) + +## 2011-06-20 (1.5.3) * Alias State#configure method as State#merge to increase duck type synonymy with Hash. - * Add as_json methods in json/add/core, so rails can create its json objects + * Add `as_json` methods in json/add/core, so rails can create its json objects the new way. -2011-05-11 (1.5.2) + +## 2011-05-11 (1.5.2) * Apply documentation patch by Cory Monty . - * Add gemspecs for json and json_pure. + * Add gemspecs for json and json\_pure. * Fix bug in jruby pretty printing. - * Fix bug in object_class and array_class when inheriting from Hash or Array. -2011-01-24 (1.5.1) + * Fix bug in `object_class` and `array_class` when inheriting from Hash or + Array. + +## 2011-01-24 (1.5.1) * Made rake-compiler build a fat binary gem. This should fix issue https://github.com/flori/json/issues#issue/54. -2011-01-22 (1.5.0) + +## 2011-01-22 (1.5.0) * Included Java source codes for the Jruby extension made by Daniel Luz . - * Output full exception message of deep_const_get to aid debugging. - * Fixed an issue with ruby 1.9 Module#const_defined? method, that was + * Output full exception message of `deep_const_get` to aid debugging. + * Fixed an issue with ruby 1.9 `Module#const_defined?` method, that was reported by Riley Goodside. -2010-08-09 (1.4.6) + +## 2010-08-09 (1.4.6) * Fixed oversight reported in http://github.com/flori/json/issues/closed#issue/23, always create a new object from the state prototype. * Made pure and ext api more similar again. -2010-08-07 (1.4.5) + +## 2010-08-07 (1.4.5) * Manage data structure nesting depth in state object during generation. This - should reduce problems with to_json method definіtions that only have one + should reduce problems with `to_json` method definіtions that only have one argument. * Some fixes in the state objects and additional tests. -2010-08-06 (1.4.4) +## 2010-08-06 (1.4.4) * Fixes build problem for rubinius under OS X, http://github.com/flori/json/issues/closed#issue/25 * Fixes crashes described in http://github.com/flori/json/issues/closed#issue/21 and http://github.com/flori/json/issues/closed#issue/23 -2010-05-05 (1.4.3) +## 2010-05-05 (1.4.3) * Fixed some test assertions, from Ruby r27587 and r27590, patch by nobu. * Fixed issue http://github.com/flori/json/issues/#issue/20 reported by electronicwhisper@github. Thx! -2010-04-26 (1.4.2) + +## 2010-04-26 (1.4.2) * Applied patch from naruse Yui NARUSE to make building with Microsoft Visual C possible again. * Applied patch from devrandom in order to allow building of @@ -154,34 +189,43 @@ * Thanks to Dustin Schneider , who reported a memory leak, which is fixed in this release. * Applied 993f261ccb8f911d2ae57e9db48ec7acd0187283 patch from josh@github. -2010-04-25 (1.4.1) + +## 2010-04-25 (1.4.1) * Fix for a bug reported by Dan DeLeo , caused by T_FIXNUM being different on 32bit/64bit architectures. -2010-04-23 (1.4.0) + +## 2010-04-23 (1.4.0) * Major speed improvements and building with simplified directory/file-structure. * Extension should at least be comapatible with MRI, YARV and Rubinius. -2010-04-07 (1.2.4) + +## 2010-04-07 (1.2.4) * Triger const_missing callback to make Rails' dynamic class loading work. -2010-03-11 (1.2.3) - * Added a State#[] method which returns an attribute's value in order to + +## 2010-03-11 (1.2.3) + * Added a `State#[]` method which returns an attribute's value in order to increase duck type compatibility to Hash. -2010-02-27 (1.2.2) + +## 2010-02-27 (1.2.2) * Made some changes to make the building of the parser/generator compatible to Rubinius. -2009-11-25 (1.2.1) - * Added :symbolize_names option to Parser, which returns symbols instead of + +## 2009-11-25 (1.2.1) + * Added `:symbolize_names` option to Parser, which returns symbols instead of strings in object names/keys. -2009-10-01 (1.2.0) - * fast_generate now raises an exeception for nan and infinite floats. + +## 2009-10-01 (1.2.0) + * `fast_generate` now raises an exeception for nan and infinite floats. * On Ruby 1.8 json supports parsing of UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, and UTF-32LE JSON documents now. Under Ruby 1.9 the M17n conversion functions are used to convert from all supported encodings. ASCII-8BIT encoded strings are handled like all strings under Ruby 1.8 were. * Better documentation -2009-08-23 (1.1.9) - * Added forgotten main doc file extra_rdoc_files. -2009-08-23 (1.1.8) + +## 2009-08-23 (1.1.9) + * Added forgotten main doc file `extra_rdoc_files`. + +## 2009-08-23 (1.1.8) * Applied a patch by OZAWA Sakuro to make json/pure work in environments that don't provide iconv. * Applied patch by okkez_ in order to fix Ruby Bug #1768: @@ -189,7 +233,8 @@ * Finally got around to avoid the rather paranoid escaping of ?/ characters in the generator's output. The parsers aren't affected by this change. Thanks to Rich Apodaca for the suggestion. -2009-06-29 (1.1.7) + +## 2009-06-29 (1.1.7) * Security Fix for JSON::Pure::Parser. A specially designed string could cause catastrophic backtracking in one of the parser's regular expressions in earlier 1.1.x versions. JSON::Ext::Parser isn't affected by this issue. @@ -197,16 +242,19 @@ problem. * This release also uses a less strict ruby version requirement for the creation of the mswin32 native gem. -2009-05-10 (1.1.6) + +## 2009-05-10 (1.1.6) * No changes. І tested native linux gems in the last release and they don't play well with different ruby versions other than the one the gem was built with. This release is just to bump the version number in order to skip the native gem on rubyforge. -2009-05-10 (1.1.5) + +## 2009-05-10 (1.1.5) * Started to build gems with rake-compiler gem. * Applied patch object/array class patch from Brian Candler and fixes. -2009-04-01 (1.1.4) + +## 2009-04-01 (1.1.4) * Fixed a bug in the creation of serialized generic rails objects reported by Friedrich Graeter . * Deleted tests/runner.rb, we're using testrb instead. @@ -215,7 +263,8 @@ 1.9. * Improved speed of the code path for the fast_generate method in the pure variant. -2008-07-10 (1.1.3) + +## 2008-07-10 (1.1.3) * Wesley Beary reported a bug in json/add/core's DateTime handling: If the nominator and denominator of the offset were divisible by each other Ruby's Rational#to_s returns them as an integer not a fraction @@ -225,7 +274,8 @@ * Supports ragel >= 6.0 now. * Corrected some tests. * Some minor changes. -2007-11-27 (1.1.2) + +## 2007-11-27 (1.1.2) * Remember default dir (last used directory) in editor. * JSON::Editor.edit method added, the editor can now receive json texts from the clipboard via C-v. @@ -241,13 +291,14 @@ generator by returning something other than a String instance from a to_json method. I now guard against this by doing a rather crude type check, which raises an exception instead of crashing. -2007-07-06 (1.1.1) + +## 2007-07-06 (1.1.1) * Yui NARUSE sent some patches to fix tests for Ruby 1.9. I applied them and adapted some of them a bit to run both on 1.8 and 1.9. - * Introduced a JSON.parse! method without depth checking for people who like - danger. - * Made generate and pretty_generate methods configurable by an options hash. + * Introduced a `JSON.parse!` method without depth checking for people who + like danger. + * Made generate and `pretty_generate` methods configurable by an options hash. * Added :allow_nan option to parser and generator in order to handle NaN, Infinity, and -Infinity correctly - if requested. Floats, which aren't numbers, aren't valid JSON according to RFC4627, so by default an exception will be @@ -256,55 +307,65 @@ * Fixed some more tests for Ruby 1.9. * Implemented dump/load interface of Marshal as suggested in ruby-core:11405 by murphy . - * Implemented the max_nesting feature for generate methods, too. + * Implemented the `max_nesting` feature for generate methods, too. * Added some implementations for ruby core's custom objects for serialisation/deserialisation purposes. -2007-05-21 (1.1.0) + +## 2007-05-21 (1.1.0) * Implemented max_nesting feature for parser to avoid stack overflows for data from untrusted sources. If you trust the source, you can disable it with the option max_nesting => false. * Piers Cawley reported a bug, that not every - character can be escaped by ?\ as required by RFC4627. There's a + character can be escaped by `\` as required by RFC4627. There's a contradiction between David Crockford's JSON checker test vectors (in tests/fixtures) and RFC4627, though. I decided to stick to the RFC, because the JSON checker seems to be a bit older than the RFC. * Extended license to Ruby License, which includes the GPL. * Added keyboard shortcuts, and 'Open location' menu item to edit_json.rb. -2007-05-09 (1.0.4) + +## 2007-05-09 (1.0.4) * Applied a patch from Yui NARUSE to make JSON compile under Ruby 1.9. Thank you very much for mailing it to me! * Made binary variants of JSON fail early, instead of falling back to the pure version. This should avoid overshadowing of eventual problems while loading of the binary. -2007-03-24 (1.0.3) + +## 2007-03-24 (1.0.3) * Improved performance of pure variant a bit. * The ext variant of this release supports the mswin32 platform. Ugh! -2007-03-24 (1.0.2) + +## 2007-03-24 (1.0.2) * Ext Parser didn't parse 0e0 correctly into 0.0: Fixed! -2007-03-24 (1.0.1) + +## 2007-03-24 (1.0.1) * Forgot some object files in the build dir. I really like that - not! -2007-03-24 (1.0.0) + +## 2007-03-24 (1.0.0) * Added C implementations for the JSON generator and a ragel based JSON parser in C. * Much more tests, especially fixtures from json.org. * Further improved conformance to RFC4627. -2007-02-09 (0.4.3) + +## 2007-02-09 (0.4.3) * Conform more to RFC4627 for JSON: This means JSON strings - now always must contain exactly one object "{ ... }" or array "[ ... ]" in + now always must contain exactly one object `"{ ... }"` or array `"[ ... ]"` in order to be parsed without raising an exception. The definition of what constitutes a whitespace is narrower in JSON than in Ruby ([ \t\r\n]), and there are differences in floats and integers (no octals or hexadecimals) as well. - * Added aliases generate and pretty_generate of unparse and pretty_unparse. + * Added aliases generate and `pretty_generate` of unparse and `pretty_unparse`. * Fixed a test case. - * Catch an Iconv::InvalidEncoding exception, that seems to occur on some Sun + * Catch an `Iconv::InvalidEncoding` exception, that seems to occur on some Sun boxes with SunOS 5.8, if iconv doesn't support utf16 conversions. This was reported by Andrew R Jackson , thanks a bunch! -2006-08-25 (0.4.2) + +## 2006-08-25 (0.4.2) * Fixed a bug in handling solidi (/-characters), that was reported by Kevin Gilpin . -2006-02-06 (0.4.1) + +## 2006-02-06 (0.4.1) * Fixed a bug related to escaping with backslashes. Thanks for the report go to Florian Munz . -2005-09-23 (0.4.0) + +## 2005-09-23 (0.4.0) * Initial Rubyforge Version From 05a3adc16f4296c34cac479d6001beefa68c015b Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 1 Jul 2016 17:23:00 +0200 Subject: [PATCH 165/312] Rename to be shorter --- README-json-jruby.markdown => README-json-jruby.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README-json-jruby.markdown => README-json-jruby.md (100%) diff --git a/README-json-jruby.markdown b/README-json-jruby.md similarity index 100% rename from README-json-jruby.markdown rename to README-json-jruby.md From f679ebd0c69a94e3e70a897ac9a229f5779c2ee1 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 1 Jul 2016 17:23:39 +0200 Subject: [PATCH 166/312] Bump version to 2.0.1 --- VERSION | 2 +- json.gemspec | Bin 5476 -> 5473 bytes json_pure.gemspec | 6 +++--- lib/json/version.rb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index 227cea215..38f77a65b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.0 +2.0.1 diff --git a/json.gemspec b/json.gemspec index 595d3e07225c172a2b39272575f20e3c0e17db57..c5a3c1003d4176d1075f1ca1493029f6cae29894 100644 GIT binary patch delta 32 ocmaE&^-ybqHlyK0olT5}8}G+4G3(`~OtxhEdT%j delta 34 qcmaE;^+aoeHlx8rolT4e8}G+4O?F^5U{5T{PRTFN+g!-}K@b4pgbcv| diff --git a/json_pure.gemspec b/json_pure.gemspec index 880fdcfaa..bf7dc79f4 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -1,9 +1,9 @@ # -*- encoding: utf-8 -*- -# stub: json_pure 2.0.0 ruby lib +# stub: json_pure 2.0.1 ruby lib Gem::Specification.new do |s| s.name = "json_pure".freeze - s.version = "2.0.0" + s.version = "2.0.1" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] - s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES".freeze, "Gemfile".freeze, "README-json-jruby.markdown".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] + s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] s.homepage = "http://flori.github.com/json".freeze s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] diff --git a/lib/json/version.rb b/lib/json/version.rb index 520a8ad3b..5184ad3c1 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module JSON # JSON version - VERSION = '2.0.0' + VERSION = '2.0.1' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: From b25de1fd3977557bdaca4b048058632c31bb3db3 Mon Sep 17 00:00:00 2001 From: chottoda Date: Tue, 5 Jul 2016 16:30:01 +0900 Subject: [PATCH 167/312] [Now complies to newest JSON RFC 7159.](https://github.com/chottoda/json/blob/master/CHANGES.md#2015-09-11-200) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5691f3e35..d5ff32d79 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ ## Description -This is a implementation of the JSON specification according to RFC 4627 -http://www.ietf.org/rfc/rfc4627.txt . Starting from version 1.0.0 on there +This is a implementation of the JSON specification according to RFC 7159 +http://www.ietf.org/rfc/rfc7159.txt . Starting from version 1.0.0 on there will be two variants available: * A pure ruby variant, that relies on the iconv and the stringscan From d484f402327c9abf26e6b021576872e207132483 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 7 Jul 2016 14:50:01 +0200 Subject: [PATCH 168/312] Test parsing some simple singular values --- tests/json_parser_test.rb | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb index c1c2779b9..f34bc0258 100644 --- a/tests/json_parser_test.rb +++ b/tests/json_parser_test.rb @@ -40,6 +40,18 @@ def test_parser_reset assert_equal({ 'a' => 'b' }, parser.parse) end + def test_parse_values + assert_equal(nil, parse('null')) + assert_equal(false, parse('false')) + assert_equal(true, parse('true')) + assert_equal(-23, parse('-23')) + assert_equal(23, parse('23')) + assert_in_delta(0.23, parse('0.23'), 1e-2) + assert_in_delta(0.0, parse('0e0'), 1e-2) + assert_equal("", parse('""')) + assert_equal("foobar", parse('"foobar"')) + end + def test_parse_simple_arrays assert_equal([], parse('[]')) assert_equal([], parse(' [ ] ')) @@ -277,7 +289,6 @@ def test_backslash assert_equal data, parse(json) end - class SubArray < Array def <<(v) @shifted = true From 5ed5674fd5d9a4a55438065ae764259e4242f852 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 8 Jul 2016 15:59:39 +0900 Subject: [PATCH 169/312] Suppress a warning Suppress a unused-but-set-variable warning by gcc. --- ext/json/ext/generator/generator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 2b56721b2..ef85bb733 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -951,6 +951,7 @@ static VALUE cState_generate(VALUE self, VALUE obj) { VALUE result = cState_partial_generate(self, obj); GET_STATE(self); + (void)state; return result; } From dbdb94d984214dc468131a249c7a4060edd1db3c Mon Sep 17 00:00:00 2001 From: Joe Lencioni Date: Tue, 12 Jul 2016 15:56:03 -0700 Subject: [PATCH 170/312] Fix typo "improvemed" => "improved" --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 89326f3c1..62a04aa18 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -28,7 +28,7 @@ `JSON.dump_default_options`. * More tests by Michael Mac-Vicar and fixing `space_before` accessor in generator. - * Performance on Jruby improvemed by Ben Browning . + * Performance on Jruby improved by Ben Browning . * Some fixes to be compatible with the new Ruby 2.2 by Zachary Scott and SHIBATA Hiroshi . From 17b28a2ffd65f428159d5479c804f48075c2dccf Mon Sep 17 00:00:00 2001 From: SHIBATA Hiroshi Date: Thu, 14 Jul 2016 12:44:31 +0900 Subject: [PATCH 171/312] Fix inconsistency usage for assertion methods --- tests/json_common_interface_test.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/json_common_interface_test.rb b/tests/json_common_interface_test.rb index b2051d4c5..29b4a5b56 100644 --- a/tests/json_common_interface_test.rb +++ b/tests/json_common_interface_test.rb @@ -47,7 +47,7 @@ def test_create_id end def test_deep_const_get - assert_raises(ArgumentError) { JSON.deep_const_get('Nix::Da') } + assert_raise(ArgumentError) { JSON.deep_const_get('Nix::Da') } assert_equal File::SEPARATOR, JSON.deep_const_get('File::SEPARATOR') end @@ -93,8 +93,8 @@ def test_load_with_options def test_load_null assert_equal nil, JSON.load(nil, nil, :allow_blank => true) - assert_raises(TypeError) { JSON.load(nil, nil, :allow_blank => false) } - assert_raises(JSON::ParserError) { JSON.load('', nil, :allow_blank => false) } + assert_raise(TypeError) { JSON.load(nil, nil, :allow_blank => false) } + assert_raise(JSON::ParserError) { JSON.load('', nil, :allow_blank => false) } end def test_dump From bb5b67741c20c8a53f2e81985fafccbeb750818c Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 19 Jul 2016 10:07:56 +0200 Subject: [PATCH 172/312] Add required_ruby_version to json_pure spec --- Rakefile | 1 + json.gemspec | Bin 5473 -> 5473 bytes json_pure.gemspec | 3 ++- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 958dfa682..48b365c1a 100644 --- a/Rakefile +++ b/Rakefile @@ -95,6 +95,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.email = "flori@ping.de" s.homepage = "http://flori.github.com/#{PKG_NAME}" s.license = 'Ruby' + s.required_ruby_version = '~> 2.0' end desc 'Creates a json_pure.gemspec file' diff --git a/json.gemspec b/json.gemspec index c5a3c1003d4176d1075f1ca1493029f6cae29894..477309432df0186baf36941e810717b147f0b377 100644 GIT binary patch delta 15 XcmaE;^-ycWMn)z>%gvh^*9ijvHS7ir delta 15 XcmaE;^-ycWMn)zB!_Au+*9ijvHMIr= diff --git a/json_pure.gemspec b/json_pure.gemspec index bf7dc79f4..841dfa70b 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2016-07-01" + s.date = "2016-07-19" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] @@ -16,6 +16,7 @@ Gem::Specification.new do |s| s.homepage = "http://flori.github.com/json".freeze s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] + s.required_ruby_version = Gem::Requirement.new("~> 2.0".freeze) s.rubygems_version = "2.6.4".freeze s.summary = "JSON Implementation for Ruby".freeze s.test_files = ["./tests/test_helper.rb".freeze] From 047814c7a6916bde393e6080c98385c8170d3f98 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 26 Jul 2016 11:27:14 +0200 Subject: [PATCH 173/312] Fix issue #296 when parsing frozen strings --- VERSION | 2 +- ext/json/ext/parser/parser.c | 19 +++-- ext/json/ext/parser/parser.rl | 3 + java/src/json/ext/Parser.java | 145 +++++++++++++++++----------------- java/src/json/ext/Parser.rl | 3 + json.gemspec | Bin 5473 -> 5473 bytes json_pure.gemspec | 6 +- lib/json/version.rb | 2 +- tests/json_parser_test.rb | 7 ++ 9 files changed, 103 insertions(+), 84 deletions(-) diff --git a/VERSION b/VERSION index 38f77a65b..e9307ca57 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.1 +2.0.2 diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 975a26769..0dae674c8 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1670,6 +1670,9 @@ static VALUE convert_encoding(VALUE source) #ifdef HAVE_RUBY_ENCODING_H rb_encoding *enc = rb_enc_get(source); if (enc == rb_ascii8bit_encoding()) { + if (OBJ_FROZEN(source)) { + source = rb_str_dup(source); + } FORCE_UTF8(source); } else { source = rb_str_conv_enc(source, NULL, rb_utf8_encoding()); @@ -1805,7 +1808,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1809 "parser.c" +#line 1812 "parser.c" enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1813,7 +1816,7 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; -#line 717 "parser.rl" +#line 720 "parser.rl" /* @@ -1830,16 +1833,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -#line 1834 "parser.c" +#line 1837 "parser.c" { cs = JSON_start; } -#line 733 "parser.rl" +#line 736 "parser.rl" p = json->source; pe = p + json->len; -#line 1843 "parser.c" +#line 1846 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1873,7 +1876,7 @@ case 1: cs = 0; goto _out; tr2: -#line 709 "parser.rl" +#line 712 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1883,7 +1886,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1887 "parser.c" +#line 1890 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1972,7 +1975,7 @@ case 9: _out: {} } -#line 736 "parser.rl" +#line 739 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index c67634b8b..dd24cf94c 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -565,6 +565,9 @@ static VALUE convert_encoding(VALUE source) #ifdef HAVE_RUBY_ENCODING_H rb_encoding *enc = rb_enc_get(source); if (enc == rb_ascii8bit_encoding()) { + if (OBJ_FROZEN(source)) { + source = rb_str_dup(source); + } FORCE_UTF8(source); } else { source = rb_str_conv_enc(source, NULL, rb_utf8_encoding()); diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index 8c338402b..2a7d9f544 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -181,6 +181,9 @@ public IRubyObject initialize(ThreadContext context, IRubyObject[] args) { private RubyString convertEncoding(ThreadContext context, RubyString source) { RubyEncoding encoding = (RubyEncoding)source.encoding(context); if (encoding == info.ascii8bit.get()) { + if (source.isFrozen()) { + source = (RubyString) source.dup(); + } source.force_encoding(context, info.utf8.get()); } else { source = (RubyString) source.encode(context, info.utf8.get()); @@ -304,11 +307,11 @@ private Ruby getRuntime() { } -// line 330 "Parser.rl" +// line 333 "Parser.rl" -// line 312 "Parser.java" +// line 315 "Parser.java" private static byte[] init__JSON_value_actions_0() { return new byte [] { @@ -422,7 +425,7 @@ private static byte[] init__JSON_value_from_state_actions_0() static final int JSON_value_en_main = 1; -// line 436 "Parser.rl" +// line 439 "Parser.rl" void parseValue(ParserResult res, int p, int pe) { @@ -430,14 +433,14 @@ void parseValue(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 434 "Parser.java" +// line 437 "Parser.java" { cs = JSON_value_start; } -// line 443 "Parser.rl" +// line 446 "Parser.rl" -// line 441 "Parser.java" +// line 444 "Parser.java" { int _klen; int _trans = 0; @@ -463,13 +466,13 @@ void parseValue(ParserResult res, int p, int pe) { while ( _nacts-- > 0 ) { switch ( _JSON_value_actions[_acts++] ) { case 9: -// line 421 "Parser.rl" +// line 424 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 473 "Parser.java" +// line 476 "Parser.java" } } @@ -532,25 +535,25 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) switch ( _JSON_value_actions[_acts++] ) { case 0: -// line 338 "Parser.rl" +// line 341 "Parser.rl" { result = getRuntime().getNil(); } break; case 1: -// line 341 "Parser.rl" +// line 344 "Parser.rl" { result = getRuntime().getFalse(); } break; case 2: -// line 344 "Parser.rl" +// line 347 "Parser.rl" { result = getRuntime().getTrue(); } break; case 3: -// line 347 "Parser.rl" +// line 350 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_NAN); @@ -560,7 +563,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 4: -// line 354 "Parser.rl" +// line 357 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_INFINITY); @@ -570,7 +573,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 5: -// line 361 "Parser.rl" +// line 364 "Parser.rl" { if (pe > p + 8 && absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) { @@ -599,7 +602,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 6: -// line 387 "Parser.rl" +// line 390 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -612,7 +615,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 7: -// line 397 "Parser.rl" +// line 400 "Parser.rl" { currentNesting++; parseArray(res, p, pe); @@ -627,7 +630,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 8: -// line 409 "Parser.rl" +// line 412 "Parser.rl" { currentNesting++; parseObject(res, p, pe); @@ -641,7 +644,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } } break; -// line 645 "Parser.java" +// line 648 "Parser.java" } } } @@ -661,7 +664,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) break; } } -// line 444 "Parser.rl" +// line 447 "Parser.rl" if (cs >= JSON_value_first_final && result != null) { res.update(result, p); @@ -671,7 +674,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } -// line 675 "Parser.java" +// line 678 "Parser.java" private static byte[] init__JSON_integer_actions_0() { return new byte [] { @@ -770,7 +773,7 @@ private static byte[] init__JSON_integer_trans_actions_0() static final int JSON_integer_en_main = 1; -// line 463 "Parser.rl" +// line 466 "Parser.rl" void parseInteger(ParserResult res, int p, int pe) { @@ -788,15 +791,15 @@ int parseIntegerInternal(int p, int pe) { int cs = EVIL; -// line 792 "Parser.java" +// line 795 "Parser.java" { cs = JSON_integer_start; } -// line 480 "Parser.rl" +// line 483 "Parser.rl" int memo = p; -// line 800 "Parser.java" +// line 803 "Parser.java" { int _klen; int _trans = 0; @@ -877,13 +880,13 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) switch ( _JSON_integer_actions[_acts++] ) { case 0: -// line 457 "Parser.rl" +// line 460 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 887 "Parser.java" +// line 890 "Parser.java" } } } @@ -903,7 +906,7 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) break; } } -// line 482 "Parser.rl" +// line 485 "Parser.rl" if (cs < JSON_integer_first_final) { return -1; @@ -925,7 +928,7 @@ RubyInteger bytesToInum(Ruby runtime, ByteList num) { } -// line 929 "Parser.java" +// line 932 "Parser.java" private static byte[] init__JSON_float_actions_0() { return new byte [] { @@ -1027,7 +1030,7 @@ private static byte[] init__JSON_float_trans_actions_0() static final int JSON_float_en_main = 1; -// line 517 "Parser.rl" +// line 520 "Parser.rl" void parseFloat(ParserResult res, int p, int pe) { @@ -1045,15 +1048,15 @@ int parseFloatInternal(int p, int pe) { int cs = EVIL; -// line 1049 "Parser.java" +// line 1052 "Parser.java" { cs = JSON_float_start; } -// line 534 "Parser.rl" +// line 537 "Parser.rl" int memo = p; -// line 1057 "Parser.java" +// line 1060 "Parser.java" { int _klen; int _trans = 0; @@ -1134,13 +1137,13 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) switch ( _JSON_float_actions[_acts++] ) { case 0: -// line 508 "Parser.rl" +// line 511 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1144 "Parser.java" +// line 1147 "Parser.java" } } } @@ -1160,7 +1163,7 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) break; } } -// line 536 "Parser.rl" +// line 539 "Parser.rl" if (cs < JSON_float_first_final) { return -1; @@ -1176,7 +1179,7 @@ RubyFloat createFloat(int p, int new_p) { } -// line 1180 "Parser.java" +// line 1183 "Parser.java" private static byte[] init__JSON_string_actions_0() { return new byte [] { @@ -1278,7 +1281,7 @@ private static byte[] init__JSON_string_trans_actions_0() static final int JSON_string_en_main = 1; -// line 581 "Parser.rl" +// line 584 "Parser.rl" void parseString(ParserResult res, int p, int pe) { @@ -1286,15 +1289,15 @@ void parseString(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 1290 "Parser.java" +// line 1293 "Parser.java" { cs = JSON_string_start; } -// line 588 "Parser.rl" +// line 591 "Parser.rl" int memo = p; -// line 1298 "Parser.java" +// line 1301 "Parser.java" { int _klen; int _trans = 0; @@ -1375,7 +1378,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) switch ( _JSON_string_actions[_acts++] ) { case 0: -// line 556 "Parser.rl" +// line 559 "Parser.rl" { int offset = byteList.begin(); ByteList decoded = decoder.decode(byteList, memo + 1 - offset, @@ -1390,13 +1393,13 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) } break; case 1: -// line 569 "Parser.rl" +// line 572 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1400 "Parser.java" +// line 1403 "Parser.java" } } } @@ -1416,7 +1419,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) break; } } -// line 590 "Parser.rl" +// line 593 "Parser.rl" if (parser.createAdditions) { RubyHash matchString = parser.matchString; @@ -1454,7 +1457,7 @@ public void visit(IRubyObject pattern, IRubyObject klass) { } -// line 1458 "Parser.java" +// line 1461 "Parser.java" private static byte[] init__JSON_array_actions_0() { return new byte [] { @@ -1567,7 +1570,7 @@ private static byte[] init__JSON_array_trans_actions_0() static final int JSON_array_en_main = 1; -// line 663 "Parser.rl" +// line 666 "Parser.rl" void parseArray(ParserResult res, int p, int pe) { @@ -1587,14 +1590,14 @@ void parseArray(ParserResult res, int p, int pe) { } -// line 1591 "Parser.java" +// line 1594 "Parser.java" { cs = JSON_array_start; } -// line 682 "Parser.rl" +// line 685 "Parser.rl" -// line 1598 "Parser.java" +// line 1601 "Parser.java" { int _klen; int _trans = 0; @@ -1675,7 +1678,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) switch ( _JSON_array_actions[_acts++] ) { case 0: -// line 632 "Parser.rl" +// line 635 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1692,13 +1695,13 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } break; case 1: -// line 647 "Parser.rl" +// line 650 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1702 "Parser.java" +// line 1705 "Parser.java" } } } @@ -1718,7 +1721,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) break; } } -// line 683 "Parser.rl" +// line 686 "Parser.rl" if (cs >= JSON_array_first_final) { res.update(result, p + 1); @@ -1728,7 +1731,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } -// line 1732 "Parser.java" +// line 1735 "Parser.java" private static byte[] init__JSON_object_actions_0() { return new byte [] { @@ -1851,7 +1854,7 @@ private static byte[] init__JSON_object_trans_actions_0() static final int JSON_object_en_main = 1; -// line 742 "Parser.rl" +// line 745 "Parser.rl" void parseObject(ParserResult res, int p, int pe) { @@ -1876,14 +1879,14 @@ void parseObject(ParserResult res, int p, int pe) { } -// line 1880 "Parser.java" +// line 1883 "Parser.java" { cs = JSON_object_start; } -// line 766 "Parser.rl" +// line 769 "Parser.rl" -// line 1887 "Parser.java" +// line 1890 "Parser.java" { int _klen; int _trans = 0; @@ -1964,7 +1967,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) switch ( _JSON_object_actions[_acts++] ) { case 0: -// line 697 "Parser.rl" +// line 700 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1981,7 +1984,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 1: -// line 712 "Parser.rl" +// line 715 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -2001,13 +2004,13 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 2: -// line 730 "Parser.rl" +// line 733 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 2011 "Parser.java" +// line 2014 "Parser.java" } } } @@ -2027,7 +2030,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) break; } } -// line 767 "Parser.rl" +// line 770 "Parser.rl" if (cs < JSON_object_first_final) { res.update(null, p + 1); @@ -2060,7 +2063,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } -// line 2064 "Parser.java" +// line 2067 "Parser.java" private static byte[] init__JSON_actions_0() { return new byte [] { @@ -2163,7 +2166,7 @@ private static byte[] init__JSON_trans_actions_0() static final int JSON_en_main = 1; -// line 818 "Parser.rl" +// line 821 "Parser.rl" public IRubyObject parseImplemetation() { @@ -2173,16 +2176,16 @@ public IRubyObject parseImplemetation() { ParserResult res = new ParserResult(); -// line 2177 "Parser.java" +// line 2180 "Parser.java" { cs = JSON_start; } -// line 827 "Parser.rl" +// line 830 "Parser.rl" p = byteList.begin(); pe = p + byteList.length(); -// line 2186 "Parser.java" +// line 2189 "Parser.java" { int _klen; int _trans = 0; @@ -2263,7 +2266,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) switch ( _JSON_actions[_acts++] ) { case 0: -// line 804 "Parser.rl" +// line 807 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2275,7 +2278,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) } } break; -// line 2279 "Parser.java" +// line 2282 "Parser.java" } } } @@ -2295,7 +2298,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) break; } } -// line 830 "Parser.rl" +// line 833 "Parser.rl" if (cs >= JSON_first_final && p == pe) { return result; diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 28247eaeb..1ad8f216a 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -179,6 +179,9 @@ public class Parser extends RubyObject { private RubyString convertEncoding(ThreadContext context, RubyString source) { RubyEncoding encoding = (RubyEncoding)source.encoding(context); if (encoding == info.ascii8bit.get()) { + if (source.isFrozen()) { + source = (RubyString) source.dup(); + } source.force_encoding(context, info.utf8.get()); } else { source = (RubyString) source.encode(context, info.utf8.get()); diff --git a/json.gemspec b/json.gemspec index 477309432df0186baf36941e810717b147f0b377..2c304ef918b82ccd06d1fe161486aabd85b5f289 100644 GIT binary patch delta 24 fcmaE;^-ybqHlxu*olQXE{v{?Ov(1|s*9ijvdKw9P delta 24 fcmaE;^-ybqHlyK0olQXE{v{?u%gvh^*9ijvdI$-7 diff --git a/json_pure.gemspec b/json_pure.gemspec index 841dfa70b..b6d6093fa 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -1,14 +1,14 @@ # -*- encoding: utf-8 -*- -# stub: json_pure 2.0.1 ruby lib +# stub: json_pure 2.0.2 ruby lib Gem::Specification.new do |s| s.name = "json_pure".freeze - s.version = "2.0.1" + s.version = "2.0.2" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2016-07-19" + s.date = "2016-07-26" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] diff --git a/lib/json/version.rb b/lib/json/version.rb index 5184ad3c1..8997def28 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module JSON # JSON version - VERSION = '2.0.1' + VERSION = '2.0.2' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb index f34bc0258..40ad500cb 100644 --- a/tests/json_parser_test.rb +++ b/tests/json_parser_test.rb @@ -449,6 +449,13 @@ def test_generate_of_core_subclasses assert_equal obj, obj_again end + def test_parsing_frozen_ascii8bit_string + assert_equal( + { 'foo' => 'bar' }, + JSON('{ "foo": "bar" }'.force_encoding(Encoding::ASCII_8BIT).freeze) + ) + end + private def assert_equal_float(expected, actual, delta = 1e-2) From f1ca4fed316ad416ae718544623865aca4231a08 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 26 Jul 2016 13:11:16 +0200 Subject: [PATCH 174/312] Add change to CHANGES --- CHANGES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 62a04aa18..8e00ae429 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## 2016-07-26 (2.0.2) + * Specify `required_ruby_version` for json\_pure. + * Fix issue #295 failure when parsing frozen strings. + ## 2016-07-01 (2.0.1) * Fix problem when requiring json\_pure and Parser constant was defiend top level. From cb5cbae950982cf2a34b3c50de0a14ccfc2c1790 Mon Sep 17 00:00:00 2001 From: Alexandre Perrin Date: Fri, 29 Jul 2016 11:08:31 +0200 Subject: [PATCH 175/312] README.md typo fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5ff32d79..f9cd95d56 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ generate a JSON document from an array or hash: ```ruby document = JSON 'test' => 23 # => "{\"test\":23}" -document = JSON['test'] => 23 # => "{\"test\":23}" +document = JSON['test' => 23] # => "{\"test\":23}" ``` and From 05485253d0945177e5b282235f9f00ba10eef8f5 Mon Sep 17 00:00:00 2001 From: Kouhei Yanagita Date: Tue, 30 Aug 2016 10:43:01 +0900 Subject: [PATCH 176/312] Correct documentation of OpenStruct.json_create --- lib/json/add/ostruct.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/add/ostruct.rb b/lib/json/add/ostruct.rb index 7c1391005..e064c85ff 100644 --- a/lib/json/add/ostruct.rb +++ b/lib/json/add/ostruct.rb @@ -7,7 +7,7 @@ class OpenStruct # Deserializes JSON string by constructing new Struct object with values - # v serialized by to_json. + # t serialized by to_json. def self.json_create(object) new(object['t'] || object[:t]) end From 4c87156e86fb907ceeaa7b44715f79da03c57d68 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 9 Sep 2016 18:30:04 +0900 Subject: [PATCH 177/312] Get rid of use of Bignum, obsolete name --- tests/json_generator_test.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/json_generator_test.rb b/tests/json_generator_test.rb index 18b08337f..86be398f4 100644 --- a/tests/json_generator_test.rb +++ b/tests/json_generator_test.rb @@ -277,12 +277,13 @@ def foo.to_h if defined?(JSON::Ext::Generator) def test_broken_bignum # [ruby-core:38867] pid = fork do - Bignum.class_eval do + x = 1 << 64 + x.class.class_eval do def to_s end end begin - JSON::Ext::Generator::State.new.generate(1<<64) + JSON::Ext::Generator::State.new.generate(x) exit 1 rescue TypeError exit 0 From 4733c379374f4c18a85d892c3265f98d8f38d823 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 9 Sep 2016 12:27:47 +0200 Subject: [PATCH 178/312] New gemspec --- json.gemspec | Bin 5473 -> 5473 bytes json_pure.gemspec | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/json.gemspec b/json.gemspec index 2c304ef918b82ccd06d1fe161486aabd85b5f289..e1cbad08ae78d747cf6367da23ef2af6429322e6 100644 GIT binary patch delta 17 ZcmaE;^-ycWdPWvYT?5O_n;F*$0{}ok266xZ delta 17 ZcmaE;^-ycWdPWv=T_dy2n;F*$0{}oO25$fW diff --git a/json_pure.gemspec b/json_pure.gemspec index b6d6093fa..70c20892c 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2016-07-26" + s.date = "2016-09-09" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] From f2708a4075f59231bf8deee0bdff20c572df2263 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 12 Sep 2016 09:59:39 +0200 Subject: [PATCH 179/312] Test ruby 2.4.0-preview2 --- .travis.yml | 1 + json.gemspec | Bin 5473 -> 5473 bytes json_pure.gemspec | 4 ++-- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 49f95293b..76cef677a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ rvm: - 2.1 - 2.2 - 2.3.1 + - 2.4.0-preview2 - ruby-head matrix: include: diff --git a/json.gemspec b/json.gemspec index e1cbad08ae78d747cf6367da23ef2af6429322e6..7c862b0b1a02ed3f662e07bec74de40af6d2c896 100644 GIT binary patch delta 22 ecmaE;^-ycWMn)z>qs^Ncbp;vCHa`?= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2016-09-09" + s.date = "2016-09-12" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] s.required_ruby_version = Gem::Requirement.new("~> 2.0".freeze) - s.rubygems_version = "2.6.4".freeze + s.rubygems_version = "2.6.6".freeze s.summary = "JSON Implementation for Ruby".freeze s.test_files = ["./tests/test_helper.rb".freeze] From 0689312047d5a2130a035baedbe9f46a1c498c06 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 12 Sep 2016 10:25:08 +0200 Subject: [PATCH 180/312] Avoid buggy bundler --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 76cef677a..ec48a7f99 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,5 +17,6 @@ matrix: allow_failures: - rvm: rbx-2 - rvm: ruby-head +before_install: "gem install bundler -v 1.12.0" script: "bundle exec rake" sudo: false From 01167a57fce155afc62b95e3ae5d50e004af9580 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 23 Sep 2016 16:23:36 +0200 Subject: [PATCH 181/312] Simplify JAVA_HOME code --- Rakefile | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Rakefile b/Rakefile index 48b365c1a..f10f366cd 100644 --- a/Rakefile +++ b/Rakefile @@ -200,13 +200,11 @@ namespace :gems do end if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby' - if ENV.key?('JAVA_HOME') - warn " *** JAVA_HOME was set to #{ENV['JAVA_HOME'].inspect}" - elsif File.directory?(local_java = '/usr/local/java/jdk') || - File.directory?(local_java = '/usr/lib/jvm/java-6-openjdk') - then - ENV['JAVA_HOME'] = local_java - end + ENV['JAVA_HOME'] ||= [ + '/usr/local/java/jdk', + '/usr/lib/jvm/java-6-openjdk', + '/Library/Java/Home', + ].find { |c| File.directory?(c) } if ENV['JAVA_HOME'] warn " *** JAVA_HOME is set to #{ENV['JAVA_HOME'].inspect}" ENV['PATH'] = ENV['PATH'].split(/:/).unshift(java_path = "#{ENV['JAVA_HOME']}/bin") * ':' From 8c7eb9e93916f2d863fc9ead9422427e243a5956 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 23 Sep 2016 16:23:54 +0200 Subject: [PATCH 182/312] Ignore byebug_history --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5ef62afbd..69b608db7 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ Gemfile.lock .DS_Store */**/Makefile */**/*.o +.byebug_history From 7e240ed5765867bfbdd166435f941a4cebed8cd8 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 23 Sep 2016 18:37:50 +0300 Subject: [PATCH 183/312] Merge decimal_class patch by Michael Jaschob Also: - Avoid some issues with bundler - Avoid some issues with jruby --- .travis.yml | 5 +- Gemfile | 13 +- Rakefile | 6 +- VERSION | 2 +- ext/json/ext/parser/parser.c | 2461 +++++++++++------------- ext/json/ext/parser/parser.h | 1 + ext/json/ext/parser/parser.rl | 23 +- json-java.gemspec => java/json.gemspec | 6 +- java/src/json/ext/Parser.java | 169 +- java/src/json/ext/Parser.rl | 33 +- json.gemspec | Bin 5473 -> 5473 bytes json_pure.gemspec | 8 +- lib/json/pure/parser.rb | 6 +- lib/json/version.rb | 2 +- tests/test_helper.rb | 2 - 15 files changed, 1327 insertions(+), 1410 deletions(-) rename json-java.gemspec => java/json.gemspec (85%) diff --git a/.travis.yml b/.travis.yml index ec48a7f99..9fccd10a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,13 +10,10 @@ rvm: - 2.3.1 - 2.4.0-preview2 - ruby-head + - jruby matrix: - include: - - rvm: jruby - env: JRUBY_OPTS="--2.0" allow_failures: - rvm: rbx-2 - rvm: ruby-head -before_install: "gem install bundler -v 1.12.0" script: "bundle exec rake" sudo: false diff --git a/Gemfile b/Gemfile index 51ff10afc..747bc7121 100644 --- a/Gemfile +++ b/Gemfile @@ -2,8 +2,15 @@ source 'https://rubygems.org' -gemspec :name => 'json' -gemspec :name => 'json_pure' -gemspec :name => 'json-java' +case ENV['JSON'] +when 'ext', nil + if ENV['RUBY_ENGINE'] == 'jruby' + gemspec :name => 'json', :path => 'java' + else + gemspec :name => 'json' + end +when 'pure' + gemspec :name => 'json_pure' +end gem 'simplecov' diff --git a/Rakefile b/Rakefile index f10f366cd..3e8d065fa 100644 --- a/Rakefile +++ b/Rakefile @@ -251,13 +251,13 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby' desc "Package the jruby gem" task :jruby_gem => :create_jar do - sh 'gem build json-java.gemspec' + sh 'gem build java/json.gemspec' mkdir_p 'pkg' mv "json-#{PKG_VERSION}-java.gem", 'pkg' end desc "Testing library (jruby)" - task :test_ext => [ :create_jar, :check_env, :do_test_ext ] + task :test_ext => [ :check_env, :create_jar, :do_test_ext ] UndocumentedTestTask.new do |t| t.name = 'do_test_ext' @@ -331,7 +331,7 @@ else end desc "Testing library (extension)" - task :test_ext => [ :compile, :check_env, :do_test_ext ] + task :test_ext => [ :check_env, :compile, :do_test_ext ] UndocumentedTestTask.new do |t| t.name = 'do_test_ext' diff --git a/VERSION b/VERSION index e9307ca57..7ec1d6db4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.2 +2.1.0 diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 0dae674c8..cb7c68cfb 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1,5 +1,5 @@ -#line 1 "parser.rl" +#line 1 "ext/json/ext/parser/parser.rl" #include "../fbuffer/fbuffer.h" #include "parser.h" @@ -94,23 +94,98 @@ static VALUE CNaN, CInfinity, CMinusInfinity; static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, - i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match, - i_match_string, i_aset, i_aref, i_leftshift; + i_object_class, i_array_class, i_decimal_class, i_key_p, + i_deep_const_get, i_match, i_match_string, i_aset, i_aref, + i_leftshift, i_new; -#line 124 "parser.rl" +#line 125 "ext/json/ext/parser/parser.rl" -#line 106 "parser.c" -enum {JSON_object_start = 1}; -enum {JSON_object_first_final = 27}; -enum {JSON_object_error = 0}; +#line 107 "ext/json/ext/parser/parser.c" +static const char _JSON_object_actions[] = { + 0, 1, 0, 1, 1, 1, 2 +}; + +static const char _JSON_object_key_offsets[] = { + 0, 0, 1, 8, 14, 16, 17, 19, + 20, 36, 43, 49, 51, 52, 54, 55, + 57, 58, 60, 61, 63, 64, 66, 67, + 69, 70, 72, 73 +}; + +static const char _JSON_object_trans_keys[] = { + 123, 13, 32, 34, 47, 125, 9, 10, + 13, 32, 47, 58, 9, 10, 42, 47, + 42, 42, 47, 10, 13, 32, 34, 45, + 47, 73, 78, 91, 102, 110, 116, 123, + 9, 10, 48, 57, 13, 32, 44, 47, + 125, 9, 10, 13, 32, 34, 47, 9, + 10, 42, 47, 42, 42, 47, 10, 42, + 47, 42, 42, 47, 10, 42, 47, 42, + 42, 47, 10, 42, 47, 42, 42, 47, + 10, 0 +}; + +static const char _JSON_object_single_lengths[] = { + 0, 1, 5, 4, 2, 1, 2, 1, + 12, 5, 4, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 0 +}; + +static const char _JSON_object_range_lengths[] = { + 0, 0, 1, 1, 0, 0, 0, 0, + 2, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; + +static const char _JSON_object_index_offsets[] = { + 0, 0, 2, 9, 15, 18, 20, 23, + 25, 40, 47, 53, 56, 58, 61, 63, + 66, 68, 71, 73, 76, 78, 81, 83, + 86, 88, 91, 93 +}; + +static const char _JSON_object_indicies[] = { + 0, 1, 0, 0, 2, 3, 4, 0, + 1, 5, 5, 6, 7, 5, 1, 8, + 9, 1, 10, 8, 10, 5, 8, 5, + 9, 7, 7, 11, 11, 12, 11, 11, + 11, 11, 11, 11, 11, 7, 11, 1, + 13, 13, 14, 15, 4, 13, 1, 14, + 14, 2, 16, 14, 1, 17, 18, 1, + 19, 17, 19, 14, 17, 14, 18, 20, + 21, 1, 22, 20, 22, 13, 20, 13, + 21, 23, 24, 1, 25, 23, 25, 7, + 23, 7, 24, 26, 27, 1, 28, 26, + 28, 0, 26, 0, 27, 1, 0 +}; + +static const char _JSON_object_trans_targs[] = { + 2, 0, 3, 23, 27, 3, 4, 8, + 5, 7, 6, 9, 19, 9, 10, 15, + 11, 12, 14, 13, 16, 18, 17, 20, + 22, 21, 24, 26, 25 +}; + +static const char _JSON_object_trans_actions[] = { + 0, 0, 3, 0, 5, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 +}; -enum {JSON_object_en_main = 1}; +static const int JSON_object_start = 1; +static const int JSON_object_first_final = 27; +static const int JSON_object_error = 0; +static const int JSON_object_en_main = 1; -#line 165 "parser.rl" + +#line 166 "ext/json/ext/parser/parser.rl" static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -125,128 +200,95 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class); - -#line 130 "parser.c" + +#line 205 "ext/json/ext/parser/parser.c" { cs = JSON_object_start; } -#line 180 "parser.rl" - -#line 137 "parser.c" +#line 181 "ext/json/ext/parser/parser.rl" + +#line 212 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_object_trans_keys + _JSON_object_key_offsets[cs]; + _trans = _JSON_object_index_offsets[cs]; + + _klen = _JSON_object_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_object_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_object_indicies[_trans]; + cs = _JSON_object_trans_targs[_trans]; + + if ( _JSON_object_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_object_actions + _JSON_object_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -case 1: - if ( (*p) == 123 ) - goto st2; - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 13: goto st2; - case 32: goto st2; - case 34: goto tr2; - case 47: goto st23; - case 125: goto tr4; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st2; - goto st0; -tr2: -#line 147 "parser.rl" - { - char *np; - json->parsing_name = 1; - np = JSON_parse_string(json, p, pe, &last_name); - json->parsing_name = 0; - if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;} - } - goto st3; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: -#line 178 "parser.c" - switch( (*p) ) { - case 13: goto st3; - case 32: goto st3; - case 47: goto st4; - case 58: goto st8; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st3; - goto st0; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - switch( (*p) ) { - case 42: goto st5; - case 47: goto st7; - } - goto st0; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - if ( (*p) == 42 ) - goto st6; - goto st5; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - switch( (*p) ) { - case 42: goto st6; - case 47: goto st3; - } - goto st5; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - if ( (*p) == 10 ) - goto st3; - goto st7; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - switch( (*p) ) { - case 13: goto st8; - case 32: goto st8; - case 34: goto tr11; - case 45: goto tr11; - case 47: goto st19; - case 73: goto tr11; - case 78: goto tr11; - case 91: goto tr11; - case 102: goto tr11; - case 110: goto tr11; - case 116: goto tr11; - case 123: goto tr11; - } - if ( (*p) > 10 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr11; - } else if ( (*p) >= 9 ) - goto st8; - goto st0; -tr11: -#line 132 "parser.rl" + switch ( *_acts++ ) + { + case 0: +#line 133 "ext/json/ext/parser/parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); if (np == NULL) { - p--; {p++; cs = 9; goto _out;} + p--; {p++; goto _out; } } else { if (NIL_P(json->object_class)) { rb_hash_aset(*result, last_name, v); @@ -256,206 +298,35 @@ case 8: {p = (( np))-1;} } } - goto st9; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: -#line 265 "parser.c" - switch( (*p) ) { - case 13: goto st9; - case 32: goto st9; - case 44: goto st10; - case 47: goto st15; - case 125: goto tr4; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st9; - goto st0; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: - switch( (*p) ) { - case 13: goto st10; - case 32: goto st10; - case 34: goto tr2; - case 47: goto st11; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st10; - goto st0; -st11: - if ( ++p == pe ) - goto _test_eof11; -case 11: - switch( (*p) ) { - case 42: goto st12; - case 47: goto st14; - } - goto st0; -st12: - if ( ++p == pe ) - goto _test_eof12; -case 12: - if ( (*p) == 42 ) - goto st13; - goto st12; -st13: - if ( ++p == pe ) - goto _test_eof13; -case 13: - switch( (*p) ) { - case 42: goto st13; - case 47: goto st10; - } - goto st12; -st14: - if ( ++p == pe ) - goto _test_eof14; -case 14: - if ( (*p) == 10 ) - goto st10; - goto st14; -st15: - if ( ++p == pe ) - goto _test_eof15; -case 15: - switch( (*p) ) { - case 42: goto st16; - case 47: goto st18; - } - goto st0; -st16: - if ( ++p == pe ) - goto _test_eof16; -case 16: - if ( (*p) == 42 ) - goto st17; - goto st16; -st17: - if ( ++p == pe ) - goto _test_eof17; -case 17: - switch( (*p) ) { - case 42: goto st17; - case 47: goto st9; - } - goto st16; -st18: - if ( ++p == pe ) - goto _test_eof18; -case 18: - if ( (*p) == 10 ) - goto st9; - goto st18; -tr4: -#line 155 "parser.rl" - { p--; {p++; cs = 27; goto _out;} } - goto st27; -st27: - if ( ++p == pe ) - goto _test_eof27; -case 27: -#line 361 "parser.c" - goto st0; -st19: - if ( ++p == pe ) - goto _test_eof19; -case 19: - switch( (*p) ) { - case 42: goto st20; - case 47: goto st22; - } - goto st0; -st20: - if ( ++p == pe ) - goto _test_eof20; -case 20: - if ( (*p) == 42 ) - goto st21; - goto st20; -st21: - if ( ++p == pe ) - goto _test_eof21; -case 21: - switch( (*p) ) { - case 42: goto st21; - case 47: goto st8; - } - goto st20; -st22: - if ( ++p == pe ) - goto _test_eof22; -case 22: - if ( (*p) == 10 ) - goto st8; - goto st22; -st23: - if ( ++p == pe ) - goto _test_eof23; -case 23: - switch( (*p) ) { - case 42: goto st24; - case 47: goto st26; - } - goto st0; -st24: - if ( ++p == pe ) - goto _test_eof24; -case 24: - if ( (*p) == 42 ) - goto st25; - goto st24; -st25: - if ( ++p == pe ) - goto _test_eof25; -case 25: - switch( (*p) ) { - case 42: goto st25; - case 47: goto st2; - } - goto st24; -st26: - if ( ++p == pe ) - goto _test_eof26; -case 26: - if ( (*p) == 10 ) - goto st2; - goto st26; - } - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof18: cs = 18; goto _test_eof; - _test_eof27: cs = 27; goto _test_eof; - _test_eof19: cs = 19; goto _test_eof; - _test_eof20: cs = 20; goto _test_eof; - _test_eof21: cs = 21; goto _test_eof; - _test_eof22: cs = 22; goto _test_eof; - _test_eof23: cs = 23; goto _test_eof; - _test_eof24: cs = 24; goto _test_eof; - _test_eof25: cs = 25; goto _test_eof; - _test_eof26: cs = 26; goto _test_eof; - + break; + case 1: +#line 148 "ext/json/ext/parser/parser.rl" + { + char *np; + json->parsing_name = 1; + np = JSON_parse_string(json, p, pe, &last_name); + json->parsing_name = 0; + if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} + } + break; + case 2: +#line 156 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 317 "ext/json/ext/parser/parser.c" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 181 "parser.rl" +#line 182 "ext/json/ext/parser/parser.rl" if (cs >= JSON_object_first_final) { if (json->create_additions) { @@ -480,78 +351,245 @@ case 26: -#line 484 "parser.c" -enum {JSON_value_start = 1}; -enum {JSON_value_first_final = 29}; -enum {JSON_value_error = 0}; +#line 355 "ext/json/ext/parser/parser.c" +static const char _JSON_value_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 1, 4, 1, 5, 1, 6, 1, + 7, 1, 8, 1, 9 +}; + +static const char _JSON_value_key_offsets[] = { + 0, 0, 16, 18, 19, 21, 22, 24, + 25, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47 +}; + +static const char _JSON_value_trans_keys[] = { + 13, 32, 34, 45, 47, 73, 78, 91, + 102, 110, 116, 123, 9, 10, 48, 57, + 42, 47, 42, 42, 47, 10, 42, 47, + 42, 42, 47, 10, 110, 102, 105, 110, + 105, 116, 121, 97, 78, 97, 108, 115, + 101, 117, 108, 108, 114, 117, 101, 13, + 32, 47, 9, 10, 0 +}; + +static const char _JSON_value_single_lengths[] = { + 0, 12, 2, 1, 2, 1, 2, 1, + 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3 +}; + +static const char _JSON_value_range_lengths[] = { + 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1 +}; + +static const char _JSON_value_index_offsets[] = { + 0, 0, 15, 18, 20, 23, 25, 28, + 30, 33, 35, 37, 39, 41, 43, 45, + 47, 49, 51, 53, 55, 57, 59, 61, + 63, 65, 67, 69, 71, 73 +}; + +static const char _JSON_value_trans_targs[] = { + 1, 1, 29, 29, 6, 10, 17, 29, + 19, 23, 26, 29, 1, 29, 0, 3, + 5, 0, 4, 3, 4, 29, 3, 29, + 5, 7, 9, 0, 8, 7, 8, 1, + 7, 1, 9, 11, 0, 12, 0, 13, + 0, 14, 0, 15, 0, 16, 0, 29, + 0, 18, 0, 29, 0, 20, 0, 21, + 0, 22, 0, 29, 0, 24, 0, 25, + 0, 29, 0, 27, 0, 28, 0, 29, + 0, 29, 29, 2, 29, 0, 0 +}; + +static const char _JSON_value_trans_actions[] = { + 0, 0, 11, 13, 0, 0, 0, 15, + 0, 0, 0, 17, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0 +}; + +static const char _JSON_value_from_state_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19 +}; + +static const int JSON_value_start = 1; +static const int JSON_value_first_final = 29; +static const int JSON_value_error = 0; -enum {JSON_value_en_main = 1}; +static const int JSON_value_en_main = 1; -#line 281 "parser.rl" +#line 282 "ext/json/ext/parser/parser.rl" static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) { int cs = EVIL; - -#line 500 "parser.c" + +#line 448 "ext/json/ext/parser/parser.c" { cs = JSON_value_start; } -#line 288 "parser.rl" - -#line 507 "parser.c" +#line 289 "ext/json/ext/parser/parser.rl" + +#line 455 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _acts = _JSON_value_actions + _JSON_value_from_state_actions[cs]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { + switch ( *_acts++ ) { + case 9: +#line 269 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 476 "ext/json/ext/parser/parser.c" + } + } + + _keys = _JSON_value_trans_keys + _JSON_value_key_offsets[cs]; + _trans = _JSON_value_index_offsets[cs]; + + _klen = _JSON_value_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_value_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _JSON_value_trans_targs[_trans]; + + if ( _JSON_value_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_value_actions + _JSON_value_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -st1: - if ( ++p == pe ) - goto _test_eof1; -case 1: - switch( (*p) ) { - case 13: goto st1; - case 32: goto st1; - case 34: goto tr2; - case 45: goto tr3; - case 47: goto st6; - case 73: goto st10; - case 78: goto st17; - case 91: goto tr7; - case 102: goto st19; - case 110: goto st23; - case 116: goto st26; - case 123: goto tr11; - } - if ( (*p) > 10 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr3; - } else if ( (*p) >= 9 ) - goto st1; - goto st0; -st0: -cs = 0; - goto _out; -tr2: -#line 233 "parser.rl" + switch ( *_acts++ ) + { + case 0: +#line 211 "ext/json/ext/parser/parser.rl" + { + *result = Qnil; + } + break; + case 1: +#line 214 "ext/json/ext/parser/parser.rl" + { + *result = Qfalse; + } + break; + case 2: +#line 217 "ext/json/ext/parser/parser.rl" + { + *result = Qtrue; + } + break; + case 3: +#line 220 "ext/json/ext/parser/parser.rl" + { + if (json->allow_nan) { + *result = CNaN; + } else { + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); + } + } + break; + case 4: +#line 227 "ext/json/ext/parser/parser.rl" + { + if (json->allow_nan) { + *result = CInfinity; + } else { + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); + } + } + break; + case 5: +#line 234 "ext/json/ext/parser/parser.rl" { char *np = JSON_parse_string(json, p, pe, result); - if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} } - goto st29; -tr3: -#line 238 "parser.rl" + break; + case 6: +#line 239 "ext/json/ext/parser/parser.rl" { char *np; if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) { if (json->allow_nan) { *result = CMinusInfinity; {p = (( p + 10))-1;} - p--; {p++; cs = 29; goto _out;} + p--; {p++; goto _out; } } else { rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); } @@ -560,311 +598,39 @@ cs = 0; if (np != NULL) {p = (( np))-1;} np = JSON_parse_integer(json, p, pe, result); if (np != NULL) {p = (( np))-1;} - p--; {p++; cs = 29; goto _out;} + p--; {p++; goto _out; } } - goto st29; -tr7: -#line 256 "parser.rl" + break; + case 7: +#line 257 "ext/json/ext/parser/parser.rl" { char *np; np = JSON_parse_array(json, p, pe, result, current_nesting + 1); - if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} } - goto st29; -tr11: -#line 262 "parser.rl" + break; + case 8: +#line 263 "ext/json/ext/parser/parser.rl" { char *np; np = JSON_parse_object(json, p, pe, result, current_nesting + 1); - if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} - } - goto st29; -tr25: -#line 226 "parser.rl" - { - if (json->allow_nan) { - *result = CInfinity; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); - } + if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} } - goto st29; -tr27: -#line 219 "parser.rl" - { - if (json->allow_nan) { - *result = CNaN; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); - } - } - goto st29; -tr31: -#line 213 "parser.rl" - { - *result = Qfalse; - } - goto st29; -tr34: -#line 210 "parser.rl" - { - *result = Qnil; - } - goto st29; -tr37: -#line 216 "parser.rl" - { - *result = Qtrue; - } - goto st29; -st29: - if ( ++p == pe ) - goto _test_eof29; -case 29: -#line 268 "parser.rl" - { p--; {p++; cs = 29; goto _out;} } -#line 627 "parser.c" - switch( (*p) ) { - case 13: goto st29; - case 32: goto st29; - case 47: goto st2; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st29; - goto st0; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 42: goto st3; - case 47: goto st5; - } - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - if ( (*p) == 42 ) - goto st4; - goto st3; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - switch( (*p) ) { - case 42: goto st4; - case 47: goto st29; + break; +#line 621 "ext/json/ext/parser/parser.c" + } } - goto st3; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - if ( (*p) == 10 ) - goto st29; - goto st5; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - switch( (*p) ) { - case 42: goto st7; - case 47: goto st9; - } - goto st0; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - if ( (*p) == 42 ) - goto st8; - goto st7; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - switch( (*p) ) { - case 42: goto st8; - case 47: goto st1; - } - goto st7; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: - if ( (*p) == 10 ) - goto st1; - goto st9; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: - if ( (*p) == 110 ) - goto st11; - goto st0; -st11: - if ( ++p == pe ) - goto _test_eof11; -case 11: - if ( (*p) == 102 ) - goto st12; - goto st0; -st12: - if ( ++p == pe ) - goto _test_eof12; -case 12: - if ( (*p) == 105 ) - goto st13; - goto st0; -st13: - if ( ++p == pe ) - goto _test_eof13; -case 13: - if ( (*p) == 110 ) - goto st14; - goto st0; -st14: - if ( ++p == pe ) - goto _test_eof14; -case 14: - if ( (*p) == 105 ) - goto st15; - goto st0; -st15: - if ( ++p == pe ) - goto _test_eof15; -case 15: - if ( (*p) == 116 ) - goto st16; - goto st0; -st16: - if ( ++p == pe ) - goto _test_eof16; -case 16: - if ( (*p) == 121 ) - goto tr25; - goto st0; -st17: - if ( ++p == pe ) - goto _test_eof17; -case 17: - if ( (*p) == 97 ) - goto st18; - goto st0; -st18: - if ( ++p == pe ) - goto _test_eof18; -case 18: - if ( (*p) == 78 ) - goto tr27; - goto st0; -st19: - if ( ++p == pe ) - goto _test_eof19; -case 19: - if ( (*p) == 97 ) - goto st20; - goto st0; -st20: - if ( ++p == pe ) - goto _test_eof20; -case 20: - if ( (*p) == 108 ) - goto st21; - goto st0; -st21: - if ( ++p == pe ) - goto _test_eof21; -case 21: - if ( (*p) == 115 ) - goto st22; - goto st0; -st22: - if ( ++p == pe ) - goto _test_eof22; -case 22: - if ( (*p) == 101 ) - goto tr31; - goto st0; -st23: - if ( ++p == pe ) - goto _test_eof23; -case 23: - if ( (*p) == 117 ) - goto st24; - goto st0; -st24: - if ( ++p == pe ) - goto _test_eof24; -case 24: - if ( (*p) == 108 ) - goto st25; - goto st0; -st25: - if ( ++p == pe ) - goto _test_eof25; -case 25: - if ( (*p) == 108 ) - goto tr34; - goto st0; -st26: - if ( ++p == pe ) - goto _test_eof26; -case 26: - if ( (*p) == 114 ) - goto st27; - goto st0; -st27: - if ( ++p == pe ) - goto _test_eof27; -case 27: - if ( (*p) == 117 ) - goto st28; - goto st0; -st28: - if ( ++p == pe ) - goto _test_eof28; -case 28: - if ( (*p) == 101 ) - goto tr37; - goto st0; - } - _test_eof1: cs = 1; goto _test_eof; - _test_eof29: cs = 29; goto _test_eof; - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof18: cs = 18; goto _test_eof; - _test_eof19: cs = 19; goto _test_eof; - _test_eof20: cs = 20; goto _test_eof; - _test_eof21: cs = 21; goto _test_eof; - _test_eof22: cs = 22; goto _test_eof; - _test_eof23: cs = 23; goto _test_eof; - _test_eof24: cs = 24; goto _test_eof; - _test_eof25: cs = 25; goto _test_eof; - _test_eof26: cs = 26; goto _test_eof; - _test_eof27: cs = 27; goto _test_eof; - _test_eof28: cs = 28; goto _test_eof; +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 289 "parser.rl" +#line 290 "ext/json/ext/parser/parser.rl" if (cs >= JSON_value_first_final) { return p; @@ -874,91 +640,160 @@ case 28: } -#line 878 "parser.c" -enum {JSON_integer_start = 1}; -enum {JSON_integer_first_final = 3}; -enum {JSON_integer_error = 0}; +#line 644 "ext/json/ext/parser/parser.c" +static const char _JSON_integer_actions[] = { + 0, 1, 0 +}; + +static const char _JSON_integer_key_offsets[] = { + 0, 0, 4, 7, 9, 9 +}; + +static const char _JSON_integer_trans_keys[] = { + 45, 48, 49, 57, 48, 49, 57, 48, + 57, 48, 57, 0 +}; + +static const char _JSON_integer_single_lengths[] = { + 0, 2, 1, 0, 0, 0 +}; + +static const char _JSON_integer_range_lengths[] = { + 0, 1, 1, 1, 0, 1 +}; + +static const char _JSON_integer_index_offsets[] = { + 0, 0, 4, 7, 9, 10 +}; + +static const char _JSON_integer_indicies[] = { + 0, 2, 3, 1, 2, 3, 1, 1, + 4, 1, 3, 4, 0 +}; + +static const char _JSON_integer_trans_targs[] = { + 2, 0, 3, 5, 4 +}; + +static const char _JSON_integer_trans_actions[] = { + 0, 0, 0, 0, 1 +}; + +static const int JSON_integer_start = 1; +static const int JSON_integer_first_final = 3; +static const int JSON_integer_error = 0; -enum {JSON_integer_en_main = 1}; +static const int JSON_integer_en_main = 1; -#line 305 "parser.rl" +#line 306 "ext/json/ext/parser/parser.rl" static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; - -#line 894 "parser.c" + +#line 698 "ext/json/ext/parser/parser.c" { cs = JSON_integer_start; } -#line 312 "parser.rl" +#line 313 "ext/json/ext/parser/parser.rl" json->memo = p; - -#line 902 "parser.c" + +#line 706 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_integer_trans_keys + _JSON_integer_key_offsets[cs]; + _trans = _JSON_integer_index_offsets[cs]; + + _klen = _JSON_integer_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_integer_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_integer_indicies[_trans]; + cs = _JSON_integer_trans_targs[_trans]; + + if ( _JSON_integer_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_integer_actions + _JSON_integer_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -case 1: - switch( (*p) ) { - case 45: goto st2; - case 48: goto st3; - } - if ( 49 <= (*p) && (*p) <= 57 ) - goto st5; - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - if ( (*p) == 48 ) - goto st3; - if ( 49 <= (*p) && (*p) <= 57 ) - goto st5; - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st0; - goto tr4; -tr4: -#line 302 "parser.rl" - { p--; {p++; cs = 4; goto _out;} } - goto st4; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: -#line 943 "parser.c" - goto st0; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st5; - goto tr4; - } - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - + switch ( *_acts++ ) + { + case 0: +#line 303 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 784 "ext/json/ext/parser/parser.c" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 314 "parser.rl" +#line 315 "ext/json/ext/parser/parser.rl" if (cs >= JSON_integer_first_final) { long len = p - json->memo; @@ -973,164 +808,186 @@ case 5: } -#line 977 "parser.c" -enum {JSON_float_start = 1}; -enum {JSON_float_first_final = 8}; -enum {JSON_float_error = 0}; +#line 812 "ext/json/ext/parser/parser.c" +static const char _JSON_float_actions[] = { + 0, 1, 0 +}; + +static const char _JSON_float_key_offsets[] = { + 0, 0, 4, 7, 10, 12, 16, 18, + 23, 29, 29 +}; + +static const char _JSON_float_trans_keys[] = { + 45, 48, 49, 57, 48, 49, 57, 46, + 69, 101, 48, 57, 43, 45, 48, 57, + 48, 57, 46, 69, 101, 48, 57, 69, + 101, 45, 46, 48, 57, 69, 101, 45, + 46, 48, 57, 0 +}; + +static const char _JSON_float_single_lengths[] = { + 0, 2, 1, 3, 0, 2, 0, 3, + 2, 0, 2 +}; + +static const char _JSON_float_range_lengths[] = { + 0, 1, 1, 0, 1, 1, 1, 1, + 2, 0, 2 +}; + +static const char _JSON_float_index_offsets[] = { + 0, 0, 4, 7, 11, 13, 17, 19, + 24, 29, 30 +}; + +static const char _JSON_float_indicies[] = { + 0, 2, 3, 1, 2, 3, 1, 4, + 5, 5, 1, 6, 1, 7, 7, 8, + 1, 8, 1, 4, 5, 5, 3, 1, + 5, 5, 1, 6, 9, 1, 1, 1, + 1, 8, 9, 0 +}; + +static const char _JSON_float_trans_targs[] = { + 2, 0, 3, 7, 4, 5, 8, 6, + 10, 9 +}; + +static const char _JSON_float_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1 +}; + +static const int JSON_float_start = 1; +static const int JSON_float_first_final = 8; +static const int JSON_float_error = 0; -enum {JSON_float_en_main = 1}; +static const int JSON_float_en_main = 1; -#line 339 "parser.rl" +#line 340 "ext/json/ext/parser/parser.rl" static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; - -#line 993 "parser.c" + +#line 878 "ext/json/ext/parser/parser.c" { cs = JSON_float_start; } -#line 346 "parser.rl" +#line 347 "ext/json/ext/parser/parser.rl" json->memo = p; - -#line 1001 "parser.c" + +#line 886 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_float_trans_keys + _JSON_float_key_offsets[cs]; + _trans = _JSON_float_index_offsets[cs]; + + _klen = _JSON_float_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_float_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_float_indicies[_trans]; + cs = _JSON_float_trans_targs[_trans]; + + if ( _JSON_float_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_float_actions + _JSON_float_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -case 1: - switch( (*p) ) { - case 45: goto st2; - case 48: goto st3; - } - if ( 49 <= (*p) && (*p) <= 57 ) - goto st7; - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - if ( (*p) == 48 ) - goto st3; - if ( 49 <= (*p) && (*p) <= 57 ) - goto st7; - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - switch( (*p) ) { - case 46: goto st4; - case 69: goto st5; - case 101: goto st5; - } - goto st0; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st8; - goto st0; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - switch( (*p) ) { - case 69: goto st5; - case 101: goto st5; - } - if ( (*p) > 46 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st8; - } else if ( (*p) >= 45 ) - goto st0; - goto tr9; -tr9: -#line 333 "parser.rl" - { p--; {p++; cs = 9; goto _out;} } - goto st9; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: -#line 1066 "parser.c" - goto st0; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - switch( (*p) ) { - case 43: goto st6; - case 45: goto st6; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st10; - goto st0; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st10; - goto st0; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: - switch( (*p) ) { - case 69: goto st0; - case 101: goto st0; - } - if ( (*p) > 46 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st10; - } else if ( (*p) >= 45 ) - goto st0; - goto tr9; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - switch( (*p) ) { - case 46: goto st4; - case 69: goto st5; - case 101: goto st5; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st7; - goto st0; - } - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - + switch ( *_acts++ ) + { + case 0: +#line 334 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 964 "ext/json/ext/parser/parser.c" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 348 "parser.rl" +#line 349 "ext/json/ext/parser/parser.rl" if (cs >= JSON_float_first_final) { long len = p - json->memo; fbuffer_clear(json->fbuffer); fbuffer_append(json->fbuffer, json->memo, len); fbuffer_append_char(json->fbuffer, '\0'); - *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); + if (NIL_P(json->decimal_class)) { + *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); + } + else { + VALUE text; + text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); + *result = rb_funcall(json->decimal_class, i_new, 1, text); + } return p + 1; } else { return NULL; @@ -1139,15 +996,78 @@ case 7: -#line 1143 "parser.c" -enum {JSON_array_start = 1}; -enum {JSON_array_first_final = 17}; -enum {JSON_array_error = 0}; +#line 1000 "ext/json/ext/parser/parser.c" +static const char _JSON_array_actions[] = { + 0, 1, 0, 1, 1 +}; -enum {JSON_array_en_main = 1}; +static const char _JSON_array_key_offsets[] = { + 0, 0, 1, 18, 25, 41, 43, 44, + 46, 47, 49, 50, 52, 53, 55, 56, + 58, 59 +}; +static const char _JSON_array_trans_keys[] = { + 91, 13, 32, 34, 45, 47, 73, 78, + 91, 93, 102, 110, 116, 123, 9, 10, + 48, 57, 13, 32, 44, 47, 93, 9, + 10, 13, 32, 34, 45, 47, 73, 78, + 91, 102, 110, 116, 123, 9, 10, 48, + 57, 42, 47, 42, 42, 47, 10, 42, + 47, 42, 42, 47, 10, 42, 47, 42, + 42, 47, 10, 0 +}; -#line 391 "parser.rl" +static const char _JSON_array_single_lengths[] = { + 0, 1, 13, 5, 12, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 0 +}; + +static const char _JSON_array_range_lengths[] = { + 0, 0, 2, 1, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +static const char _JSON_array_index_offsets[] = { + 0, 0, 2, 18, 25, 40, 43, 45, + 48, 50, 53, 55, 58, 60, 63, 65, + 68, 70 +}; + +static const char _JSON_array_indicies[] = { + 0, 1, 0, 0, 2, 2, 3, 2, + 2, 2, 4, 2, 2, 2, 2, 0, + 2, 1, 5, 5, 6, 7, 4, 5, + 1, 6, 6, 2, 2, 8, 2, 2, + 2, 2, 2, 2, 2, 6, 2, 1, + 9, 10, 1, 11, 9, 11, 6, 9, + 6, 10, 12, 13, 1, 14, 12, 14, + 5, 12, 5, 13, 15, 16, 1, 17, + 15, 17, 0, 15, 0, 16, 1, 0 +}; + +static const char _JSON_array_trans_targs[] = { + 2, 0, 3, 13, 17, 3, 4, 9, + 5, 6, 8, 7, 10, 12, 11, 14, + 16, 15 +}; + +static const char _JSON_array_trans_actions[] = { + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +static const int JSON_array_start = 1; +static const int JSON_array_first_final = 17; +static const int JSON_array_error = 0; + +static const int JSON_array_en_main = 1; + + +#line 399 "ext/json/ext/parser/parser.rl" static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -1160,59 +1080,95 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul } *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); - -#line 1165 "parser.c" + +#line 1085 "ext/json/ext/parser/parser.c" { cs = JSON_array_start; } -#line 404 "parser.rl" - -#line 1172 "parser.c" +#line 412 "ext/json/ext/parser/parser.rl" + +#line 1092 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_array_trans_keys + _JSON_array_key_offsets[cs]; + _trans = _JSON_array_index_offsets[cs]; + + _klen = _JSON_array_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_array_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_array_indicies[_trans]; + cs = _JSON_array_trans_targs[_trans]; + + if ( _JSON_array_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_array_actions + _JSON_array_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -case 1: - if ( (*p) == 91 ) - goto st2; - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 13: goto st2; - case 32: goto st2; - case 34: goto tr2; - case 45: goto tr2; - case 47: goto st13; - case 73: goto tr2; - case 78: goto tr2; - case 91: goto tr2; - case 93: goto tr4; - case 102: goto tr2; - case 110: goto tr2; - case 116: goto tr2; - case 123: goto tr2; - } - if ( (*p) > 10 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr2; - } else if ( (*p) >= 9 ) - goto st2; - goto st0; -tr2: -#line 368 "parser.rl" + switch ( *_acts++ ) + { + case 0: +#line 376 "ext/json/ext/parser/parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); if (np == NULL) { - p--; {p++; cs = 3; goto _out;} + p--; {p++; goto _out; } } else { if (NIL_P(json->array_class)) { rb_ary_push(*result, v); @@ -1222,175 +1178,25 @@ case 2: {p = (( np))-1;} } } - goto st3; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: -#line 1231 "parser.c" - switch( (*p) ) { - case 13: goto st3; - case 32: goto st3; - case 44: goto st4; - case 47: goto st9; - case 93: goto tr4; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st3; - goto st0; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - switch( (*p) ) { - case 13: goto st4; - case 32: goto st4; - case 34: goto tr2; - case 45: goto tr2; - case 47: goto st5; - case 73: goto tr2; - case 78: goto tr2; - case 91: goto tr2; - case 102: goto tr2; - case 110: goto tr2; - case 116: goto tr2; - case 123: goto tr2; - } - if ( (*p) > 10 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr2; - } else if ( (*p) >= 9 ) - goto st4; - goto st0; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - switch( (*p) ) { - case 42: goto st6; - case 47: goto st8; - } - goto st0; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - if ( (*p) == 42 ) - goto st7; - goto st6; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - switch( (*p) ) { - case 42: goto st7; - case 47: goto st4; - } - goto st6; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - if ( (*p) == 10 ) - goto st4; - goto st8; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: - switch( (*p) ) { - case 42: goto st10; - case 47: goto st12; - } - goto st0; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: - if ( (*p) == 42 ) - goto st11; - goto st10; -st11: - if ( ++p == pe ) - goto _test_eof11; -case 11: - switch( (*p) ) { - case 42: goto st11; - case 47: goto st3; - } - goto st10; -st12: - if ( ++p == pe ) - goto _test_eof12; -case 12: - if ( (*p) == 10 ) - goto st3; - goto st12; -tr4: -#line 383 "parser.rl" - { p--; {p++; cs = 17; goto _out;} } - goto st17; -st17: - if ( ++p == pe ) - goto _test_eof17; -case 17: -#line 1338 "parser.c" - goto st0; -st13: - if ( ++p == pe ) - goto _test_eof13; -case 13: - switch( (*p) ) { - case 42: goto st14; - case 47: goto st16; - } - goto st0; -st14: - if ( ++p == pe ) - goto _test_eof14; -case 14: - if ( (*p) == 42 ) - goto st15; - goto st14; -st15: - if ( ++p == pe ) - goto _test_eof15; -case 15: - switch( (*p) ) { - case 42: goto st15; - case 47: goto st2; - } - goto st14; -st16: - if ( ++p == pe ) - goto _test_eof16; -case 16: - if ( (*p) == 10 ) - goto st2; - goto st16; - } - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - + break; + case 1: +#line 391 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 1187 "ext/json/ext/parser/parser.c" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 405 "parser.rl" +#line 413 "ext/json/ext/parser/parser.rl" if(cs >= JSON_array_first_final) { return p + 1; @@ -1471,15 +1277,62 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1475 "parser.c" -enum {JSON_string_start = 1}; -enum {JSON_string_first_final = 8}; -enum {JSON_string_error = 0}; +#line 1281 "ext/json/ext/parser/parser.c" +static const char _JSON_string_actions[] = { + 0, 2, 0, 1 +}; -enum {JSON_string_en_main = 1}; +static const char _JSON_string_key_offsets[] = { + 0, 0, 1, 5, 8, 14, 20, 26, + 32 +}; +static const char _JSON_string_trans_keys[] = { + 34, 34, 92, 0, 31, 117, 0, 31, + 48, 57, 65, 70, 97, 102, 48, 57, + 65, 70, 97, 102, 48, 57, 65, 70, + 97, 102, 48, 57, 65, 70, 97, 102, + 0 +}; -#line 504 "parser.rl" +static const char _JSON_string_single_lengths[] = { + 0, 1, 2, 1, 0, 0, 0, 0, + 0 +}; + +static const char _JSON_string_range_lengths[] = { + 0, 0, 1, 1, 3, 3, 3, 3, + 0 +}; + +static const char _JSON_string_index_offsets[] = { + 0, 0, 2, 6, 9, 13, 17, 21, + 25 +}; + +static const char _JSON_string_indicies[] = { + 0, 1, 2, 3, 1, 0, 4, 1, + 0, 5, 5, 5, 1, 6, 6, 6, + 1, 7, 7, 7, 1, 0, 0, 0, + 1, 1, 0 +}; + +static const char _JSON_string_trans_targs[] = { + 2, 0, 8, 3, 4, 5, 6, 7 +}; + +static const char _JSON_string_trans_actions[] = { + 0, 0, 1, 0, 0, 0, 0, 0 +}; + +static const int JSON_string_start = 1; +static const int JSON_string_first_final = 8; +static const int JSON_string_error = 0; + +static const int JSON_string_en_main = 1; + + +#line 512 "ext/json/ext/parser/parser.rl" static int @@ -1500,135 +1353,120 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu VALUE match_string; *result = rb_str_buf_new(0); - -#line 1505 "parser.c" + +#line 1358 "ext/json/ext/parser/parser.c" { cs = JSON_string_start; } -#line 525 "parser.rl" +#line 533 "ext/json/ext/parser/parser.rl" json->memo = p; - -#line 1513 "parser.c" + +#line 1366 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_string_trans_keys + _JSON_string_key_offsets[cs]; + _trans = _JSON_string_index_offsets[cs]; + + _klen = _JSON_string_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_string_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_string_indicies[_trans]; + cs = _JSON_string_trans_targs[_trans]; + + if ( _JSON_string_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_string_actions + _JSON_string_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -case 1: - if ( (*p) == 34 ) - goto st2; - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 34: goto tr2; - case 92: goto st3; - } - if ( 0 <= (*p) && (*p) <= 31 ) - goto st0; - goto st2; -tr2: -#line 490 "parser.rl" + switch ( *_acts++ ) + { + case 0: +#line 498 "ext/json/ext/parser/parser.rl" { *result = json_string_unescape(*result, json->memo + 1, p); if (NIL_P(*result)) { p--; - {p++; cs = 8; goto _out;} + {p++; goto _out; } } else { FORCE_UTF8(*result); {p = (( p + 1))-1;} } } -#line 501 "parser.rl" - { p--; {p++; cs = 8; goto _out;} } - goto st8; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: -#line 1556 "parser.c" - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - if ( (*p) == 117 ) - goto st4; - if ( 0 <= (*p) && (*p) <= 31 ) - goto st0; - goto st2; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st5; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st5; - } else - goto st5; - goto st0; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st6; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st6; - } else - goto st6; - goto st0; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st7; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st7; - } else - goto st7; - goto st0; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st2; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st2; - } else - goto st2; - goto st0; - } - _test_eof2: cs = 2; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - + break; + case 1: +#line 509 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 1457 "ext/json/ext/parser/parser.c" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 527 "parser.rl" +#line 535 "ext/json/ext/parser/parser.rl" if (json->create_additions && RTEST(match_string = json->match_string)) { VALUE klass; @@ -1781,6 +1619,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->array_class = Qnil; } + tmp = ID2SYM(i_decimal_class); + if (option_given_p(opts, tmp)) { + json->decimal_class = rb_hash_aref(opts, tmp); + } else { + json->decimal_class = Qnil; + } tmp = ID2SYM(i_match_string); if (option_given_p(opts, tmp)) { VALUE match_string = rb_hash_aref(opts, tmp); @@ -1798,6 +1642,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) json->create_id = rb_funcall(mJSON, i_create_id, 0); json->object_class = Qnil; json->array_class = Qnil; + json->decimal_class = Qnil; } source = convert_encoding(StringValue(source)); StringValue(source); @@ -1808,15 +1653,66 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1812 "parser.c" -enum {JSON_start = 1}; -enum {JSON_first_final = 10}; -enum {JSON_error = 0}; +#line 1657 "ext/json/ext/parser/parser.c" +static const char _JSON_actions[] = { + 0, 1, 0 +}; -enum {JSON_en_main = 1}; +static const char _JSON_key_offsets[] = { + 0, 0, 16, 18, 19, 21, 22, 24, + 25, 27, 28 +}; +static const char _JSON_trans_keys[] = { + 13, 32, 34, 45, 47, 73, 78, 91, + 102, 110, 116, 123, 9, 10, 48, 57, + 42, 47, 42, 42, 47, 10, 42, 47, + 42, 42, 47, 10, 13, 32, 47, 9, + 10, 0 +}; -#line 720 "parser.rl" +static const char _JSON_single_lengths[] = { + 0, 12, 2, 1, 2, 1, 2, 1, + 2, 1, 3 +}; + +static const char _JSON_range_lengths[] = { + 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 1 +}; + +static const char _JSON_index_offsets[] = { + 0, 0, 15, 18, 20, 23, 25, 28, + 30, 33, 35 +}; + +static const char _JSON_indicies[] = { + 0, 0, 2, 2, 3, 2, 2, 2, + 2, 2, 2, 2, 0, 2, 1, 4, + 5, 1, 6, 4, 6, 7, 4, 7, + 5, 8, 9, 1, 10, 8, 10, 0, + 8, 0, 9, 7, 7, 11, 7, 1, + 0 +}; + +static const char _JSON_trans_targs[] = { + 1, 0, 10, 6, 3, 5, 4, 10, + 7, 9, 8, 2 +}; + +static const char _JSON_trans_actions[] = { + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; + +static const int JSON_start = 1; +static const int JSON_first_final = 10; +static const int JSON_error = 0; + +static const int JSON_en_main = 1; + + +#line 735 "ext/json/ext/parser/parser.rl" /* @@ -1832,150 +1728,111 @@ static VALUE cParser_parse(VALUE self) VALUE result = Qnil; GET_PARSER; - -#line 1837 "parser.c" + +#line 1733 "ext/json/ext/parser/parser.c" { cs = JSON_start; } -#line 736 "parser.rl" +#line 751 "ext/json/ext/parser/parser.rl" p = json->source; pe = p + json->len; - -#line 1846 "parser.c" + +#line 1742 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_trans_keys + _JSON_key_offsets[cs]; + _trans = _JSON_index_offsets[cs]; + + _klen = _JSON_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_indicies[_trans]; + cs = _JSON_trans_targs[_trans]; + + if ( _JSON_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_actions + _JSON_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -st1: - if ( ++p == pe ) - goto _test_eof1; -case 1: - switch( (*p) ) { - case 13: goto st1; - case 32: goto st1; - case 34: goto tr2; - case 45: goto tr2; - case 47: goto st6; - case 73: goto tr2; - case 78: goto tr2; - case 91: goto tr2; - case 102: goto tr2; - case 110: goto tr2; - case 116: goto tr2; - case 123: goto tr2; - } - if ( (*p) > 10 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr2; - } else if ( (*p) >= 9 ) - goto st1; - goto st0; -st0: -cs = 0; - goto _out; -tr2: -#line 712 "parser.rl" + switch ( *_acts++ ) + { + case 0: +#line 727 "ext/json/ext/parser/parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); - if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} } - goto st10; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: -#line 1890 "parser.c" - switch( (*p) ) { - case 13: goto st10; - case 32: goto st10; - case 47: goto st2; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st10; - goto st0; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 42: goto st3; - case 47: goto st5; - } - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - if ( (*p) == 42 ) - goto st4; - goto st3; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - switch( (*p) ) { - case 42: goto st4; - case 47: goto st10; - } - goto st3; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - if ( (*p) == 10 ) - goto st10; - goto st5; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - switch( (*p) ) { - case 42: goto st7; - case 47: goto st9; - } - goto st0; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - if ( (*p) == 42 ) - goto st8; - goto st7; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - switch( (*p) ) { - case 42: goto st8; - case 47: goto st1; - } - goto st7; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: - if ( (*p) == 10 ) - goto st1; - goto st9; + break; +#line 1823 "ext/json/ext/parser/parser.c" + } } - _test_eof1: cs = 1; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 739 "parser.rl" +#line 754 "ext/json/ext/parser/parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -1992,6 +1849,7 @@ static void JSON_mark(void *ptr) rb_gc_mark_maybe(json->create_id); rb_gc_mark_maybe(json->object_class); rb_gc_mark_maybe(json->array_class); + rb_gc_mark_maybe(json->decimal_class); rb_gc_mark_maybe(json->match_string); } @@ -2066,6 +1924,7 @@ void Init_parser(void) i_symbolize_names = rb_intern("symbolize_names"); i_object_class = rb_intern("object_class"); i_array_class = rb_intern("array_class"); + i_decimal_class = rb_intern("decimal_class"); i_match = rb_intern("match"); i_match_string = rb_intern("match_string"); i_key_p = rb_intern("key?"); diff --git a/ext/json/ext/parser/parser.h b/ext/json/ext/parser/parser.h index 1d4683196..e6cf77902 100644 --- a/ext/json/ext/parser/parser.h +++ b/ext/json/ext/parser/parser.h @@ -39,6 +39,7 @@ typedef struct JSON_ParserStruct { int symbolize_names; VALUE object_class; VALUE array_class; + VALUE decimal_class; int create_additions; VALUE match_string; FBuffer *fbuffer; diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index dd24cf94c..03b4c892e 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -92,8 +92,9 @@ static VALUE CNaN, CInfinity, CMinusInfinity; static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, - i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match, - i_match_string, i_aset, i_aref, i_leftshift; + i_object_class, i_array_class, i_decimal_class, i_key_p, + i_deep_const_get, i_match, i_match_string, i_aset, i_aref, + i_leftshift, i_new; %%{ machine JSON_common; @@ -351,7 +352,14 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul fbuffer_clear(json->fbuffer); fbuffer_append(json->fbuffer, json->memo, len); fbuffer_append_char(json->fbuffer, '\0'); - *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); + if (NIL_P(json->decimal_class)) { + *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); + } + else { + VALUE text; + text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); + *result = rb_funcall(json->decimal_class, i_new, 1, text); + } return p + 1; } else { return NULL; @@ -676,6 +684,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->array_class = Qnil; } + tmp = ID2SYM(i_decimal_class); + if (option_given_p(opts, tmp)) { + json->decimal_class = rb_hash_aref(opts, tmp); + } else { + json->decimal_class = Qnil; + } tmp = ID2SYM(i_match_string); if (option_given_p(opts, tmp)) { VALUE match_string = rb_hash_aref(opts, tmp); @@ -693,6 +707,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) json->create_id = rb_funcall(mJSON, i_create_id, 0); json->object_class = Qnil; json->array_class = Qnil; + json->decimal_class = Qnil; } source = convert_encoding(StringValue(source)); StringValue(source); @@ -752,6 +767,7 @@ static void JSON_mark(void *ptr) rb_gc_mark_maybe(json->create_id); rb_gc_mark_maybe(json->object_class); rb_gc_mark_maybe(json->array_class); + rb_gc_mark_maybe(json->decimal_class); rb_gc_mark_maybe(json->match_string); } @@ -826,6 +842,7 @@ void Init_parser(void) i_symbolize_names = rb_intern("symbolize_names"); i_object_class = rb_intern("object_class"); i_array_class = rb_intern("array_class"); + i_decimal_class = rb_intern("decimal_class"); i_match = rb_intern("match"); i_match_string = rb_intern("match_string"); i_key_p = rb_intern("key?"); diff --git a/json-java.gemspec b/java/json.gemspec similarity index 85% rename from json-java.gemspec rename to java/json.gemspec index 1524b1f9a..e0e4efefc 100644 --- a/json-java.gemspec +++ b/java/json.gemspec @@ -3,7 +3,11 @@ require "rubygems" spec = Gem::Specification.new do |s| s.name = "json" - s.version = File.read("VERSION").chomp + s.version = if File.exist?('VERSION') + File.read("VERSION").chomp + else + File.read("../VERSION").chomp + end s.summary = "JSON implementation for JRuby" s.description = "A JSON implementation as a JRuby extension." s.author = "Daniel Luz" diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index 2a7d9f544..2ba9f8fc2 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -54,6 +54,7 @@ public class Parser extends RubyObject { private boolean symbolizeNames; private RubyClass objectClass; private RubyClass arrayClass; + private RubyClass decimalClass; private RubyHash matchString; private static final int DEFAULT_MAX_NESTING = 100; @@ -133,6 +134,10 @@ public Parser(Ruby runtime, RubyClass metaClass) { *

:array_class *
Defaults to Array. * + *
:decimal_class + *
Specifies which class to use instead of the default (Float) when + * parsing decimal numbers. This class must accept a single string argument + * in its constructor. * */ @JRubyMethod(name = "new", required = 1, optional = 1, meta = true) @@ -159,6 +164,7 @@ public IRubyObject initialize(ThreadContext context, IRubyObject[] args) { this.createAdditions = opts.getBool("create_additions", false); this.objectClass = opts.getClass("object_class", runtime.getHash()); this.arrayClass = opts.getClass("array_class", runtime.getArray()); + this.decimalClass = opts.getClass("decimal_class", null); this.matchString = opts.getHash("match_string"); if(symbolizeNames && createAdditions) { @@ -307,11 +313,11 @@ private Ruby getRuntime() { } -// line 333 "Parser.rl" +// line 339 "Parser.rl" -// line 315 "Parser.java" +// line 321 "Parser.java" private static byte[] init__JSON_value_actions_0() { return new byte [] { @@ -425,7 +431,7 @@ private static byte[] init__JSON_value_from_state_actions_0() static final int JSON_value_en_main = 1; -// line 439 "Parser.rl" +// line 445 "Parser.rl" void parseValue(ParserResult res, int p, int pe) { @@ -433,14 +439,14 @@ void parseValue(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 437 "Parser.java" +// line 443 "Parser.java" { cs = JSON_value_start; } -// line 446 "Parser.rl" +// line 452 "Parser.rl" -// line 444 "Parser.java" +// line 450 "Parser.java" { int _klen; int _trans = 0; @@ -466,13 +472,13 @@ void parseValue(ParserResult res, int p, int pe) { while ( _nacts-- > 0 ) { switch ( _JSON_value_actions[_acts++] ) { case 9: -// line 424 "Parser.rl" +// line 430 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 476 "Parser.java" +// line 482 "Parser.java" } } @@ -535,25 +541,25 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) switch ( _JSON_value_actions[_acts++] ) { case 0: -// line 341 "Parser.rl" +// line 347 "Parser.rl" { result = getRuntime().getNil(); } break; case 1: -// line 344 "Parser.rl" +// line 350 "Parser.rl" { result = getRuntime().getFalse(); } break; case 2: -// line 347 "Parser.rl" +// line 353 "Parser.rl" { result = getRuntime().getTrue(); } break; case 3: -// line 350 "Parser.rl" +// line 356 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_NAN); @@ -563,7 +569,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 4: -// line 357 "Parser.rl" +// line 363 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_INFINITY); @@ -573,7 +579,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 5: -// line 364 "Parser.rl" +// line 370 "Parser.rl" { if (pe > p + 8 && absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) { @@ -602,7 +608,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 6: -// line 390 "Parser.rl" +// line 396 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -615,7 +621,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 7: -// line 400 "Parser.rl" +// line 406 "Parser.rl" { currentNesting++; parseArray(res, p, pe); @@ -630,7 +636,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } break; case 8: -// line 412 "Parser.rl" +// line 418 "Parser.rl" { currentNesting++; parseObject(res, p, pe); @@ -644,7 +650,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } } break; -// line 648 "Parser.java" +// line 654 "Parser.java" } } } @@ -664,7 +670,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) break; } } -// line 447 "Parser.rl" +// line 453 "Parser.rl" if (cs >= JSON_value_first_final && result != null) { res.update(result, p); @@ -674,7 +680,7 @@ else if ( data[p] > _JSON_value_trans_keys[_mid+1] ) } -// line 678 "Parser.java" +// line 684 "Parser.java" private static byte[] init__JSON_integer_actions_0() { return new byte [] { @@ -773,7 +779,7 @@ private static byte[] init__JSON_integer_trans_actions_0() static final int JSON_integer_en_main = 1; -// line 466 "Parser.rl" +// line 472 "Parser.rl" void parseInteger(ParserResult res, int p, int pe) { @@ -791,15 +797,15 @@ int parseIntegerInternal(int p, int pe) { int cs = EVIL; -// line 795 "Parser.java" +// line 801 "Parser.java" { cs = JSON_integer_start; } -// line 483 "Parser.rl" +// line 489 "Parser.rl" int memo = p; -// line 803 "Parser.java" +// line 809 "Parser.java" { int _klen; int _trans = 0; @@ -880,13 +886,13 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) switch ( _JSON_integer_actions[_acts++] ) { case 0: -// line 460 "Parser.rl" +// line 466 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 890 "Parser.java" +// line 896 "Parser.java" } } } @@ -906,7 +912,7 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) break; } } -// line 485 "Parser.rl" +// line 491 "Parser.rl" if (cs < JSON_integer_first_final) { return -1; @@ -914,13 +920,13 @@ else if ( data[p] > _JSON_integer_trans_keys[_mid+1] ) return p; } - + RubyInteger createInteger(int p, int new_p) { Ruby runtime = getRuntime(); ByteList num = absSubSequence(p, new_p); return bytesToInum(runtime, num); } - + RubyInteger bytesToInum(Ruby runtime, ByteList num) { return runtime.is1_9() ? ConvertBytes.byteListToInum19(runtime, num, 10, true) : @@ -928,7 +934,7 @@ RubyInteger bytesToInum(Ruby runtime, ByteList num) { } -// line 932 "Parser.java" +// line 938 "Parser.java" private static byte[] init__JSON_float_actions_0() { return new byte [] { @@ -1030,7 +1036,7 @@ private static byte[] init__JSON_float_trans_actions_0() static final int JSON_float_en_main = 1; -// line 520 "Parser.rl" +// line 526 "Parser.rl" void parseFloat(ParserResult res, int p, int pe) { @@ -1039,7 +1045,9 @@ void parseFloat(ParserResult res, int p, int pe) { res.update(null, p); return; } - RubyFloat number = createFloat(p, new_p); + IRubyObject number = parser.decimalClass == null ? + createFloat(p, new_p) : createCustomDecimal(p, new_p); + res.update(number, new_p + 1); return; } @@ -1048,15 +1056,15 @@ int parseFloatInternal(int p, int pe) { int cs = EVIL; -// line 1052 "Parser.java" +// line 1060 "Parser.java" { cs = JSON_float_start; } -// line 537 "Parser.rl" +// line 545 "Parser.rl" int memo = p; -// line 1060 "Parser.java" +// line 1068 "Parser.java" { int _klen; int _trans = 0; @@ -1137,13 +1145,13 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) switch ( _JSON_float_actions[_acts++] ) { case 0: -// line 511 "Parser.rl" +// line 517 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1147 "Parser.java" +// line 1155 "Parser.java" } } } @@ -1163,23 +1171,30 @@ else if ( data[p] > _JSON_float_trans_keys[_mid+1] ) break; } } -// line 539 "Parser.rl" +// line 547 "Parser.rl" if (cs < JSON_float_first_final) { return -1; } - + return p; } - + RubyFloat createFloat(int p, int new_p) { Ruby runtime = getRuntime(); ByteList num = absSubSequence(p, new_p); return RubyFloat.newFloat(runtime, dc.parse(num, true, runtime.is1_9())); } + IRubyObject createCustomDecimal(int p, int new_p) { + Ruby runtime = getRuntime(); + ByteList num = absSubSequence(p, new_p); + IRubyObject numString = runtime.newString(num.toString()); + return parser.decimalClass.callMethod(context, "new", numString); + } + -// line 1183 "Parser.java" +// line 1198 "Parser.java" private static byte[] init__JSON_string_actions_0() { return new byte [] { @@ -1281,7 +1296,7 @@ private static byte[] init__JSON_string_trans_actions_0() static final int JSON_string_en_main = 1; -// line 584 "Parser.rl" +// line 599 "Parser.rl" void parseString(ParserResult res, int p, int pe) { @@ -1289,15 +1304,15 @@ void parseString(ParserResult res, int p, int pe) { IRubyObject result = null; -// line 1293 "Parser.java" +// line 1308 "Parser.java" { cs = JSON_string_start; } -// line 591 "Parser.rl" +// line 606 "Parser.rl" int memo = p; -// line 1301 "Parser.java" +// line 1316 "Parser.java" { int _klen; int _trans = 0; @@ -1378,7 +1393,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) switch ( _JSON_string_actions[_acts++] ) { case 0: -// line 559 "Parser.rl" +// line 574 "Parser.rl" { int offset = byteList.begin(); ByteList decoded = decoder.decode(byteList, memo + 1 - offset, @@ -1393,13 +1408,13 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) } break; case 1: -// line 572 "Parser.rl" +// line 587 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1403 "Parser.java" +// line 1418 "Parser.java" } } } @@ -1419,7 +1434,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) break; } } -// line 593 "Parser.rl" +// line 608 "Parser.rl" if (parser.createAdditions) { RubyHash matchString = parser.matchString; @@ -1446,7 +1461,7 @@ public void visit(IRubyObject pattern, IRubyObject klass) { } } - if (cs >= JSON_string_first_final && result != null) { + if (cs >= JSON_string_first_final && result != null) { if (result instanceof RubyString) { ((RubyString)result).force_encoding(context, info.utf8.get()); } @@ -1457,7 +1472,7 @@ public void visit(IRubyObject pattern, IRubyObject klass) { } -// line 1461 "Parser.java" +// line 1476 "Parser.java" private static byte[] init__JSON_array_actions_0() { return new byte [] { @@ -1570,7 +1585,7 @@ private static byte[] init__JSON_array_trans_actions_0() static final int JSON_array_en_main = 1; -// line 666 "Parser.rl" +// line 681 "Parser.rl" void parseArray(ParserResult res, int p, int pe) { @@ -1590,14 +1605,14 @@ void parseArray(ParserResult res, int p, int pe) { } -// line 1594 "Parser.java" +// line 1609 "Parser.java" { cs = JSON_array_start; } -// line 685 "Parser.rl" +// line 700 "Parser.rl" -// line 1601 "Parser.java" +// line 1616 "Parser.java" { int _klen; int _trans = 0; @@ -1678,7 +1693,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) switch ( _JSON_array_actions[_acts++] ) { case 0: -// line 635 "Parser.rl" +// line 650 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1695,13 +1710,13 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } break; case 1: -// line 650 "Parser.rl" +// line 665 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1705 "Parser.java" +// line 1720 "Parser.java" } } } @@ -1721,7 +1736,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) break; } } -// line 686 "Parser.rl" +// line 701 "Parser.rl" if (cs >= JSON_array_first_final) { res.update(result, p + 1); @@ -1731,7 +1746,7 @@ else if ( data[p] > _JSON_array_trans_keys[_mid+1] ) } -// line 1735 "Parser.java" +// line 1750 "Parser.java" private static byte[] init__JSON_object_actions_0() { return new byte [] { @@ -1854,7 +1869,7 @@ private static byte[] init__JSON_object_trans_actions_0() static final int JSON_object_en_main = 1; -// line 745 "Parser.rl" +// line 760 "Parser.rl" void parseObject(ParserResult res, int p, int pe) { @@ -1879,14 +1894,14 @@ void parseObject(ParserResult res, int p, int pe) { } -// line 1883 "Parser.java" +// line 1898 "Parser.java" { cs = JSON_object_start; } -// line 769 "Parser.rl" +// line 784 "Parser.rl" -// line 1890 "Parser.java" +// line 1905 "Parser.java" { int _klen; int _trans = 0; @@ -1967,7 +1982,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) switch ( _JSON_object_actions[_acts++] ) { case 0: -// line 700 "Parser.rl" +// line 715 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1984,7 +1999,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 1: -// line 715 "Parser.rl" +// line 730 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -2004,13 +2019,13 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } break; case 2: -// line 733 "Parser.rl" +// line 748 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 2014 "Parser.java" +// line 2029 "Parser.java" } } } @@ -2030,7 +2045,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) break; } } -// line 770 "Parser.rl" +// line 785 "Parser.rl" if (cs < JSON_object_first_final) { res.update(null, p + 1); @@ -2063,7 +2078,7 @@ else if ( data[p] > _JSON_object_trans_keys[_mid+1] ) } -// line 2067 "Parser.java" +// line 2082 "Parser.java" private static byte[] init__JSON_actions_0() { return new byte [] { @@ -2166,7 +2181,7 @@ private static byte[] init__JSON_trans_actions_0() static final int JSON_en_main = 1; -// line 821 "Parser.rl" +// line 836 "Parser.rl" public IRubyObject parseImplemetation() { @@ -2176,16 +2191,16 @@ public IRubyObject parseImplemetation() { ParserResult res = new ParserResult(); -// line 2180 "Parser.java" +// line 2195 "Parser.java" { cs = JSON_start; } -// line 830 "Parser.rl" +// line 845 "Parser.rl" p = byteList.begin(); pe = p + byteList.length(); -// line 2189 "Parser.java" +// line 2204 "Parser.java" { int _klen; int _trans = 0; @@ -2266,7 +2281,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) switch ( _JSON_actions[_acts++] ) { case 0: -// line 807 "Parser.rl" +// line 822 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2278,7 +2293,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) } } break; -// line 2282 "Parser.java" +// line 2297 "Parser.java" } } } @@ -2298,7 +2313,7 @@ else if ( data[p] > _JSON_trans_keys[_mid+1] ) break; } } -// line 833 "Parser.rl" +// line 848 "Parser.rl" if (cs >= JSON_first_final && p == pe) { return result; diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 1ad8f216a..4d170e1d8 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -52,7 +52,8 @@ public class Parser extends RubyObject { private boolean symbolizeNames; private RubyClass objectClass; private RubyClass arrayClass; - private RubyHash matchString; + private RubyClass decimalClass; + private RubyHash match_string; private static final int DEFAULT_MAX_NESTING = 100; @@ -131,6 +132,10 @@ public class Parser extends RubyObject { *
:array_class *
Defaults to Array. * + *
:decimal_class + *
Specifies which class to use instead of the default (Float) when + * parsing decimal numbers. This class must accept a single string argument + * in its constructor. * */ @JRubyMethod(name = "new", required = 1, optional = 1, meta = true) @@ -157,7 +162,8 @@ public class Parser extends RubyObject { this.createAdditions = opts.getBool("create_additions", false); this.objectClass = opts.getClass("object_class", runtime.getHash()); this.arrayClass = opts.getClass("array_class", runtime.getArray()); - this.matchString = opts.getHash("match_string"); + this.decimalClass = opts.getClass("decimal_class", null); + this.match_string = opts.getHash("match_string"); if(symbolizeNames && createAdditions) { throw runtime.newArgumentError( @@ -489,13 +495,13 @@ public class Parser extends RubyObject { return p; } - + RubyInteger createInteger(int p, int new_p) { Ruby runtime = getRuntime(); ByteList num = absSubSequence(p, new_p); return bytesToInum(runtime, num); } - + RubyInteger bytesToInum(Ruby runtime, ByteList num) { return runtime.is1_9() ? ConvertBytes.byteListToInum19(runtime, num, 10, true) : @@ -525,7 +531,9 @@ public class Parser extends RubyObject { res.update(null, p); return; } - RubyFloat number = createFloat(p, new_p); + IRubyObject number = parser.decimalClass == null ? + createFloat(p, new_p) : createCustomDecimal(p, new_p); + res.update(number, new_p + 1); return; } @@ -540,16 +548,23 @@ public class Parser extends RubyObject { if (cs < JSON_float_first_final) { return -1; } - + return p; } - + RubyFloat createFloat(int p, int new_p) { Ruby runtime = getRuntime(); ByteList num = absSubSequence(p, new_p); return RubyFloat.newFloat(runtime, dc.parse(num, true, runtime.is1_9())); } + IRubyObject createCustomDecimal(int p, int new_p) { + Ruby runtime = getRuntime(); + ByteList num = absSubSequence(p, new_p); + IRubyObject numString = runtime.newString(num.toString()); + return parser.decimalClass.callMethod(context, "new", numString); + } + %%{ machine JSON_string; include JSON_common; @@ -616,7 +631,7 @@ public class Parser extends RubyObject { } } - if (cs >= JSON_string_first_final && result != null) { + if (cs >= JSON_string_first_final && result != null) { if (result instanceof RubyString) { ((RubyString)result).force_encoding(context, info.utf8.get()); } @@ -734,7 +749,7 @@ public class Parser extends RubyObject { fhold; fbreak; } - + pair = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value; next_pair = ignore* value_separator pair; diff --git a/json.gemspec b/json.gemspec index 7c862b0b1a02ed3f662e07bec74de40af6d2c896..58a98b70f6b9c9f50d1039761edffd407c1ee8bc 100644 GIT binary patch delta 54 zcmaE;^-ybqCbOZQ!9<-6VCw!QCL`m`n;9Kgc(RJ~^YqeFbBha7lP9ldm)*qX%(OY4 HgNYXa4c8JG delta 52 zcmaE;^-ybqCbNN_(L|jMVCw!QCPSmmn;9KgCNE&)-7LfA%*3jjl~|TIIi5p&b36wV FF96el5F-Ep diff --git a/json_pure.gemspec b/json_pure.gemspec index a0fdfe94d..24134dddd 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -1,18 +1,18 @@ # -*- encoding: utf-8 -*- -# stub: json_pure 2.0.2 ruby lib +# stub: json_pure 2.1.0 ruby lib Gem::Specification.new do |s| s.name = "json_pure".freeze - s.version = "2.0.2" + s.version = "2.1.0" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2016-09-12" + s.date = "2016-09-23" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] - s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] + s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/json.gemspec".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] s.homepage = "http://flori.github.com/json".freeze s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index b907236bc..3a6343bc9 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -70,6 +70,9 @@ class Parser < StringScanner # option defaults to false. # * *object_class*: Defaults to Hash # * *array_class*: Defaults to Array + # * *decimal_class*: Specifies which class to use instead of the default + # (Float) when parsing decimal numbers. This class must accept a single + # string argument in its constructor. def initialize(source, opts = {}) opts ||= {} source = convert_encoding source @@ -94,6 +97,7 @@ def initialize(source, opts = {}) @create_id = @create_additions ? JSON.create_id : nil @object_class = opts[:object_class] || Hash @array_class = opts[:array_class] || Array + @decimal_class = opts[:decimal_class] @match_string = opts[:match_string] end @@ -193,7 +197,7 @@ def parse_string def parse_value case when scan(FLOAT) - Float(self[1]) + @decimal_class && @decimal_class.new(self[1]) || Float(self[1]) when scan(INTEGER) Integer(self[1]) when scan(TRUE) diff --git a/lib/json/version.rb b/lib/json/version.rb index 8997def28..b65ed87f9 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module JSON # JSON version - VERSION = '2.0.2' + VERSION = '2.1.0' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: diff --git a/tests/test_helper.rb b/tests/test_helper.rb index 9d3665d47..7e99c29d0 100644 --- a/tests/test_helper.rb +++ b/tests/test_helper.rb @@ -1,5 +1,3 @@ -gem 'json', File.read('VERSION').chomp - case ENV['JSON'] when 'pure' $:.unshift 'lib' From ba1834c34fd2a50827c929993ae3601ba9a8e64f Mon Sep 17 00:00:00 2001 From: Per Lundberg Date: Fri, 4 Nov 2016 18:55:39 +0200 Subject: [PATCH 184/312] Fixed typo --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 8e00ae429..d0c4ad5fc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ * Fix issue #295 failure when parsing frozen strings. ## 2016-07-01 (2.0.1) - * Fix problem when requiring json\_pure and Parser constant was defiend top + * Fix problem when requiring json\_pure and Parser constant was defined top level. * Add `RB_GC_GUARD` to avoid possible GC problem via Pete Johns. * Store `current_nesting` on stack by Aaron Patterson. From a67cc0f5bb09c1c67af365137e1b595d43b4cf8a Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 22 Nov 2016 17:18:15 +0100 Subject: [PATCH 185/312] Test newer rubies --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9fccd10a2..8b3307ac9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,12 @@ rvm: - 2.0.0 - 2.1 - 2.2 - - 2.3.1 - - 2.4.0-preview2 + - 2.3.3 + - 2.4.0-preview3 - ruby-head - jruby matrix: allow_failures: - - rvm: rbx-2 - rvm: ruby-head script: "bundle exec rake" sudo: false From 8a2661d2ffd050ce932b330c22b3379ec6c04398 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 22 Nov 2016 17:19:53 +0100 Subject: [PATCH 186/312] Use newest rubygems --- json.gemspec | Bin 5473 -> 5473 bytes json_pure.gemspec | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/json.gemspec b/json.gemspec index 58a98b70f6b9c9f50d1039761edffd407c1ee8bc..631d372942e58c500050265f6915b737144b58af 100644 GIT binary patch delta 27 jcmaE;^-ycWI!0DQLtP`I&6^pu1({9tj5a?MYG48Yhdc<; delta 27 jcmaE;^-ycWI!0ClOI;)5&6^pu1)0tC%r-w1YG48Yhv*32 diff --git a/json_pure.gemspec b/json_pure.gemspec index 24134dddd..a279a7b3b 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2016-09-23" + s.date = "2016-11-22" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] s.required_ruby_version = Gem::Requirement.new("~> 2.0".freeze) - s.rubygems_version = "2.6.6".freeze + s.rubygems_version = "2.5.2".freeze s.summary = "JSON Implementation for Ruby".freeze s.test_files = ["./tests/test_helper.rb".freeze] From 3015920d6eccc2885f5a9ac2d5531800c4bebc24 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 12 Jan 2017 12:56:49 +0100 Subject: [PATCH 187/312] Support some older internal Ruby API (<2.0) --- .travis.yml | 6 +- Rakefile | 4 +- ext/json/ext/parser/parser.c | 2440 ++++++++++++++++++--------------- ext/json/ext/parser/parser.rl | 2 +- json.gemspec | Bin 5473 -> 5473 bytes json_pure.gemspec | 6 +- 6 files changed, 1309 insertions(+), 1149 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8b3307ac9..9bbb218c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,13 +4,15 @@ language: ruby # Specify which ruby versions you wish to run your tests on, each version will be used rvm: + - 1.9.2 + - 1.9.3 - 2.0.0 - 2.1 - 2.2 - 2.3.3 - - 2.4.0-preview3 - - ruby-head + - 2.4.0 - jruby + - ruby-head matrix: allow_failures: - rvm: ruby-head diff --git a/Rakefile b/Rakefile index 3e8d065fa..017d14a3d 100644 --- a/Rakefile +++ b/Rakefile @@ -95,7 +95,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.email = "flori@ping.de" s.homepage = "http://flori.github.com/#{PKG_NAME}" s.license = 'Ruby' - s.required_ruby_version = '~> 2.0' + s.required_ruby_version = '>= 1.9' end desc 'Creates a json_pure.gemspec file' @@ -133,7 +133,7 @@ if defined?(Gem) and defined?(Gem::PackageTask) s.email = "flori@ping.de" s.homepage = "http://flori.github.com/#{PKG_NAME}" s.license = 'Ruby' - s.required_ruby_version = '~> 2.0' + s.required_ruby_version = '>= 1.9' end desc 'Creates a json.gemspec file' diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index cb7c68cfb..5a4da4054 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1,5 +1,5 @@ -#line 1 "ext/json/ext/parser/parser.rl" +#line 1 "parser.rl" #include "../fbuffer/fbuffer.h" #include "parser.h" @@ -99,93 +99,19 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_leftshift, i_new; -#line 125 "ext/json/ext/parser/parser.rl" +#line 125 "parser.rl" -#line 107 "ext/json/ext/parser/parser.c" -static const char _JSON_object_actions[] = { - 0, 1, 0, 1, 1, 1, 2 -}; - -static const char _JSON_object_key_offsets[] = { - 0, 0, 1, 8, 14, 16, 17, 19, - 20, 36, 43, 49, 51, 52, 54, 55, - 57, 58, 60, 61, 63, 64, 66, 67, - 69, 70, 72, 73 -}; - -static const char _JSON_object_trans_keys[] = { - 123, 13, 32, 34, 47, 125, 9, 10, - 13, 32, 47, 58, 9, 10, 42, 47, - 42, 42, 47, 10, 13, 32, 34, 45, - 47, 73, 78, 91, 102, 110, 116, 123, - 9, 10, 48, 57, 13, 32, 44, 47, - 125, 9, 10, 13, 32, 34, 47, 9, - 10, 42, 47, 42, 42, 47, 10, 42, - 47, 42, 42, 47, 10, 42, 47, 42, - 42, 47, 10, 42, 47, 42, 42, 47, - 10, 0 -}; - -static const char _JSON_object_single_lengths[] = { - 0, 1, 5, 4, 2, 1, 2, 1, - 12, 5, 4, 2, 1, 2, 1, 2, - 1, 2, 1, 2, 1, 2, 1, 2, - 1, 2, 1, 0 -}; - -static const char _JSON_object_range_lengths[] = { - 0, 0, 1, 1, 0, 0, 0, 0, - 2, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 -}; - -static const char _JSON_object_index_offsets[] = { - 0, 0, 2, 9, 15, 18, 20, 23, - 25, 40, 47, 53, 56, 58, 61, 63, - 66, 68, 71, 73, 76, 78, 81, 83, - 86, 88, 91, 93 -}; - -static const char _JSON_object_indicies[] = { - 0, 1, 0, 0, 2, 3, 4, 0, - 1, 5, 5, 6, 7, 5, 1, 8, - 9, 1, 10, 8, 10, 5, 8, 5, - 9, 7, 7, 11, 11, 12, 11, 11, - 11, 11, 11, 11, 11, 7, 11, 1, - 13, 13, 14, 15, 4, 13, 1, 14, - 14, 2, 16, 14, 1, 17, 18, 1, - 19, 17, 19, 14, 17, 14, 18, 20, - 21, 1, 22, 20, 22, 13, 20, 13, - 21, 23, 24, 1, 25, 23, 25, 7, - 23, 7, 24, 26, 27, 1, 28, 26, - 28, 0, 26, 0, 27, 1, 0 -}; - -static const char _JSON_object_trans_targs[] = { - 2, 0, 3, 23, 27, 3, 4, 8, - 5, 7, 6, 9, 19, 9, 10, 15, - 11, 12, 14, 13, 16, 18, 17, 20, - 22, 21, 24, 26, 25 -}; - -static const char _JSON_object_trans_actions[] = { - 0, 0, 3, 0, 5, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 -}; +#line 107 "parser.c" +enum {JSON_object_start = 1}; +enum {JSON_object_first_final = 27}; +enum {JSON_object_error = 0}; -static const int JSON_object_start = 1; -static const int JSON_object_first_final = 27; -static const int JSON_object_error = 0; +enum {JSON_object_en_main = 1}; -static const int JSON_object_en_main = 1; - -#line 166 "ext/json/ext/parser/parser.rl" +#line 166 "parser.rl" static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -200,95 +126,128 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class); - -#line 205 "ext/json/ext/parser/parser.c" + +#line 131 "parser.c" { cs = JSON_object_start; } -#line 181 "ext/json/ext/parser/parser.rl" - -#line 212 "ext/json/ext/parser/parser.c" - { - int _klen; - unsigned int _trans; - const char *_acts; - unsigned int _nacts; - const char *_keys; +#line 181 "parser.rl" +#line 138 "parser.c" + { if ( p == pe ) goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _JSON_object_trans_keys + _JSON_object_key_offsets[cs]; - _trans = _JSON_object_index_offsets[cs]; - - _klen = _JSON_object_single_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + _klen - 1; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + ((_upper-_lower) >> 1); - if ( (*p) < *_mid ) - _upper = _mid - 1; - else if ( (*p) > *_mid ) - _lower = _mid + 1; - else { - _trans += (unsigned int)(_mid - _keys); - goto _match; - } - } - _keys += _klen; - _trans += _klen; - } - - _klen = _JSON_object_range_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + (_klen<<1) - 2; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + (((_upper-_lower) >> 1) & ~1); - if ( (*p) < _mid[0] ) - _upper = _mid - 2; - else if ( (*p) > _mid[1] ) - _lower = _mid + 2; - else { - _trans += (unsigned int)((_mid - _keys)>>1); - goto _match; - } - } - _trans += _klen; - } - -_match: - _trans = _JSON_object_indicies[_trans]; - cs = _JSON_object_trans_targs[_trans]; - - if ( _JSON_object_trans_actions[_trans] == 0 ) - goto _again; - - _acts = _JSON_object_actions + _JSON_object_trans_actions[_trans]; - _nacts = (unsigned int) *_acts++; - while ( _nacts-- > 0 ) + switch ( cs ) { - switch ( *_acts++ ) - { - case 0: -#line 133 "ext/json/ext/parser/parser.rl" +case 1: + if ( (*p) == 123 ) + goto st2; + goto st0; +st0: +cs = 0; + goto _out; +st2: + if ( ++p == pe ) + goto _test_eof2; +case 2: + switch( (*p) ) { + case 13: goto st2; + case 32: goto st2; + case 34: goto tr2; + case 47: goto st23; + case 125: goto tr4; + } + if ( 9 <= (*p) && (*p) <= 10 ) + goto st2; + goto st0; +tr2: +#line 148 "parser.rl" + { + char *np; + json->parsing_name = 1; + np = JSON_parse_string(json, p, pe, &last_name); + json->parsing_name = 0; + if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;} + } + goto st3; +st3: + if ( ++p == pe ) + goto _test_eof3; +case 3: +#line 179 "parser.c" + switch( (*p) ) { + case 13: goto st3; + case 32: goto st3; + case 47: goto st4; + case 58: goto st8; + } + if ( 9 <= (*p) && (*p) <= 10 ) + goto st3; + goto st0; +st4: + if ( ++p == pe ) + goto _test_eof4; +case 4: + switch( (*p) ) { + case 42: goto st5; + case 47: goto st7; + } + goto st0; +st5: + if ( ++p == pe ) + goto _test_eof5; +case 5: + if ( (*p) == 42 ) + goto st6; + goto st5; +st6: + if ( ++p == pe ) + goto _test_eof6; +case 6: + switch( (*p) ) { + case 42: goto st6; + case 47: goto st3; + } + goto st5; +st7: + if ( ++p == pe ) + goto _test_eof7; +case 7: + if ( (*p) == 10 ) + goto st3; + goto st7; +st8: + if ( ++p == pe ) + goto _test_eof8; +case 8: + switch( (*p) ) { + case 13: goto st8; + case 32: goto st8; + case 34: goto tr11; + case 45: goto tr11; + case 47: goto st19; + case 73: goto tr11; + case 78: goto tr11; + case 91: goto tr11; + case 102: goto tr11; + case 110: goto tr11; + case 116: goto tr11; + case 123: goto tr11; + } + if ( (*p) > 10 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr11; + } else if ( (*p) >= 9 ) + goto st8; + goto st0; +tr11: +#line 133 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); if (np == NULL) { - p--; {p++; goto _out; } + p--; {p++; cs = 9; goto _out;} } else { if (NIL_P(json->object_class)) { rb_hash_aset(*result, last_name, v); @@ -298,35 +257,206 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu {p = (( np))-1;} } } - break; - case 1: -#line 148 "ext/json/ext/parser/parser.rl" - { - char *np; - json->parsing_name = 1; - np = JSON_parse_string(json, p, pe, &last_name); - json->parsing_name = 0; - if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} - } - break; - case 2: -#line 156 "ext/json/ext/parser/parser.rl" - { p--; {p++; goto _out; } } - break; -#line 317 "ext/json/ext/parser/parser.c" - } - } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; + goto st9; +st9: + if ( ++p == pe ) + goto _test_eof9; +case 9: +#line 266 "parser.c" + switch( (*p) ) { + case 13: goto st9; + case 32: goto st9; + case 44: goto st10; + case 47: goto st15; + case 125: goto tr4; + } + if ( 9 <= (*p) && (*p) <= 10 ) + goto st9; + goto st0; +st10: + if ( ++p == pe ) + goto _test_eof10; +case 10: + switch( (*p) ) { + case 13: goto st10; + case 32: goto st10; + case 34: goto tr2; + case 47: goto st11; + } + if ( 9 <= (*p) && (*p) <= 10 ) + goto st10; + goto st0; +st11: + if ( ++p == pe ) + goto _test_eof11; +case 11: + switch( (*p) ) { + case 42: goto st12; + case 47: goto st14; + } + goto st0; +st12: + if ( ++p == pe ) + goto _test_eof12; +case 12: + if ( (*p) == 42 ) + goto st13; + goto st12; +st13: + if ( ++p == pe ) + goto _test_eof13; +case 13: + switch( (*p) ) { + case 42: goto st13; + case 47: goto st10; + } + goto st12; +st14: + if ( ++p == pe ) + goto _test_eof14; +case 14: + if ( (*p) == 10 ) + goto st10; + goto st14; +st15: + if ( ++p == pe ) + goto _test_eof15; +case 15: + switch( (*p) ) { + case 42: goto st16; + case 47: goto st18; + } + goto st0; +st16: + if ( ++p == pe ) + goto _test_eof16; +case 16: + if ( (*p) == 42 ) + goto st17; + goto st16; +st17: + if ( ++p == pe ) + goto _test_eof17; +case 17: + switch( (*p) ) { + case 42: goto st17; + case 47: goto st9; + } + goto st16; +st18: + if ( ++p == pe ) + goto _test_eof18; +case 18: + if ( (*p) == 10 ) + goto st9; + goto st18; +tr4: +#line 156 "parser.rl" + { p--; {p++; cs = 27; goto _out;} } + goto st27; +st27: + if ( ++p == pe ) + goto _test_eof27; +case 27: +#line 362 "parser.c" + goto st0; +st19: + if ( ++p == pe ) + goto _test_eof19; +case 19: + switch( (*p) ) { + case 42: goto st20; + case 47: goto st22; + } + goto st0; +st20: + if ( ++p == pe ) + goto _test_eof20; +case 20: + if ( (*p) == 42 ) + goto st21; + goto st20; +st21: + if ( ++p == pe ) + goto _test_eof21; +case 21: + switch( (*p) ) { + case 42: goto st21; + case 47: goto st8; + } + goto st20; +st22: + if ( ++p == pe ) + goto _test_eof22; +case 22: + if ( (*p) == 10 ) + goto st8; + goto st22; +st23: + if ( ++p == pe ) + goto _test_eof23; +case 23: + switch( (*p) ) { + case 42: goto st24; + case 47: goto st26; + } + goto st0; +st24: + if ( ++p == pe ) + goto _test_eof24; +case 24: + if ( (*p) == 42 ) + goto st25; + goto st24; +st25: + if ( ++p == pe ) + goto _test_eof25; +case 25: + switch( (*p) ) { + case 42: goto st25; + case 47: goto st2; + } + goto st24; +st26: + if ( ++p == pe ) + goto _test_eof26; +case 26: + if ( (*p) == 10 ) + goto st2; + goto st26; + } + _test_eof2: cs = 2; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof6: cs = 6; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof9: cs = 9; goto _test_eof; + _test_eof10: cs = 10; goto _test_eof; + _test_eof11: cs = 11; goto _test_eof; + _test_eof12: cs = 12; goto _test_eof; + _test_eof13: cs = 13; goto _test_eof; + _test_eof14: cs = 14; goto _test_eof; + _test_eof15: cs = 15; goto _test_eof; + _test_eof16: cs = 16; goto _test_eof; + _test_eof17: cs = 17; goto _test_eof; + _test_eof18: cs = 18; goto _test_eof; + _test_eof27: cs = 27; goto _test_eof; + _test_eof19: cs = 19; goto _test_eof; + _test_eof20: cs = 20; goto _test_eof; + _test_eof21: cs = 21; goto _test_eof; + _test_eof22: cs = 22; goto _test_eof; + _test_eof23: cs = 23; goto _test_eof; + _test_eof24: cs = 24; goto _test_eof; + _test_eof25: cs = 25; goto _test_eof; + _test_eof26: cs = 26; goto _test_eof; + _test_eof: {} _out: {} } -#line 182 "ext/json/ext/parser/parser.rl" +#line 182 "parser.rl" if (cs >= JSON_object_first_final) { if (json->create_additions) { @@ -351,245 +481,78 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu -#line 355 "ext/json/ext/parser/parser.c" -static const char _JSON_value_actions[] = { - 0, 1, 0, 1, 1, 1, 2, 1, - 3, 1, 4, 1, 5, 1, 6, 1, - 7, 1, 8, 1, 9 -}; - -static const char _JSON_value_key_offsets[] = { - 0, 0, 16, 18, 19, 21, 22, 24, - 25, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47 -}; - -static const char _JSON_value_trans_keys[] = { - 13, 32, 34, 45, 47, 73, 78, 91, - 102, 110, 116, 123, 9, 10, 48, 57, - 42, 47, 42, 42, 47, 10, 42, 47, - 42, 42, 47, 10, 110, 102, 105, 110, - 105, 116, 121, 97, 78, 97, 108, 115, - 101, 117, 108, 108, 114, 117, 101, 13, - 32, 47, 9, 10, 0 -}; - -static const char _JSON_value_single_lengths[] = { - 0, 12, 2, 1, 2, 1, 2, 1, - 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3 -}; - -static const char _JSON_value_range_lengths[] = { - 0, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1 -}; - -static const char _JSON_value_index_offsets[] = { - 0, 0, 15, 18, 20, 23, 25, 28, - 30, 33, 35, 37, 39, 41, 43, 45, - 47, 49, 51, 53, 55, 57, 59, 61, - 63, 65, 67, 69, 71, 73 -}; - -static const char _JSON_value_trans_targs[] = { - 1, 1, 29, 29, 6, 10, 17, 29, - 19, 23, 26, 29, 1, 29, 0, 3, - 5, 0, 4, 3, 4, 29, 3, 29, - 5, 7, 9, 0, 8, 7, 8, 1, - 7, 1, 9, 11, 0, 12, 0, 13, - 0, 14, 0, 15, 0, 16, 0, 29, - 0, 18, 0, 29, 0, 20, 0, 21, - 0, 22, 0, 29, 0, 24, 0, 25, - 0, 29, 0, 27, 0, 28, 0, 29, - 0, 29, 29, 2, 29, 0, 0 -}; - -static const char _JSON_value_trans_actions[] = { - 0, 0, 11, 13, 0, 0, 0, 15, - 0, 0, 0, 17, 0, 13, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, - 0, 0, 0, 7, 0, 0, 0, 0, - 0, 0, 0, 3, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 5, - 0, 0, 0, 0, 0, 0, 0 -}; - -static const char _JSON_value_from_state_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19 -}; - -static const int JSON_value_start = 1; -static const int JSON_value_first_final = 29; -static const int JSON_value_error = 0; +#line 485 "parser.c" +enum {JSON_value_start = 1}; +enum {JSON_value_first_final = 29}; +enum {JSON_value_error = 0}; -static const int JSON_value_en_main = 1; +enum {JSON_value_en_main = 1}; -#line 282 "ext/json/ext/parser/parser.rl" +#line 282 "parser.rl" static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) { int cs = EVIL; - -#line 448 "ext/json/ext/parser/parser.c" + +#line 501 "parser.c" { cs = JSON_value_start; } -#line 289 "ext/json/ext/parser/parser.rl" - -#line 455 "ext/json/ext/parser/parser.c" - { - int _klen; - unsigned int _trans; - const char *_acts; - unsigned int _nacts; - const char *_keys; +#line 289 "parser.rl" +#line 508 "parser.c" + { if ( p == pe ) goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _acts = _JSON_value_actions + _JSON_value_from_state_actions[cs]; - _nacts = (unsigned int) *_acts++; - while ( _nacts-- > 0 ) { - switch ( *_acts++ ) { - case 9: -#line 269 "ext/json/ext/parser/parser.rl" - { p--; {p++; goto _out; } } - break; -#line 476 "ext/json/ext/parser/parser.c" - } - } - - _keys = _JSON_value_trans_keys + _JSON_value_key_offsets[cs]; - _trans = _JSON_value_index_offsets[cs]; - - _klen = _JSON_value_single_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + _klen - 1; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + ((_upper-_lower) >> 1); - if ( (*p) < *_mid ) - _upper = _mid - 1; - else if ( (*p) > *_mid ) - _lower = _mid + 1; - else { - _trans += (unsigned int)(_mid - _keys); - goto _match; - } - } - _keys += _klen; - _trans += _klen; - } - - _klen = _JSON_value_range_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + (_klen<<1) - 2; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + (((_upper-_lower) >> 1) & ~1); - if ( (*p) < _mid[0] ) - _upper = _mid - 2; - else if ( (*p) > _mid[1] ) - _lower = _mid + 2; - else { - _trans += (unsigned int)((_mid - _keys)>>1); - goto _match; - } - } - _trans += _klen; - } - -_match: - cs = _JSON_value_trans_targs[_trans]; - - if ( _JSON_value_trans_actions[_trans] == 0 ) - goto _again; - - _acts = _JSON_value_actions + _JSON_value_trans_actions[_trans]; - _nacts = (unsigned int) *_acts++; - while ( _nacts-- > 0 ) - { - switch ( *_acts++ ) - { - case 0: -#line 211 "ext/json/ext/parser/parser.rl" + switch ( cs ) { - *result = Qnil; - } - break; - case 1: -#line 214 "ext/json/ext/parser/parser.rl" - { - *result = Qfalse; - } - break; - case 2: -#line 217 "ext/json/ext/parser/parser.rl" - { - *result = Qtrue; - } - break; - case 3: -#line 220 "ext/json/ext/parser/parser.rl" - { - if (json->allow_nan) { - *result = CNaN; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); - } - } - break; - case 4: -#line 227 "ext/json/ext/parser/parser.rl" - { - if (json->allow_nan) { - *result = CInfinity; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); - } - } - break; - case 5: -#line 234 "ext/json/ext/parser/parser.rl" +st1: + if ( ++p == pe ) + goto _test_eof1; +case 1: + switch( (*p) ) { + case 13: goto st1; + case 32: goto st1; + case 34: goto tr2; + case 45: goto tr3; + case 47: goto st6; + case 73: goto st10; + case 78: goto st17; + case 91: goto tr7; + case 102: goto st19; + case 110: goto st23; + case 116: goto st26; + case 123: goto tr11; + } + if ( (*p) > 10 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr3; + } else if ( (*p) >= 9 ) + goto st1; + goto st0; +st0: +cs = 0; + goto _out; +tr2: +#line 234 "parser.rl" { char *np = JSON_parse_string(json, p, pe, result); - if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } - break; - case 6: -#line 239 "ext/json/ext/parser/parser.rl" + goto st29; +tr3: +#line 239 "parser.rl" { char *np; if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) { if (json->allow_nan) { *result = CMinusInfinity; {p = (( p + 10))-1;} - p--; {p++; goto _out; } + p--; {p++; cs = 29; goto _out;} } else { rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); } @@ -598,39 +561,311 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul if (np != NULL) {p = (( np))-1;} np = JSON_parse_integer(json, p, pe, result); if (np != NULL) {p = (( np))-1;} - p--; {p++; goto _out; } + p--; {p++; cs = 29; goto _out;} } - break; - case 7: -#line 257 "ext/json/ext/parser/parser.rl" + goto st29; +tr7: +#line 257 "parser.rl" { char *np; np = JSON_parse_array(json, p, pe, result, current_nesting + 1); - if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } - break; - case 8: -#line 263 "ext/json/ext/parser/parser.rl" + goto st29; +tr11: +#line 263 "parser.rl" { char *np; np = JSON_parse_object(json, p, pe, result, current_nesting + 1); - if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } - break; -#line 621 "ext/json/ext/parser/parser.c" - } + goto st29; +tr25: +#line 227 "parser.rl" + { + if (json->allow_nan) { + *result = CInfinity; + } else { + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); + } + } + goto st29; +tr27: +#line 220 "parser.rl" + { + if (json->allow_nan) { + *result = CNaN; + } else { + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); + } + } + goto st29; +tr31: +#line 214 "parser.rl" + { + *result = Qfalse; + } + goto st29; +tr34: +#line 211 "parser.rl" + { + *result = Qnil; + } + goto st29; +tr37: +#line 217 "parser.rl" + { + *result = Qtrue; + } + goto st29; +st29: + if ( ++p == pe ) + goto _test_eof29; +case 29: +#line 269 "parser.rl" + { p--; {p++; cs = 29; goto _out;} } +#line 628 "parser.c" + switch( (*p) ) { + case 13: goto st29; + case 32: goto st29; + case 47: goto st2; + } + if ( 9 <= (*p) && (*p) <= 10 ) + goto st29; + goto st0; +st2: + if ( ++p == pe ) + goto _test_eof2; +case 2: + switch( (*p) ) { + case 42: goto st3; + case 47: goto st5; + } + goto st0; +st3: + if ( ++p == pe ) + goto _test_eof3; +case 3: + if ( (*p) == 42 ) + goto st4; + goto st3; +st4: + if ( ++p == pe ) + goto _test_eof4; +case 4: + switch( (*p) ) { + case 42: goto st4; + case 47: goto st29; + } + goto st3; +st5: + if ( ++p == pe ) + goto _test_eof5; +case 5: + if ( (*p) == 10 ) + goto st29; + goto st5; +st6: + if ( ++p == pe ) + goto _test_eof6; +case 6: + switch( (*p) ) { + case 42: goto st7; + case 47: goto st9; + } + goto st0; +st7: + if ( ++p == pe ) + goto _test_eof7; +case 7: + if ( (*p) == 42 ) + goto st8; + goto st7; +st8: + if ( ++p == pe ) + goto _test_eof8; +case 8: + switch( (*p) ) { + case 42: goto st8; + case 47: goto st1; } + goto st7; +st9: + if ( ++p == pe ) + goto _test_eof9; +case 9: + if ( (*p) == 10 ) + goto st1; + goto st9; +st10: + if ( ++p == pe ) + goto _test_eof10; +case 10: + if ( (*p) == 110 ) + goto st11; + goto st0; +st11: + if ( ++p == pe ) + goto _test_eof11; +case 11: + if ( (*p) == 102 ) + goto st12; + goto st0; +st12: + if ( ++p == pe ) + goto _test_eof12; +case 12: + if ( (*p) == 105 ) + goto st13; + goto st0; +st13: + if ( ++p == pe ) + goto _test_eof13; +case 13: + if ( (*p) == 110 ) + goto st14; + goto st0; +st14: + if ( ++p == pe ) + goto _test_eof14; +case 14: + if ( (*p) == 105 ) + goto st15; + goto st0; +st15: + if ( ++p == pe ) + goto _test_eof15; +case 15: + if ( (*p) == 116 ) + goto st16; + goto st0; +st16: + if ( ++p == pe ) + goto _test_eof16; +case 16: + if ( (*p) == 121 ) + goto tr25; + goto st0; +st17: + if ( ++p == pe ) + goto _test_eof17; +case 17: + if ( (*p) == 97 ) + goto st18; + goto st0; +st18: + if ( ++p == pe ) + goto _test_eof18; +case 18: + if ( (*p) == 78 ) + goto tr27; + goto st0; +st19: + if ( ++p == pe ) + goto _test_eof19; +case 19: + if ( (*p) == 97 ) + goto st20; + goto st0; +st20: + if ( ++p == pe ) + goto _test_eof20; +case 20: + if ( (*p) == 108 ) + goto st21; + goto st0; +st21: + if ( ++p == pe ) + goto _test_eof21; +case 21: + if ( (*p) == 115 ) + goto st22; + goto st0; +st22: + if ( ++p == pe ) + goto _test_eof22; +case 22: + if ( (*p) == 101 ) + goto tr31; + goto st0; +st23: + if ( ++p == pe ) + goto _test_eof23; +case 23: + if ( (*p) == 117 ) + goto st24; + goto st0; +st24: + if ( ++p == pe ) + goto _test_eof24; +case 24: + if ( (*p) == 108 ) + goto st25; + goto st0; +st25: + if ( ++p == pe ) + goto _test_eof25; +case 25: + if ( (*p) == 108 ) + goto tr34; + goto st0; +st26: + if ( ++p == pe ) + goto _test_eof26; +case 26: + if ( (*p) == 114 ) + goto st27; + goto st0; +st27: + if ( ++p == pe ) + goto _test_eof27; +case 27: + if ( (*p) == 117 ) + goto st28; + goto st0; +st28: + if ( ++p == pe ) + goto _test_eof28; +case 28: + if ( (*p) == 101 ) + goto tr37; + goto st0; + } + _test_eof1: cs = 1; goto _test_eof; + _test_eof29: cs = 29; goto _test_eof; + _test_eof2: cs = 2; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof6: cs = 6; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof9: cs = 9; goto _test_eof; + _test_eof10: cs = 10; goto _test_eof; + _test_eof11: cs = 11; goto _test_eof; + _test_eof12: cs = 12; goto _test_eof; + _test_eof13: cs = 13; goto _test_eof; + _test_eof14: cs = 14; goto _test_eof; + _test_eof15: cs = 15; goto _test_eof; + _test_eof16: cs = 16; goto _test_eof; + _test_eof17: cs = 17; goto _test_eof; + _test_eof18: cs = 18; goto _test_eof; + _test_eof19: cs = 19; goto _test_eof; + _test_eof20: cs = 20; goto _test_eof; + _test_eof21: cs = 21; goto _test_eof; + _test_eof22: cs = 22; goto _test_eof; + _test_eof23: cs = 23; goto _test_eof; + _test_eof24: cs = 24; goto _test_eof; + _test_eof25: cs = 25; goto _test_eof; + _test_eof26: cs = 26; goto _test_eof; + _test_eof27: cs = 27; goto _test_eof; + _test_eof28: cs = 28; goto _test_eof; -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; _test_eof: {} _out: {} } -#line 290 "ext/json/ext/parser/parser.rl" +#line 290 "parser.rl" if (cs >= JSON_value_first_final) { return p; @@ -640,160 +875,91 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul } -#line 644 "ext/json/ext/parser/parser.c" -static const char _JSON_integer_actions[] = { - 0, 1, 0 -}; - -static const char _JSON_integer_key_offsets[] = { - 0, 0, 4, 7, 9, 9 -}; +#line 879 "parser.c" +enum {JSON_integer_start = 1}; +enum {JSON_integer_first_final = 3}; +enum {JSON_integer_error = 0}; -static const char _JSON_integer_trans_keys[] = { - 45, 48, 49, 57, 48, 49, 57, 48, - 57, 48, 57, 0 -}; +enum {JSON_integer_en_main = 1}; -static const char _JSON_integer_single_lengths[] = { - 0, 2, 1, 0, 0, 0 -}; -static const char _JSON_integer_range_lengths[] = { - 0, 1, 1, 1, 0, 1 -}; - -static const char _JSON_integer_index_offsets[] = { - 0, 0, 4, 7, 9, 10 -}; - -static const char _JSON_integer_indicies[] = { - 0, 2, 3, 1, 2, 3, 1, 1, - 4, 1, 3, 4, 0 -}; - -static const char _JSON_integer_trans_targs[] = { - 2, 0, 3, 5, 4 -}; - -static const char _JSON_integer_trans_actions[] = { - 0, 0, 0, 0, 1 -}; - -static const int JSON_integer_start = 1; -static const int JSON_integer_first_final = 3; -static const int JSON_integer_error = 0; - -static const int JSON_integer_en_main = 1; - - -#line 306 "ext/json/ext/parser/parser.rl" +#line 306 "parser.rl" static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; - -#line 698 "ext/json/ext/parser/parser.c" + +#line 895 "parser.c" { cs = JSON_integer_start; } -#line 313 "ext/json/ext/parser/parser.rl" +#line 313 "parser.rl" json->memo = p; - -#line 706 "ext/json/ext/parser/parser.c" - { - int _klen; - unsigned int _trans; - const char *_acts; - unsigned int _nacts; - const char *_keys; +#line 903 "parser.c" + { if ( p == pe ) goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _JSON_integer_trans_keys + _JSON_integer_key_offsets[cs]; - _trans = _JSON_integer_index_offsets[cs]; - - _klen = _JSON_integer_single_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + _klen - 1; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + ((_upper-_lower) >> 1); - if ( (*p) < *_mid ) - _upper = _mid - 1; - else if ( (*p) > *_mid ) - _lower = _mid + 1; - else { - _trans += (unsigned int)(_mid - _keys); - goto _match; - } - } - _keys += _klen; - _trans += _klen; - } - - _klen = _JSON_integer_range_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + (_klen<<1) - 2; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + (((_upper-_lower) >> 1) & ~1); - if ( (*p) < _mid[0] ) - _upper = _mid - 2; - else if ( (*p) > _mid[1] ) - _lower = _mid + 2; - else { - _trans += (unsigned int)((_mid - _keys)>>1); - goto _match; - } - } - _trans += _klen; - } - -_match: - _trans = _JSON_integer_indicies[_trans]; - cs = _JSON_integer_trans_targs[_trans]; - - if ( _JSON_integer_trans_actions[_trans] == 0 ) - goto _again; - - _acts = _JSON_integer_actions + _JSON_integer_trans_actions[_trans]; - _nacts = (unsigned int) *_acts++; - while ( _nacts-- > 0 ) + switch ( cs ) { - switch ( *_acts++ ) - { - case 0: -#line 303 "ext/json/ext/parser/parser.rl" - { p--; {p++; goto _out; } } - break; -#line 784 "ext/json/ext/parser/parser.c" - } - } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; +case 1: + switch( (*p) ) { + case 45: goto st2; + case 48: goto st3; + } + if ( 49 <= (*p) && (*p) <= 57 ) + goto st5; + goto st0; +st0: +cs = 0; + goto _out; +st2: + if ( ++p == pe ) + goto _test_eof2; +case 2: + if ( (*p) == 48 ) + goto st3; + if ( 49 <= (*p) && (*p) <= 57 ) + goto st5; + goto st0; +st3: + if ( ++p == pe ) + goto _test_eof3; +case 3: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st0; + goto tr4; +tr4: +#line 303 "parser.rl" + { p--; {p++; cs = 4; goto _out;} } + goto st4; +st4: + if ( ++p == pe ) + goto _test_eof4; +case 4: +#line 944 "parser.c" + goto st0; +st5: + if ( ++p == pe ) + goto _test_eof5; +case 5: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st5; + goto tr4; + } + _test_eof2: cs = 2; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof: {} _out: {} } -#line 315 "ext/json/ext/parser/parser.rl" +#line 315 "parser.rl" if (cs >= JSON_integer_first_final) { long len = p - json->memo; @@ -808,172 +974,157 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res } -#line 812 "ext/json/ext/parser/parser.c" -static const char _JSON_float_actions[] = { - 0, 1, 0 -}; - -static const char _JSON_float_key_offsets[] = { - 0, 0, 4, 7, 10, 12, 16, 18, - 23, 29, 29 -}; - -static const char _JSON_float_trans_keys[] = { - 45, 48, 49, 57, 48, 49, 57, 46, - 69, 101, 48, 57, 43, 45, 48, 57, - 48, 57, 46, 69, 101, 48, 57, 69, - 101, 45, 46, 48, 57, 69, 101, 45, - 46, 48, 57, 0 -}; - -static const char _JSON_float_single_lengths[] = { - 0, 2, 1, 3, 0, 2, 0, 3, - 2, 0, 2 -}; - -static const char _JSON_float_range_lengths[] = { - 0, 1, 1, 0, 1, 1, 1, 1, - 2, 0, 2 -}; - -static const char _JSON_float_index_offsets[] = { - 0, 0, 4, 7, 11, 13, 17, 19, - 24, 29, 30 -}; - -static const char _JSON_float_indicies[] = { - 0, 2, 3, 1, 2, 3, 1, 4, - 5, 5, 1, 6, 1, 7, 7, 8, - 1, 8, 1, 4, 5, 5, 3, 1, - 5, 5, 1, 6, 9, 1, 1, 1, - 1, 8, 9, 0 -}; - -static const char _JSON_float_trans_targs[] = { - 2, 0, 3, 7, 4, 5, 8, 6, - 10, 9 -}; +#line 978 "parser.c" +enum {JSON_float_start = 1}; +enum {JSON_float_first_final = 8}; +enum {JSON_float_error = 0}; -static const char _JSON_float_trans_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1 -}; +enum {JSON_float_en_main = 1}; -static const int JSON_float_start = 1; -static const int JSON_float_first_final = 8; -static const int JSON_float_error = 0; -static const int JSON_float_en_main = 1; - - -#line 340 "ext/json/ext/parser/parser.rl" +#line 340 "parser.rl" static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; - -#line 878 "ext/json/ext/parser/parser.c" + +#line 994 "parser.c" { cs = JSON_float_start; } -#line 347 "ext/json/ext/parser/parser.rl" +#line 347 "parser.rl" json->memo = p; - -#line 886 "ext/json/ext/parser/parser.c" - { - int _klen; - unsigned int _trans; - const char *_acts; - unsigned int _nacts; - const char *_keys; +#line 1002 "parser.c" + { if ( p == pe ) goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _JSON_float_trans_keys + _JSON_float_key_offsets[cs]; - _trans = _JSON_float_index_offsets[cs]; - - _klen = _JSON_float_single_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + _klen - 1; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + ((_upper-_lower) >> 1); - if ( (*p) < *_mid ) - _upper = _mid - 1; - else if ( (*p) > *_mid ) - _lower = _mid + 1; - else { - _trans += (unsigned int)(_mid - _keys); - goto _match; - } - } - _keys += _klen; - _trans += _klen; - } - - _klen = _JSON_float_range_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + (_klen<<1) - 2; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + (((_upper-_lower) >> 1) & ~1); - if ( (*p) < _mid[0] ) - _upper = _mid - 2; - else if ( (*p) > _mid[1] ) - _lower = _mid + 2; - else { - _trans += (unsigned int)((_mid - _keys)>>1); - goto _match; - } - } - _trans += _klen; - } - -_match: - _trans = _JSON_float_indicies[_trans]; - cs = _JSON_float_trans_targs[_trans]; - - if ( _JSON_float_trans_actions[_trans] == 0 ) - goto _again; - - _acts = _JSON_float_actions + _JSON_float_trans_actions[_trans]; - _nacts = (unsigned int) *_acts++; - while ( _nacts-- > 0 ) + switch ( cs ) { - switch ( *_acts++ ) - { - case 0: -#line 334 "ext/json/ext/parser/parser.rl" - { p--; {p++; goto _out; } } - break; -#line 964 "ext/json/ext/parser/parser.c" - } - } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; +case 1: + switch( (*p) ) { + case 45: goto st2; + case 48: goto st3; + } + if ( 49 <= (*p) && (*p) <= 57 ) + goto st7; + goto st0; +st0: +cs = 0; + goto _out; +st2: + if ( ++p == pe ) + goto _test_eof2; +case 2: + if ( (*p) == 48 ) + goto st3; + if ( 49 <= (*p) && (*p) <= 57 ) + goto st7; + goto st0; +st3: + if ( ++p == pe ) + goto _test_eof3; +case 3: + switch( (*p) ) { + case 46: goto st4; + case 69: goto st5; + case 101: goto st5; + } + goto st0; +st4: + if ( ++p == pe ) + goto _test_eof4; +case 4: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st8; + goto st0; +st8: + if ( ++p == pe ) + goto _test_eof8; +case 8: + switch( (*p) ) { + case 69: goto st5; + case 101: goto st5; + } + if ( (*p) > 46 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st8; + } else if ( (*p) >= 45 ) + goto st0; + goto tr9; +tr9: +#line 334 "parser.rl" + { p--; {p++; cs = 9; goto _out;} } + goto st9; +st9: + if ( ++p == pe ) + goto _test_eof9; +case 9: +#line 1067 "parser.c" + goto st0; +st5: + if ( ++p == pe ) + goto _test_eof5; +case 5: + switch( (*p) ) { + case 43: goto st6; + case 45: goto st6; + } + if ( 48 <= (*p) && (*p) <= 57 ) + goto st10; + goto st0; +st6: + if ( ++p == pe ) + goto _test_eof6; +case 6: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st10; + goto st0; +st10: + if ( ++p == pe ) + goto _test_eof10; +case 10: + switch( (*p) ) { + case 69: goto st0; + case 101: goto st0; + } + if ( (*p) > 46 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st10; + } else if ( (*p) >= 45 ) + goto st0; + goto tr9; +st7: + if ( ++p == pe ) + goto _test_eof7; +case 7: + switch( (*p) ) { + case 46: goto st4; + case 69: goto st5; + case 101: goto st5; + } + if ( 48 <= (*p) && (*p) <= 57 ) + goto st7; + goto st0; + } + _test_eof2: cs = 2; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof9: cs = 9; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof6: cs = 6; goto _test_eof; + _test_eof10: cs = 10; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof: {} _out: {} } -#line 349 "ext/json/ext/parser/parser.rl" +#line 349 "parser.rl" if (cs >= JSON_float_first_final) { long len = p - json->memo; @@ -996,78 +1147,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul -#line 1000 "ext/json/ext/parser/parser.c" -static const char _JSON_array_actions[] = { - 0, 1, 0, 1, 1 -}; - -static const char _JSON_array_key_offsets[] = { - 0, 0, 1, 18, 25, 41, 43, 44, - 46, 47, 49, 50, 52, 53, 55, 56, - 58, 59 -}; - -static const char _JSON_array_trans_keys[] = { - 91, 13, 32, 34, 45, 47, 73, 78, - 91, 93, 102, 110, 116, 123, 9, 10, - 48, 57, 13, 32, 44, 47, 93, 9, - 10, 13, 32, 34, 45, 47, 73, 78, - 91, 102, 110, 116, 123, 9, 10, 48, - 57, 42, 47, 42, 42, 47, 10, 42, - 47, 42, 42, 47, 10, 42, 47, 42, - 42, 47, 10, 0 -}; - -static const char _JSON_array_single_lengths[] = { - 0, 1, 13, 5, 12, 2, 1, 2, - 1, 2, 1, 2, 1, 2, 1, 2, - 1, 0 -}; - -static const char _JSON_array_range_lengths[] = { - 0, 0, 2, 1, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 -}; - -static const char _JSON_array_index_offsets[] = { - 0, 0, 2, 18, 25, 40, 43, 45, - 48, 50, 53, 55, 58, 60, 63, 65, - 68, 70 -}; - -static const char _JSON_array_indicies[] = { - 0, 1, 0, 0, 2, 2, 3, 2, - 2, 2, 4, 2, 2, 2, 2, 0, - 2, 1, 5, 5, 6, 7, 4, 5, - 1, 6, 6, 2, 2, 8, 2, 2, - 2, 2, 2, 2, 2, 6, 2, 1, - 9, 10, 1, 11, 9, 11, 6, 9, - 6, 10, 12, 13, 1, 14, 12, 14, - 5, 12, 5, 13, 15, 16, 1, 17, - 15, 17, 0, 15, 0, 16, 1, 0 -}; - -static const char _JSON_array_trans_targs[] = { - 2, 0, 3, 13, 17, 3, 4, 9, - 5, 6, 8, 7, 10, 12, 11, 14, - 16, 15 -}; - -static const char _JSON_array_trans_actions[] = { - 0, 0, 1, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 -}; - -static const int JSON_array_start = 1; -static const int JSON_array_first_final = 17; -static const int JSON_array_error = 0; +#line 1151 "parser.c" +enum {JSON_array_start = 1}; +enum {JSON_array_first_final = 17}; +enum {JSON_array_error = 0}; -static const int JSON_array_en_main = 1; +enum {JSON_array_en_main = 1}; -#line 399 "ext/json/ext/parser/parser.rl" +#line 399 "parser.rl" static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -1080,95 +1168,59 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul } *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); - -#line 1085 "ext/json/ext/parser/parser.c" + +#line 1173 "parser.c" { cs = JSON_array_start; } -#line 412 "ext/json/ext/parser/parser.rl" - -#line 1092 "ext/json/ext/parser/parser.c" - { - int _klen; - unsigned int _trans; - const char *_acts; - unsigned int _nacts; - const char *_keys; +#line 412 "parser.rl" +#line 1180 "parser.c" + { if ( p == pe ) goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _JSON_array_trans_keys + _JSON_array_key_offsets[cs]; - _trans = _JSON_array_index_offsets[cs]; - - _klen = _JSON_array_single_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + _klen - 1; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + ((_upper-_lower) >> 1); - if ( (*p) < *_mid ) - _upper = _mid - 1; - else if ( (*p) > *_mid ) - _lower = _mid + 1; - else { - _trans += (unsigned int)(_mid - _keys); - goto _match; - } - } - _keys += _klen; - _trans += _klen; - } - - _klen = _JSON_array_range_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + (_klen<<1) - 2; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + (((_upper-_lower) >> 1) & ~1); - if ( (*p) < _mid[0] ) - _upper = _mid - 2; - else if ( (*p) > _mid[1] ) - _lower = _mid + 2; - else { - _trans += (unsigned int)((_mid - _keys)>>1); - goto _match; - } - } - _trans += _klen; - } - -_match: - _trans = _JSON_array_indicies[_trans]; - cs = _JSON_array_trans_targs[_trans]; - - if ( _JSON_array_trans_actions[_trans] == 0 ) - goto _again; - - _acts = _JSON_array_actions + _JSON_array_trans_actions[_trans]; - _nacts = (unsigned int) *_acts++; - while ( _nacts-- > 0 ) + switch ( cs ) { - switch ( *_acts++ ) - { - case 0: -#line 376 "ext/json/ext/parser/parser.rl" +case 1: + if ( (*p) == 91 ) + goto st2; + goto st0; +st0: +cs = 0; + goto _out; +st2: + if ( ++p == pe ) + goto _test_eof2; +case 2: + switch( (*p) ) { + case 13: goto st2; + case 32: goto st2; + case 34: goto tr2; + case 45: goto tr2; + case 47: goto st13; + case 73: goto tr2; + case 78: goto tr2; + case 91: goto tr2; + case 93: goto tr4; + case 102: goto tr2; + case 110: goto tr2; + case 116: goto tr2; + case 123: goto tr2; + } + if ( (*p) > 10 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr2; + } else if ( (*p) >= 9 ) + goto st2; + goto st0; +tr2: +#line 376 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); if (np == NULL) { - p--; {p++; goto _out; } + p--; {p++; cs = 3; goto _out;} } else { if (NIL_P(json->array_class)) { rb_ary_push(*result, v); @@ -1178,25 +1230,175 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul {p = (( np))-1;} } } - break; - case 1: -#line 391 "ext/json/ext/parser/parser.rl" - { p--; {p++; goto _out; } } - break; -#line 1187 "ext/json/ext/parser/parser.c" - } - } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; + goto st3; +st3: + if ( ++p == pe ) + goto _test_eof3; +case 3: +#line 1239 "parser.c" + switch( (*p) ) { + case 13: goto st3; + case 32: goto st3; + case 44: goto st4; + case 47: goto st9; + case 93: goto tr4; + } + if ( 9 <= (*p) && (*p) <= 10 ) + goto st3; + goto st0; +st4: + if ( ++p == pe ) + goto _test_eof4; +case 4: + switch( (*p) ) { + case 13: goto st4; + case 32: goto st4; + case 34: goto tr2; + case 45: goto tr2; + case 47: goto st5; + case 73: goto tr2; + case 78: goto tr2; + case 91: goto tr2; + case 102: goto tr2; + case 110: goto tr2; + case 116: goto tr2; + case 123: goto tr2; + } + if ( (*p) > 10 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr2; + } else if ( (*p) >= 9 ) + goto st4; + goto st0; +st5: + if ( ++p == pe ) + goto _test_eof5; +case 5: + switch( (*p) ) { + case 42: goto st6; + case 47: goto st8; + } + goto st0; +st6: + if ( ++p == pe ) + goto _test_eof6; +case 6: + if ( (*p) == 42 ) + goto st7; + goto st6; +st7: + if ( ++p == pe ) + goto _test_eof7; +case 7: + switch( (*p) ) { + case 42: goto st7; + case 47: goto st4; + } + goto st6; +st8: + if ( ++p == pe ) + goto _test_eof8; +case 8: + if ( (*p) == 10 ) + goto st4; + goto st8; +st9: + if ( ++p == pe ) + goto _test_eof9; +case 9: + switch( (*p) ) { + case 42: goto st10; + case 47: goto st12; + } + goto st0; +st10: + if ( ++p == pe ) + goto _test_eof10; +case 10: + if ( (*p) == 42 ) + goto st11; + goto st10; +st11: + if ( ++p == pe ) + goto _test_eof11; +case 11: + switch( (*p) ) { + case 42: goto st11; + case 47: goto st3; + } + goto st10; +st12: + if ( ++p == pe ) + goto _test_eof12; +case 12: + if ( (*p) == 10 ) + goto st3; + goto st12; +tr4: +#line 391 "parser.rl" + { p--; {p++; cs = 17; goto _out;} } + goto st17; +st17: + if ( ++p == pe ) + goto _test_eof17; +case 17: +#line 1346 "parser.c" + goto st0; +st13: + if ( ++p == pe ) + goto _test_eof13; +case 13: + switch( (*p) ) { + case 42: goto st14; + case 47: goto st16; + } + goto st0; +st14: + if ( ++p == pe ) + goto _test_eof14; +case 14: + if ( (*p) == 42 ) + goto st15; + goto st14; +st15: + if ( ++p == pe ) + goto _test_eof15; +case 15: + switch( (*p) ) { + case 42: goto st15; + case 47: goto st2; + } + goto st14; +st16: + if ( ++p == pe ) + goto _test_eof16; +case 16: + if ( (*p) == 10 ) + goto st2; + goto st16; + } + _test_eof2: cs = 2; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof6: cs = 6; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof9: cs = 9; goto _test_eof; + _test_eof10: cs = 10; goto _test_eof; + _test_eof11: cs = 11; goto _test_eof; + _test_eof12: cs = 12; goto _test_eof; + _test_eof17: cs = 17; goto _test_eof; + _test_eof13: cs = 13; goto _test_eof; + _test_eof14: cs = 14; goto _test_eof; + _test_eof15: cs = 15; goto _test_eof; + _test_eof16: cs = 16; goto _test_eof; + _test_eof: {} _out: {} } -#line 413 "ext/json/ext/parser/parser.rl" +#line 413 "parser.rl" if(cs >= JSON_array_first_final) { return p + 1; @@ -1277,62 +1479,15 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1281 "ext/json/ext/parser/parser.c" -static const char _JSON_string_actions[] = { - 0, 2, 0, 1 -}; - -static const char _JSON_string_key_offsets[] = { - 0, 0, 1, 5, 8, 14, 20, 26, - 32 -}; - -static const char _JSON_string_trans_keys[] = { - 34, 34, 92, 0, 31, 117, 0, 31, - 48, 57, 65, 70, 97, 102, 48, 57, - 65, 70, 97, 102, 48, 57, 65, 70, - 97, 102, 48, 57, 65, 70, 97, 102, - 0 -}; - -static const char _JSON_string_single_lengths[] = { - 0, 1, 2, 1, 0, 0, 0, 0, - 0 -}; - -static const char _JSON_string_range_lengths[] = { - 0, 0, 1, 1, 3, 3, 3, 3, - 0 -}; - -static const char _JSON_string_index_offsets[] = { - 0, 0, 2, 6, 9, 13, 17, 21, - 25 -}; - -static const char _JSON_string_indicies[] = { - 0, 1, 2, 3, 1, 0, 4, 1, - 0, 5, 5, 5, 1, 6, 6, 6, - 1, 7, 7, 7, 1, 0, 0, 0, - 1, 1, 0 -}; - -static const char _JSON_string_trans_targs[] = { - 2, 0, 8, 3, 4, 5, 6, 7 -}; - -static const char _JSON_string_trans_actions[] = { - 0, 0, 1, 0, 0, 0, 0, 0 -}; - -static const int JSON_string_start = 1; -static const int JSON_string_first_final = 8; -static const int JSON_string_error = 0; +#line 1483 "parser.c" +enum {JSON_string_start = 1}; +enum {JSON_string_first_final = 8}; +enum {JSON_string_error = 0}; -static const int JSON_string_en_main = 1; +enum {JSON_string_en_main = 1}; -#line 512 "ext/json/ext/parser/parser.rl" +#line 512 "parser.rl" static int @@ -1353,120 +1508,135 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu VALUE match_string; *result = rb_str_buf_new(0); - -#line 1358 "ext/json/ext/parser/parser.c" + +#line 1513 "parser.c" { cs = JSON_string_start; } -#line 533 "ext/json/ext/parser/parser.rl" +#line 533 "parser.rl" json->memo = p; - -#line 1366 "ext/json/ext/parser/parser.c" - { - int _klen; - unsigned int _trans; - const char *_acts; - unsigned int _nacts; - const char *_keys; +#line 1521 "parser.c" + { if ( p == pe ) goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _JSON_string_trans_keys + _JSON_string_key_offsets[cs]; - _trans = _JSON_string_index_offsets[cs]; - - _klen = _JSON_string_single_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + _klen - 1; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + ((_upper-_lower) >> 1); - if ( (*p) < *_mid ) - _upper = _mid - 1; - else if ( (*p) > *_mid ) - _lower = _mid + 1; - else { - _trans += (unsigned int)(_mid - _keys); - goto _match; - } - } - _keys += _klen; - _trans += _klen; - } - - _klen = _JSON_string_range_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + (_klen<<1) - 2; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + (((_upper-_lower) >> 1) & ~1); - if ( (*p) < _mid[0] ) - _upper = _mid - 2; - else if ( (*p) > _mid[1] ) - _lower = _mid + 2; - else { - _trans += (unsigned int)((_mid - _keys)>>1); - goto _match; - } - } - _trans += _klen; - } - -_match: - _trans = _JSON_string_indicies[_trans]; - cs = _JSON_string_trans_targs[_trans]; - - if ( _JSON_string_trans_actions[_trans] == 0 ) - goto _again; - - _acts = _JSON_string_actions + _JSON_string_trans_actions[_trans]; - _nacts = (unsigned int) *_acts++; - while ( _nacts-- > 0 ) + switch ( cs ) { - switch ( *_acts++ ) - { - case 0: -#line 498 "ext/json/ext/parser/parser.rl" +case 1: + if ( (*p) == 34 ) + goto st2; + goto st0; +st0: +cs = 0; + goto _out; +st2: + if ( ++p == pe ) + goto _test_eof2; +case 2: + switch( (*p) ) { + case 34: goto tr2; + case 92: goto st3; + } + if ( 0 <= (*p) && (*p) <= 31 ) + goto st0; + goto st2; +tr2: +#line 498 "parser.rl" { *result = json_string_unescape(*result, json->memo + 1, p); if (NIL_P(*result)) { p--; - {p++; goto _out; } + {p++; cs = 8; goto _out;} } else { FORCE_UTF8(*result); {p = (( p + 1))-1;} } } - break; - case 1: -#line 509 "ext/json/ext/parser/parser.rl" - { p--; {p++; goto _out; } } - break; -#line 1457 "ext/json/ext/parser/parser.c" - } - } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; +#line 509 "parser.rl" + { p--; {p++; cs = 8; goto _out;} } + goto st8; +st8: + if ( ++p == pe ) + goto _test_eof8; +case 8: +#line 1564 "parser.c" + goto st0; +st3: + if ( ++p == pe ) + goto _test_eof3; +case 3: + if ( (*p) == 117 ) + goto st4; + if ( 0 <= (*p) && (*p) <= 31 ) + goto st0; + goto st2; +st4: + if ( ++p == pe ) + goto _test_eof4; +case 4: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st5; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st5; + } else + goto st5; + goto st0; +st5: + if ( ++p == pe ) + goto _test_eof5; +case 5: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st6; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st6; + } else + goto st6; + goto st0; +st6: + if ( ++p == pe ) + goto _test_eof6; +case 6: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st7; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st7; + } else + goto st7; + goto st0; +st7: + if ( ++p == pe ) + goto _test_eof7; +case 7: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st2; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st2; + } else + goto st2; + goto st0; + } + _test_eof2: cs = 2; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof6: cs = 6; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof: {} _out: {} } -#line 535 "ext/json/ext/parser/parser.rl" +#line 535 "parser.rl" if (json->create_additions && RTEST(match_string = json->match_string)) { VALUE klass; @@ -1513,7 +1683,7 @@ static VALUE convert_encoding(VALUE source) } FORCE_UTF8(source); } else { - source = rb_str_conv_enc(source, NULL, rb_utf8_encoding()); + source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding()); } #endif return source; @@ -1653,66 +1823,15 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1657 "ext/json/ext/parser/parser.c" -static const char _JSON_actions[] = { - 0, 1, 0 -}; - -static const char _JSON_key_offsets[] = { - 0, 0, 16, 18, 19, 21, 22, 24, - 25, 27, 28 -}; - -static const char _JSON_trans_keys[] = { - 13, 32, 34, 45, 47, 73, 78, 91, - 102, 110, 116, 123, 9, 10, 48, 57, - 42, 47, 42, 42, 47, 10, 42, 47, - 42, 42, 47, 10, 13, 32, 47, 9, - 10, 0 -}; - -static const char _JSON_single_lengths[] = { - 0, 12, 2, 1, 2, 1, 2, 1, - 2, 1, 3 -}; - -static const char _JSON_range_lengths[] = { - 0, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 1 -}; - -static const char _JSON_index_offsets[] = { - 0, 0, 15, 18, 20, 23, 25, 28, - 30, 33, 35 -}; - -static const char _JSON_indicies[] = { - 0, 0, 2, 2, 3, 2, 2, 2, - 2, 2, 2, 2, 0, 2, 1, 4, - 5, 1, 6, 4, 6, 7, 4, 7, - 5, 8, 9, 1, 10, 8, 10, 0, - 8, 0, 9, 7, 7, 11, 7, 1, - 0 -}; - -static const char _JSON_trans_targs[] = { - 1, 0, 10, 6, 3, 5, 4, 10, - 7, 9, 8, 2 -}; - -static const char _JSON_trans_actions[] = { - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0 -}; - -static const int JSON_start = 1; -static const int JSON_first_final = 10; -static const int JSON_error = 0; +#line 1827 "parser.c" +enum {JSON_start = 1}; +enum {JSON_first_final = 10}; +enum {JSON_error = 0}; -static const int JSON_en_main = 1; +enum {JSON_en_main = 1}; -#line 735 "ext/json/ext/parser/parser.rl" +#line 735 "parser.rl" /* @@ -1728,111 +1847,150 @@ static VALUE cParser_parse(VALUE self) VALUE result = Qnil; GET_PARSER; - -#line 1733 "ext/json/ext/parser/parser.c" + +#line 1852 "parser.c" { cs = JSON_start; } -#line 751 "ext/json/ext/parser/parser.rl" +#line 751 "parser.rl" p = json->source; pe = p + json->len; - -#line 1742 "ext/json/ext/parser/parser.c" - { - int _klen; - unsigned int _trans; - const char *_acts; - unsigned int _nacts; - const char *_keys; +#line 1861 "parser.c" + { if ( p == pe ) goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _JSON_trans_keys + _JSON_key_offsets[cs]; - _trans = _JSON_index_offsets[cs]; - - _klen = _JSON_single_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + _klen - 1; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + ((_upper-_lower) >> 1); - if ( (*p) < *_mid ) - _upper = _mid - 1; - else if ( (*p) > *_mid ) - _lower = _mid + 1; - else { - _trans += (unsigned int)(_mid - _keys); - goto _match; - } - } - _keys += _klen; - _trans += _klen; - } - - _klen = _JSON_range_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + (_klen<<1) - 2; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + (((_upper-_lower) >> 1) & ~1); - if ( (*p) < _mid[0] ) - _upper = _mid - 2; - else if ( (*p) > _mid[1] ) - _lower = _mid + 2; - else { - _trans += (unsigned int)((_mid - _keys)>>1); - goto _match; - } - } - _trans += _klen; - } - -_match: - _trans = _JSON_indicies[_trans]; - cs = _JSON_trans_targs[_trans]; - - if ( _JSON_trans_actions[_trans] == 0 ) - goto _again; - - _acts = _JSON_actions + _JSON_trans_actions[_trans]; - _nacts = (unsigned int) *_acts++; - while ( _nacts-- > 0 ) + switch ( cs ) { - switch ( *_acts++ ) - { - case 0: -#line 727 "ext/json/ext/parser/parser.rl" +st1: + if ( ++p == pe ) + goto _test_eof1; +case 1: + switch( (*p) ) { + case 13: goto st1; + case 32: goto st1; + case 34: goto tr2; + case 45: goto tr2; + case 47: goto st6; + case 73: goto tr2; + case 78: goto tr2; + case 91: goto tr2; + case 102: goto tr2; + case 110: goto tr2; + case 116: goto tr2; + case 123: goto tr2; + } + if ( (*p) > 10 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr2; + } else if ( (*p) >= 9 ) + goto st1; + goto st0; +st0: +cs = 0; + goto _out; +tr2: +#line 727 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); - if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} } - break; -#line 1823 "ext/json/ext/parser/parser.c" - } + goto st10; +st10: + if ( ++p == pe ) + goto _test_eof10; +case 10: +#line 1905 "parser.c" + switch( (*p) ) { + case 13: goto st10; + case 32: goto st10; + case 47: goto st2; + } + if ( 9 <= (*p) && (*p) <= 10 ) + goto st10; + goto st0; +st2: + if ( ++p == pe ) + goto _test_eof2; +case 2: + switch( (*p) ) { + case 42: goto st3; + case 47: goto st5; + } + goto st0; +st3: + if ( ++p == pe ) + goto _test_eof3; +case 3: + if ( (*p) == 42 ) + goto st4; + goto st3; +st4: + if ( ++p == pe ) + goto _test_eof4; +case 4: + switch( (*p) ) { + case 42: goto st4; + case 47: goto st10; + } + goto st3; +st5: + if ( ++p == pe ) + goto _test_eof5; +case 5: + if ( (*p) == 10 ) + goto st10; + goto st5; +st6: + if ( ++p == pe ) + goto _test_eof6; +case 6: + switch( (*p) ) { + case 42: goto st7; + case 47: goto st9; + } + goto st0; +st7: + if ( ++p == pe ) + goto _test_eof7; +case 7: + if ( (*p) == 42 ) + goto st8; + goto st7; +st8: + if ( ++p == pe ) + goto _test_eof8; +case 8: + switch( (*p) ) { + case 42: goto st8; + case 47: goto st1; + } + goto st7; +st9: + if ( ++p == pe ) + goto _test_eof9; +case 9: + if ( (*p) == 10 ) + goto st1; + goto st9; } + _test_eof1: cs = 1; goto _test_eof; + _test_eof10: cs = 10; goto _test_eof; + _test_eof2: cs = 2; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof6: cs = 6; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof9: cs = 9; goto _test_eof; -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; _test_eof: {} _out: {} } -#line 754 "ext/json/ext/parser/parser.rl" +#line 754 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index 03b4c892e..dc660268e 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -578,7 +578,7 @@ static VALUE convert_encoding(VALUE source) } FORCE_UTF8(source); } else { - source = rb_str_conv_enc(source, NULL, rb_utf8_encoding()); + source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding()); } #endif return source; diff --git a/json.gemspec b/json.gemspec index 631d372942e58c500050265f6915b737144b58af..f97fdc3cd01c831e6f91a3ae1aafacbc8a271ed3 100644 GIT binary patch delta 39 vcmaE;^-ycW8b&sAT?0d1!_Au*nFQJFY!wXkEGO?0QeigJv)KGlsDTLp_IL}K delta 39 vcmaE;^-ycW8b&rVT|+}%qs^NbnFQJD>=caj3?}aqQeigLGur%6sDTLp`p65+ diff --git a/json_pure.gemspec b/json_pure.gemspec index a279a7b3b..da7a564d8 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2016-11-22" + s.date = "2017-01-12" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] @@ -16,8 +16,8 @@ Gem::Specification.new do |s| s.homepage = "http://flori.github.com/json".freeze s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] - s.required_ruby_version = Gem::Requirement.new("~> 2.0".freeze) - s.rubygems_version = "2.5.2".freeze + s.required_ruby_version = Gem::Requirement.new(">= 1.9".freeze) + s.rubygems_version = "2.6.8".freeze s.summary = "JSON Implementation for Ruby".freeze s.test_files = ["./tests/test_helper.rb".freeze] From bc9664348b7a58f2ac0c4aef0181eccad58c66da Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 12 Jan 2017 13:06:02 +0100 Subject: [PATCH 188/312] Let's not get ahead of ourselves --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9bbb218c2..39b6085ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,6 @@ language: ruby # Specify which ruby versions you wish to run your tests on, each version will be used rvm: - - 1.9.2 - 1.9.3 - 2.0.0 - 2.1 From c9fc0f047b11497bb30c75880a9f5af7698d350b Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Sun, 22 Jan 2017 22:18:37 +0100 Subject: [PATCH 189/312] Remove unused macro --- ext/json/ext/fbuffer/fbuffer.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/ext/json/ext/fbuffer/fbuffer.h b/ext/json/ext/fbuffer/fbuffer.h index 5a0a27cda..dc8f406b5 100644 --- a/ext/json/ext/fbuffer/fbuffer.h +++ b/ext/json/ext/fbuffer/fbuffer.h @@ -12,9 +12,6 @@ #define RFLOAT_VALUE(val) (RFLOAT(val)->value) #endif -#ifndef RARRAY_PTR -#define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr -#endif #ifndef RARRAY_LEN #define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len #endif From 3b7f8b0e76d6e5a33cbf0f91fe252b6625768512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xu=C3=A2n=20Baldauf?= Date: Sun, 19 Mar 2017 13:26:07 +0100 Subject: [PATCH 190/312] Actually test BigDecimal parsing. --- tests/json_parser_test.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb index 40ad500cb..f36e9c84e 100644 --- a/tests/json_parser_test.rb +++ b/tests/json_parser_test.rb @@ -108,6 +108,11 @@ def test_parse_numbers assert_equal -1.0/0, parse('-Infinity', :allow_nan => true) end + def test_parse_bigdecimals + assert_equal(BigDecimal, JSON.parse('{"foo": 9.01234567890123456789}', decimal_class: BigDecimal)["foo"].class) + assert_equal(BigDecimal.new("0.901234567890123456789E1"),JSON.parse('{"foo": 9.01234567890123456789}', decimal_class: BigDecimal)["foo"] ) + end + if Array.method_defined?(:permutation) def test_parse_more_complex_arrays a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }] From 27eeabf4c9a4916adf5a42554bfa451034653167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xu=C3=A2n=20Baldauf?= Date: Mon, 27 Mar 2017 19:57:40 +0200 Subject: [PATCH 191/312] Back-out change of directory of json-java.gemspec. --- Gemfile | 2 +- Rakefile | 2 +- java/json.gemspec => json-java.gemspec | 6 +----- 3 files changed, 3 insertions(+), 7 deletions(-) rename java/json.gemspec => json-java.gemspec (85%) diff --git a/Gemfile b/Gemfile index 747bc7121..64f98d6c9 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ source 'https://rubygems.org' case ENV['JSON'] when 'ext', nil if ENV['RUBY_ENGINE'] == 'jruby' - gemspec :name => 'json', :path => 'java' + gemspec :name => 'json-java' else gemspec :name => 'json' end diff --git a/Rakefile b/Rakefile index 017d14a3d..c6c195f9f 100644 --- a/Rakefile +++ b/Rakefile @@ -251,7 +251,7 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby' desc "Package the jruby gem" task :jruby_gem => :create_jar do - sh 'gem build java/json.gemspec' + sh 'gem build json-java.gemspec' mkdir_p 'pkg' mv "json-#{PKG_VERSION}-java.gem", 'pkg' end diff --git a/java/json.gemspec b/json-java.gemspec similarity index 85% rename from java/json.gemspec rename to json-java.gemspec index e0e4efefc..1524b1f9a 100644 --- a/java/json.gemspec +++ b/json-java.gemspec @@ -3,11 +3,7 @@ require "rubygems" spec = Gem::Specification.new do |s| s.name = "json" - s.version = if File.exist?('VERSION') - File.read("VERSION").chomp - else - File.read("../VERSION").chomp - end + s.version = File.read("VERSION").chomp s.summary = "JSON implementation for JRuby" s.description = "A JSON implementation as a JRuby extension." s.author = "Daniel Luz" From 8f782fd8e181d9cfe9387ded43a5ca9692266b85 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 2 Mar 2017 12:12:33 +0100 Subject: [PATCH 192/312] Fix arbitrary heap exposure problem --- ext/json/ext/generator/generator.c | 12 ++++++------ ext/json/ext/generator/generator.h | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index ef85bb733..2bf807456 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -308,7 +308,7 @@ static char *fstrndup(const char *ptr, unsigned long len) { char *result; if (len <= 0) return NULL; result = ALLOC_N(char, len); - memccpy(result, ptr, 0, len); + memcpy(result, ptr, len); return result; } @@ -1062,7 +1062,7 @@ static VALUE cState_indent_set(VALUE self, VALUE indent) } } else { if (state->indent) ruby_xfree(state->indent); - state->indent = strdup(RSTRING_PTR(indent)); + state->indent = fstrndup(RSTRING_PTR(indent), len); state->indent_len = len; } return Qnil; @@ -1100,7 +1100,7 @@ static VALUE cState_space_set(VALUE self, VALUE space) } } else { if (state->space) ruby_xfree(state->space); - state->space = strdup(RSTRING_PTR(space)); + state->space = fstrndup(RSTRING_PTR(space), len); state->space_len = len; } return Qnil; @@ -1136,7 +1136,7 @@ static VALUE cState_space_before_set(VALUE self, VALUE space_before) } } else { if (state->space_before) ruby_xfree(state->space_before); - state->space_before = strdup(RSTRING_PTR(space_before)); + state->space_before = fstrndup(RSTRING_PTR(space_before), len); state->space_before_len = len; } return Qnil; @@ -1173,7 +1173,7 @@ static VALUE cState_object_nl_set(VALUE self, VALUE object_nl) } } else { if (state->object_nl) ruby_xfree(state->object_nl); - state->object_nl = strdup(RSTRING_PTR(object_nl)); + state->object_nl = fstrndup(RSTRING_PTR(object_nl), len); state->object_nl_len = len; } return Qnil; @@ -1208,7 +1208,7 @@ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl) } } else { if (state->array_nl) ruby_xfree(state->array_nl); - state->array_nl = strdup(RSTRING_PTR(array_nl)); + state->array_nl = fstrndup(RSTRING_PTR(array_nl), len); state->array_nl_len = len; } return Qnil; diff --git a/ext/json/ext/generator/generator.h b/ext/json/ext/generator/generator.h index 900b4d58f..c367a6209 100644 --- a/ext/json/ext/generator/generator.h +++ b/ext/json/ext/generator/generator.h @@ -1,7 +1,6 @@ #ifndef _GENERATOR_H_ #define _GENERATOR_H_ -#include #include #include From f94da5a9bf3dfe841ff217e4c2d0c9a13252c627 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 23 Mar 2017 14:26:12 +0100 Subject: [PATCH 193/312] Raise exception for incomplete unicode surrogates/character escape sequences --- ext/json/ext/parser/parser.c | 46 ++++++++++++++++++++-------------- ext/json/ext/parser/parser.rl | 12 +++++++-- json.gemspec | Bin 5473 -> 5474 bytes json_pure.gemspec | 4 +-- tests/json_encoding_test.rb | 2 ++ 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 5a4da4054..2546d46f4 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1443,13 +1443,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) break; case 'u': if (pe > stringEnd - 4) { - return Qnil; + rb_enc_raise( + EXC_ENCODING eParserError, + "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p + ); } else { UTF32 ch = unescape_unicode((unsigned char *) ++pe); pe += 3; if (UNI_SUR_HIGH_START == (ch & 0xFC00)) { pe++; - if (pe > stringEnd - 6) return Qnil; + if (pe > stringEnd - 6) { + rb_enc_raise( + EXC_ENCODING eParserError, + "%u: incomplete surrogate pair at '%s'", __LINE__, p + ); + } if (pe[0] == '\\' && pe[1] == 'u') { UTF32 sur = unescape_unicode((unsigned char *) pe + 2); ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) @@ -1479,7 +1487,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1483 "parser.c" +#line 1491 "parser.c" enum {JSON_string_start = 1}; enum {JSON_string_first_final = 8}; enum {JSON_string_error = 0}; @@ -1487,7 +1495,7 @@ enum {JSON_string_error = 0}; enum {JSON_string_en_main = 1}; -#line 512 "parser.rl" +#line 520 "parser.rl" static int @@ -1509,15 +1517,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = rb_str_buf_new(0); -#line 1513 "parser.c" +#line 1521 "parser.c" { cs = JSON_string_start; } -#line 533 "parser.rl" +#line 541 "parser.rl" json->memo = p; -#line 1521 "parser.c" +#line 1529 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1542,7 +1550,7 @@ case 2: goto st0; goto st2; tr2: -#line 498 "parser.rl" +#line 506 "parser.rl" { *result = json_string_unescape(*result, json->memo + 1, p); if (NIL_P(*result)) { @@ -1553,14 +1561,14 @@ case 2: {p = (( p + 1))-1;} } } -#line 509 "parser.rl" +#line 517 "parser.rl" { p--; {p++; cs = 8; goto _out;} } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: -#line 1564 "parser.c" +#line 1572 "parser.c" goto st0; st3: if ( ++p == pe ) @@ -1636,7 +1644,7 @@ case 7: _out: {} } -#line 535 "parser.rl" +#line 543 "parser.rl" if (json->create_additions && RTEST(match_string = json->match_string)) { VALUE klass; @@ -1823,7 +1831,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1827 "parser.c" +#line 1835 "parser.c" enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1831,7 +1839,7 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; -#line 735 "parser.rl" +#line 743 "parser.rl" /* @@ -1848,16 +1856,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -#line 1852 "parser.c" +#line 1860 "parser.c" { cs = JSON_start; } -#line 751 "parser.rl" +#line 759 "parser.rl" p = json->source; pe = p + json->len; -#line 1861 "parser.c" +#line 1869 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1891,7 +1899,7 @@ case 1: cs = 0; goto _out; tr2: -#line 727 "parser.rl" +#line 735 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1901,7 +1909,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1905 "parser.c" +#line 1913 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1990,7 +1998,7 @@ case 9: _out: {} } -#line 754 "parser.rl" +#line 762 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index dc660268e..de2ef6976 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -454,13 +454,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) break; case 'u': if (pe > stringEnd - 4) { - return Qnil; + rb_enc_raise( + EXC_ENCODING eParserError, + "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p + ); } else { UTF32 ch = unescape_unicode((unsigned char *) ++pe); pe += 3; if (UNI_SUR_HIGH_START == (ch & 0xFC00)) { pe++; - if (pe > stringEnd - 6) return Qnil; + if (pe > stringEnd - 6) { + rb_enc_raise( + EXC_ENCODING eParserError, + "%u: incomplete surrogate pair at '%s'", __LINE__, p + ); + } if (pe[0] == '\\' && pe[1] == 'u') { UTF32 sur = unescape_unicode((unsigned char *) pe + 2); ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) diff --git a/json.gemspec b/json.gemspec index f97fdc3cd01c831e6f91a3ae1aafacbc8a271ed3..d6ca864e6f97568741ee953b5a829f581cab232a 100644 GIT binary patch delta 25 hcmaE;^+;>OdPWvwT_fYon;CTlnG6j!KNM= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2017-01-12" + s.date = "2017-03-23" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] s.required_ruby_version = Gem::Requirement.new(">= 1.9".freeze) - s.rubygems_version = "2.6.8".freeze + s.rubygems_version = "2.6.10".freeze s.summary = "JSON Implementation for Ruby".freeze s.test_files = ["./tests/test_helper.rb".freeze] diff --git a/tests/json_encoding_test.rb b/tests/json_encoding_test.rb index 29ae02e56..4e086ef84 100644 --- a/tests/json_encoding_test.rb +++ b/tests/json_encoding_test.rb @@ -79,6 +79,8 @@ def test_unicode json = '["\ud840\udc01"]' assert_equal json, generate(utf8, :ascii_only => true) assert_equal utf8, parse(json) + assert_raises(JSON::ParserError) { parse('"\u"') } + assert_raises(JSON::ParserError) { parse('"\ud800"') } end def test_chars From 5ab3c81fe30600811f02faa0a9d815ac0f0d8f24 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Mon, 10 Apr 2017 09:40:32 +0200 Subject: [PATCH 194/312] New gemspecs --- json.gemspec | Bin 5474 -> 5474 bytes json_pure.gemspec | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/json.gemspec b/json.gemspec index d6ca864e6f97568741ee953b5a829f581cab232a..e9920a56cb1a08d42bb650499253b14640aed201 100644 GIT binary patch delta 24 gcmaE)^+;>OdPWu#T|484Wi-5^7)q0CBMhKmY&$ delta 24 gcmaE)^+;>OdPWvwT_fYon;G>484Wf+5^7)q0CCU=LI3~& diff --git a/json_pure.gemspec b/json_pure.gemspec index 417787c75..cd3c59bd9 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2017-03-23" + s.date = "2017-04-10" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] s.required_ruby_version = Gem::Requirement.new(">= 1.9".freeze) - s.rubygems_version = "2.6.10".freeze + s.rubygems_version = "2.6.11".freeze s.summary = "JSON Implementation for Ruby".freeze s.test_files = ["./tests/test_helper.rb".freeze] From 68fede4510f1404d62f98eb911eb0746d68602a6 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 18 Apr 2017 11:01:04 +0200 Subject: [PATCH 195/312] Test the new feature and fix problems - Initialize i_new - Add to changes - Test on ruby 2.4.1 --- .travis.yml | 2 +- CHANGES.md | 13 ++++++++ ext/json/ext/parser/parser.c | 58 +++++++++++++++++----------------- ext/json/ext/parser/parser.rl | 4 +-- json.gemspec | Bin 5474 -> 5473 bytes json_pure.gemspec | 4 +-- 6 files changed, 47 insertions(+), 34 deletions(-) diff --git a/.travis.yml b/.travis.yml index 39b6085ab..e2eeda56e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ rvm: - 2.1 - 2.2 - 2.3.3 - - 2.4.0 + - 2.4.1 - jruby - ruby-head matrix: diff --git a/CHANGES.md b/CHANGES.md index d0c4ad5fc..d96e9ae9d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,18 @@ # Changes +## 2017-04-18 (2.1.0) + * Allow passing of `decimal_class` option to specify a class as which to parse + JSON float numbers. +## 2017-03-23 (2.0.4) + * Raise exception for incomplete unicode surrogates/character escape + sequences. This problem was reported by Daniel Gollahon (dgollahon). + * Fix arbitrary heap exposure problem. This problem was reported by Ahmad + Sherif (ahmadsherif). + +## 2017-01-12 (2.0.3) + * Set `required_ruby_version` to 1.9 + * Some small fixes + ## 2016-07-26 (2.0.2) * Specify `required_ruby_version` for json\_pure. * Fix issue #295 failure when parsing frozen strings. diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 2546d46f4..d2e4eb668 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1133,8 +1133,7 @@ case 7: fbuffer_append_char(json->fbuffer, '\0'); if (NIL_P(json->decimal_class)) { *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); - } - else { + } else { VALUE text; text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); *result = rb_funcall(json->decimal_class, i_new, 1, text); @@ -1147,7 +1146,7 @@ case 7: -#line 1151 "parser.c" +#line 1150 "parser.c" enum {JSON_array_start = 1}; enum {JSON_array_first_final = 17}; enum {JSON_array_error = 0}; @@ -1155,7 +1154,7 @@ enum {JSON_array_error = 0}; enum {JSON_array_en_main = 1}; -#line 399 "parser.rl" +#line 398 "parser.rl" static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -1169,14 +1168,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); -#line 1173 "parser.c" +#line 1172 "parser.c" { cs = JSON_array_start; } -#line 412 "parser.rl" +#line 411 "parser.rl" -#line 1180 "parser.c" +#line 1179 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1215,7 +1214,7 @@ case 2: goto st2; goto st0; tr2: -#line 376 "parser.rl" +#line 375 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); @@ -1235,7 +1234,7 @@ case 2: if ( ++p == pe ) goto _test_eof3; case 3: -#line 1239 "parser.c" +#line 1238 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -1335,14 +1334,14 @@ case 12: goto st3; goto st12; tr4: -#line 391 "parser.rl" +#line 390 "parser.rl" { p--; {p++; cs = 17; goto _out;} } goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: -#line 1346 "parser.c" +#line 1345 "parser.c" goto st0; st13: if ( ++p == pe ) @@ -1398,7 +1397,7 @@ case 16: _out: {} } -#line 413 "parser.rl" +#line 412 "parser.rl" if(cs >= JSON_array_first_final) { return p + 1; @@ -1487,7 +1486,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1491 "parser.c" +#line 1490 "parser.c" enum {JSON_string_start = 1}; enum {JSON_string_first_final = 8}; enum {JSON_string_error = 0}; @@ -1495,7 +1494,7 @@ enum {JSON_string_error = 0}; enum {JSON_string_en_main = 1}; -#line 520 "parser.rl" +#line 519 "parser.rl" static int @@ -1517,15 +1516,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = rb_str_buf_new(0); -#line 1521 "parser.c" +#line 1520 "parser.c" { cs = JSON_string_start; } -#line 541 "parser.rl" +#line 540 "parser.rl" json->memo = p; -#line 1529 "parser.c" +#line 1528 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1550,7 +1549,7 @@ case 2: goto st0; goto st2; tr2: -#line 506 "parser.rl" +#line 505 "parser.rl" { *result = json_string_unescape(*result, json->memo + 1, p); if (NIL_P(*result)) { @@ -1561,14 +1560,14 @@ case 2: {p = (( p + 1))-1;} } } -#line 517 "parser.rl" +#line 516 "parser.rl" { p--; {p++; cs = 8; goto _out;} } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: -#line 1572 "parser.c" +#line 1571 "parser.c" goto st0; st3: if ( ++p == pe ) @@ -1644,7 +1643,7 @@ case 7: _out: {} } -#line 543 "parser.rl" +#line 542 "parser.rl" if (json->create_additions && RTEST(match_string = json->match_string)) { VALUE klass; @@ -1831,7 +1830,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1835 "parser.c" +#line 1834 "parser.c" enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1839,7 +1838,7 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; -#line 743 "parser.rl" +#line 742 "parser.rl" /* @@ -1856,16 +1855,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -#line 1860 "parser.c" +#line 1859 "parser.c" { cs = JSON_start; } -#line 759 "parser.rl" +#line 758 "parser.rl" p = json->source; pe = p + json->len; -#line 1869 "parser.c" +#line 1868 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1899,7 +1898,7 @@ case 1: cs = 0; goto _out; tr2: -#line 735 "parser.rl" +#line 734 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1909,7 +1908,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1913 "parser.c" +#line 1912 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1998,7 +1997,7 @@ case 9: _out: {} } -#line 762 "parser.rl" +#line 761 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -2098,6 +2097,7 @@ void Init_parser(void) i_aset = rb_intern("[]="); i_aref = rb_intern("[]"); i_leftshift = rb_intern("<<"); + i_new = rb_intern("new"); } /* diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index de2ef6976..29900a4a4 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -354,8 +354,7 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul fbuffer_append_char(json->fbuffer, '\0'); if (NIL_P(json->decimal_class)) { *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); - } - else { + } else { VALUE text; text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); *result = rb_funcall(json->decimal_class, i_new, 1, text); @@ -858,6 +857,7 @@ void Init_parser(void) i_aset = rb_intern("[]="); i_aref = rb_intern("[]"); i_leftshift = rb_intern("<<"); + i_new = rb_intern("new"); } /* diff --git a/json.gemspec b/json.gemspec index e9920a56cb1a08d42bb650499253b14640aed201..68a04bcbfe3b79522d823b3808de3ec975873795 100644 GIT binary patch delta 21 bcmaE)^-ycWCPqe!&6^o@1%cEfp#~-ZUnK{- delta 22 ecmaE;^+;>OCPqes&6^o@1(^&DH$N0=U;+STJ_p?Z diff --git a/json_pure.gemspec b/json_pure.gemspec index cd3c59bd9..5043beb5f 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2017-04-10" + s.date = "2017-04-18" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] s.required_ruby_version = Gem::Requirement.new(">= 1.9".freeze) - s.rubygems_version = "2.6.11".freeze + s.rubygems_version = "2.6.8".freeze s.summary = "JSON Implementation for Ruby".freeze s.test_files = ["./tests/test_helper.rb".freeze] From 6d72031b7db09468064d5c27da7b196410fb5d94 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 18 Apr 2017 11:10:48 +0200 Subject: [PATCH 196/312] newest version --- json.gemspec | Bin 5473 -> 5474 bytes json_pure.gemspec | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/json.gemspec b/json.gemspec index 68a04bcbfe3b79522d823b3808de3ec975873795..4b68c377f3c5ec15b67a6663a5b9de7330e8025d 100644 GIT binary patch delta 15 WcmaE;^+;>O10g0u!_5zc8khh$wgyH3 delta 14 VcmaE)^-ycW10hC>&5wi{m;f`(1{?qY diff --git a/json_pure.gemspec b/json_pure.gemspec index 5043beb5f..315fed79f 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] s.required_ruby_version = Gem::Requirement.new(">= 1.9".freeze) - s.rubygems_version = "2.6.8".freeze + s.rubygems_version = "2.6.11".freeze s.summary = "JSON Implementation for Ruby".freeze s.test_files = ["./tests/test_helper.rb".freeze] From 7cd07fabbe8ca1242304eb21ac8245eef0fb9343 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 18 Apr 2017 11:11:47 +0200 Subject: [PATCH 197/312] Use assert_raise --- tests/json_encoding_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/json_encoding_test.rb b/tests/json_encoding_test.rb index 4e086ef84..cc7b71553 100644 --- a/tests/json_encoding_test.rb +++ b/tests/json_encoding_test.rb @@ -79,8 +79,8 @@ def test_unicode json = '["\ud840\udc01"]' assert_equal json, generate(utf8, :ascii_only => true) assert_equal utf8, parse(json) - assert_raises(JSON::ParserError) { parse('"\u"') } - assert_raises(JSON::ParserError) { parse('"\ud800"') } + assert_raise(JSON::ParserError) { parse('"\u"') } + assert_raise(JSON::ParserError) { parse('"\ud800"') } end def test_chars From 4688035c424a26a8d943c261170988f1b788fa56 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Tue, 18 Apr 2017 11:16:28 +0200 Subject: [PATCH 198/312] Moving json java gemspec from here to there --- json.gemspec | Bin 5474 -> 5474 bytes json_pure.gemspec | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/json.gemspec b/json.gemspec index 4b68c377f3c5ec15b67a6663a5b9de7330e8025d..b8f3009a9c7b797c77d7f249debf50085383f40f 100644 GIT binary patch delta 31 ncmaE)^+;>OXV%FJ*myU~usJia>SiUDB~Fg#5Z@fn!ORN)z_OXI7r9;`}_l^wiwqg4E>6>)B;Du{kqsj^|+J1px0Q3?={o diff --git a/json_pure.gemspec b/json_pure.gemspec index 315fed79f..4964a42c0 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] - s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/json.gemspec".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] + s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] s.homepage = "http://flori.github.com/json".freeze s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] From abce1e45a62613bd41db7ed66bdb753e1efc8b85 Mon Sep 17 00:00:00 2001 From: Per Lundberg Date: Wed, 31 May 2017 13:00:47 +0300 Subject: [PATCH 199/312] README: Fixed code examples to start in the left-most column I feel that it's more natural this way. What do you think, do you prefer the current style? --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index f9cd95d56..a2dfe7136 100644 --- a/README.md +++ b/README.md @@ -179,14 +179,14 @@ should return a JSON object (a hash converted to JSON with `#to_json`) like this (don't forget the `*a` for all the arguments): ```ruby - class Range - def to_json(*a) - { - 'json_class' => self.class.name, # = 'Range' - 'data' => [ first, last, exclude_end? ] - }.to_json(*a) - end - end +class Range + def to_json(*a) + { + 'json_class' => self.class.name, # = 'Range' + 'data' => [ first, last, exclude_end? ] + }.to_json(*a) + end +end ``` The hash key `json_class` is the class, that will be asked to deserialise the @@ -200,20 +200,20 @@ called with the JSON object converted to a Ruby hash. So a range can be deserialised by implementing `Range.json_create` like this: ```ruby - class Range - def self.json_create(o) - new(*o['data']) - end - end +class Range + def self.json_create(o) + new(*o['data']) + end +end ``` Now it possible to serialise/deserialise ranges as well: ```ruby - json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] - # => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]" - JSON.parse json - # => [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +# => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]" +JSON.parse json +# => [1, 2, {"a"=>3.141}, false, true, nil, 4..10] ``` `JSON.generate` always creates the shortest possible string representation of a From 4c3fa82f905c2b01cc9186c0b701c0f1b1956a11 Mon Sep 17 00:00:00 2001 From: Per Lundberg Date: Wed, 31 May 2017 13:42:43 +0300 Subject: [PATCH 200/312] Fixed json_create example to use create_additions = true The example doesn't work OOTB, since this flag is _not enabled_ by default. (Even with this change in place, I cannot get additions to work with the `Range` class. For custom objects it works though, I tested with the example from the `json_addition_test.rb` - that's where I got the working approach.) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9cd95d56..7d5b15692 100644 --- a/README.md +++ b/README.md @@ -212,7 +212,7 @@ Now it possible to serialise/deserialise ranges as well: ```ruby json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] # => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]" - JSON.parse json + JSON.parse json, :create_additions => true # => [1, 2, {"a"=>3.141}, false, true, nil, 4..10] ``` From c50106e191049a582a4d400f637e29b7b67fea48 Mon Sep 17 00:00:00 2001 From: Per Lundberg Date: Thu, 1 Jun 2017 17:06:05 +0300 Subject: [PATCH 201/312] README: Added note about json/add/exception --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 45e1348b3..2ef93dcb4 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,18 @@ require 'json/add/rails' Both of the additions attempt to require `'json'` (like above) first, if it has not been required yet. +## Serializing exceptions + +The JSON module doesn't extend `Exception` by default. If you convert an `Exception` +object to JSON, it will by default only include the exception message. + +To include the full details, you must either load the load the `json/add/core` mentioned +above, or specifically load the exception addition: + +```ruby +require 'json/add/exception' +``` + ## More Examples To create a JSON document from a ruby data structure, you can call From 05bd14ffc24fe0dc88f2560b9acab1465dc7169b Mon Sep 17 00:00:00 2001 From: SHIBATA Hiroshi Date: Fri, 16 Jun 2017 13:56:14 +0900 Subject: [PATCH 202/312] Added missing bigdecimal for its test --- tests/json_parser_test.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/json_parser_test.rb b/tests/json_parser_test.rb index f36e9c84e..5f454eb12 100644 --- a/tests/json_parser_test.rb +++ b/tests/json_parser_test.rb @@ -4,6 +4,7 @@ require 'stringio' require 'tempfile' require 'ostruct' +require 'bigdecimal' class JSONParserTest < Test::Unit::TestCase include JSON From 4753d185eb7d74806c43716db846febf33b9cd23 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Wed, 21 Jun 2017 11:50:59 +0200 Subject: [PATCH 203/312] simplecov breaks testing => removed --- Gemfile | 2 -- json.gemspec | Bin 5474 -> 5474 bytes json_pure.gemspec | 2 +- tests/test_helper.rb | 4 ---- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 64f98d6c9..8fe591e03 100644 --- a/Gemfile +++ b/Gemfile @@ -12,5 +12,3 @@ when 'ext', nil when 'pure' gemspec :name => 'json_pure' end - -gem 'simplecov' diff --git a/json.gemspec b/json.gemspec index b8f3009a9c7b797c77d7f249debf50085383f40f..24795b2795353d4a837a593396a00387f589a13e 100644 GIT binary patch delta 17 ZcmaE)^+;>OdPWvAT_eNIn;F*&0{}oJ25bNT delta 17 ZcmaE)^+;>OdPWu#T|= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2017-04-18" + s.date = "2017-06-21" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] diff --git a/tests/test_helper.rb b/tests/test_helper.rb index 7e99c29d0..c5ec0fca7 100644 --- a/tests/test_helper.rb +++ b/tests/test_helper.rb @@ -15,7 +15,3 @@ require 'byebug' rescue LoadError end -if ENV['START_SIMPLECOV'].to_i == 1 - require 'simplecov' - SimpleCov.start -end From 06f93995137e0a61dd829fef3306fde262f88628 Mon Sep 17 00:00:00 2001 From: Josh Kline Date: Sat, 28 Dec 2013 15:37:33 -0800 Subject: [PATCH 204/312] JSON marshalling support for Set and SortedSet --- lib/json/add/set.rb | 29 +++++++++++++++++++++++++++++ tests/json_addition_test.rb | 10 ++++++++++ 2 files changed, 39 insertions(+) create mode 100644 lib/json/add/set.rb diff --git a/lib/json/add/set.rb b/lib/json/add/set.rb new file mode 100644 index 000000000..71e2a0ac8 --- /dev/null +++ b/lib/json/add/set.rb @@ -0,0 +1,29 @@ +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +defined?(::Set) or require 'set' + +class Set + # Import a JSON Marshalled object. + # + # method used for JSON marshalling support. + def self.json_create(object) + new object['a'] + end + + # Marshal the object to JSON. + # + # method used for JSON marshalling support. + def as_json(*) + { + JSON.create_id => self.class.name, + 'a' => to_a, + } + end + + # return the JSON value + def to_json(*args) + as_json.to_json(*args) + end +end + diff --git a/tests/json_addition_test.rb b/tests/json_addition_test.rb index a028e0f08..61625f89e 100644 --- a/tests/json_addition_test.rb +++ b/tests/json_addition_test.rb @@ -5,6 +5,7 @@ require 'json/add/rational' require 'json/add/bigdecimal' require 'json/add/ostruct' +require 'json/add/set' require 'date' class JSONAdditionTest < Test::Unit::TestCase @@ -190,4 +191,13 @@ def test_ostruct o.foo = { 'bar' => true } assert_equal o, parse(JSON(o), :create_additions => true) end + + def test_set + s = Set.new([:a, :b, :c, :a]) + assert_equal s, JSON.parse(JSON(s), :create_additions => true) + ss = SortedSet.new([:d, :b, :a, :c]) + ss_again = JSON.parse(JSON(ss), :create_additions => true) + assert_kind_of ss.class, ss_again + assert_equal ss, ss_again + end end From b3ec252120f4a5c12de3ffcf16b2540bdea79248 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Wed, 4 Oct 2017 17:55:02 +0200 Subject: [PATCH 205/312] Allow failing 1.9.3 on travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index e2eeda56e..fdd55631b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,5 +15,6 @@ rvm: matrix: allow_failures: - rvm: ruby-head + - rvm: 1.9.3 script: "bundle exec rake" sudo: false From 5d261d369c6497ea42f7568c2a36d0a3a49bfd4f Mon Sep 17 00:00:00 2001 From: Joe Francis Date: Mon, 9 Oct 2017 10:25:17 -0500 Subject: [PATCH 206/312] fix link in travis widget --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2ef93dcb4..720a1a5bf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -# JSON implementation for Ruby ![Travis Widget] -[Travis Widget]: http://travis-ci.org/flori/json.svg?branch=master +# JSON implementation for Ruby + +[![Travis Widget](http://travis-ci.org/flori/json.svg?branch=master)](https://travis-ci.org/flori/json) ## Description From 565c72ba9e70f4262e66dd33fffb307711d6de27 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 21 Dec 2017 09:57:16 +0100 Subject: [PATCH 207/312] fix test as reported in #343 --- tests/json_common_interface_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/json_common_interface_test.rb b/tests/json_common_interface_test.rb index 29b4a5b56..de88c6e89 100644 --- a/tests/json_common_interface_test.rb +++ b/tests/json_common_interface_test.rb @@ -56,7 +56,7 @@ def test_parse end def test_parse_bang - assert_equal [ 1, NaN, 3, ], JSON.parse!('[ 1, NaN, 3 ]') + assert_equal [ 1, Infinity, 3, ], JSON.parse!('[ 1, Infinity, 3 ]') end def test_generate From 2f3f44c180e1fc095006fb6b7749aa395a39d934 Mon Sep 17 00:00:00 2001 From: zverok Date: Thu, 8 Mar 2018 20:32:00 +0200 Subject: [PATCH 208/312] Add :nodoc: for GeneratorMethods --- ext/json/ext/generator/generator.c | 70 ++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 2bf807456..8fd00cea6 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -324,6 +324,76 @@ static char *fstrndup(const char *ptr, unsigned long len) { * */ +/* Explanation of the following: that's the only way to not pollute + * standard library's docs with GeneratorMethods:: which + * are uninformative and take a large place in a list of classes + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Array + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Bignum + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::FalseClass + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Fixnum + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Float + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Hash + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Integer + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::NilClass + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Object + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::String + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::String::Extend + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::TrueClass + * :nodoc: + */ + /* * call-seq: to_json(state = nil) * From 3e371734855199ec12fe9bf19531e5bbd510f323 Mon Sep 17 00:00:00 2001 From: Nicolas Leger Date: Mon, 26 Mar 2018 16:38:37 +0200 Subject: [PATCH 209/312] [CI] Test against Ruby 2.5 --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fdd55631b..d09db8aaa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,8 +8,9 @@ rvm: - 2.0.0 - 2.1 - 2.2 - - 2.3.3 - - 2.4.1 + - 2.3 + - 2.4 + - 2.5 - jruby - ruby-head matrix: From 0d1c2a0f0e62839ccc049cbd3b0810e276d1e1ca Mon Sep 17 00:00:00 2001 From: SHIBATA Hiroshi Date: Thu, 25 Oct 2018 16:19:43 +0800 Subject: [PATCH 210/312] Temporary ignored CI result of JRuby. see https://github.com/flori/json/pull/355 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d09db8aaa..7debc102a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,10 +11,10 @@ rvm: - 2.3 - 2.4 - 2.5 - - jruby - ruby-head matrix: allow_failures: + - rvm: jruby - rvm: ruby-head - rvm: 1.9.3 script: "bundle exec rake" From 78baad8e646180deb1d85da20da31398aa68cad4 Mon Sep 17 00:00:00 2001 From: eregon Date: Fri, 3 Aug 2018 15:11:22 +0000 Subject: [PATCH 211/312] Fix missed update of parser source in r62429 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64175 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/json/ext/parser/parser.rl | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index 29900a4a4..fba01ac0e 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -824,6 +824,7 @@ static VALUE cParser_source(VALUE self) void Init_parser(void) { +#undef rb_intern rb_require("json/common"); mJSON = rb_define_module("JSON"); mExt = rb_define_module_under(mJSON, "Ext"); From 033dd10ac202a94a74652ad93e77c68937cc7b8e Mon Sep 17 00:00:00 2001 From: eregon Date: Fri, 3 Aug 2018 15:11:36 +0000 Subject: [PATCH 212/312] ext/json/parser/parser.c: do not call rb_str_resize() on Time object * See https://github.com/flori/json/issues/342 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64177 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/json/ext/parser/parser.c | 20 +++++++++++--------- ext/json/ext/parser/parser.rl | 4 +++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index d2e4eb668..f41aac58d 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1659,7 +1659,9 @@ case 7: if (json->symbolize_names && json->parsing_name) { *result = rb_str_intern(*result); } else { - rb_str_resize(*result, RSTRING_LEN(*result)); + if (RB_TYPE_P(*result, T_STRING)) { + rb_str_resize(*result, RSTRING_LEN(*result)); + } } if (cs >= JSON_string_first_final) { return p + 1; @@ -1830,7 +1832,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1834 "parser.c" +#line 1836 "parser.c" enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1838,7 +1840,7 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; -#line 742 "parser.rl" +#line 744 "parser.rl" /* @@ -1855,16 +1857,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -#line 1859 "parser.c" +#line 1861 "parser.c" { cs = JSON_start; } -#line 758 "parser.rl" +#line 760 "parser.rl" p = json->source; pe = p + json->len; -#line 1868 "parser.c" +#line 1870 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1898,7 +1900,7 @@ case 1: cs = 0; goto _out; tr2: -#line 734 "parser.rl" +#line 736 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1908,7 +1910,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1912 "parser.c" +#line 1914 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1997,7 +1999,7 @@ case 9: _out: {} } -#line 761 "parser.rl" +#line 763 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index fba01ac0e..edab32b78 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -554,7 +554,9 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu if (json->symbolize_names && json->parsing_name) { *result = rb_str_intern(*result); } else { - rb_str_resize(*result, RSTRING_LEN(*result)); + if (RB_TYPE_P(*result, T_STRING)) { + rb_str_resize(*result, RSTRING_LEN(*result)); + } } if (cs >= JSON_string_first_final) { return p + 1; From 4a10634c9a841c3e233388ebb3da343c95d8a6e2 Mon Sep 17 00:00:00 2001 From: SHIBATA Hiroshi Date: Thu, 25 Oct 2018 21:07:31 +0800 Subject: [PATCH 213/312] Fixup 0d1c2a0f0e62839ccc049cbd3b0810e276d1e1ca --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7debc102a..2c493b9ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,10 +12,11 @@ rvm: - 2.4 - 2.5 - ruby-head + - jruby matrix: allow_failures: - - rvm: jruby - - rvm: ruby-head - rvm: 1.9.3 + - rvm: ruby-head + - rvm: jruby script: "bundle exec rake" sudo: false From 50a6e54c018062b8cbaf418efed51e3bbec81aa1 Mon Sep 17 00:00:00 2001 From: SHIBATA Hiroshi Date: Wed, 31 Oct 2018 09:05:48 +0900 Subject: [PATCH 214/312] Removed control characters from gemspec --- json.gemspec | Bin 5474 -> 5474 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/json.gemspec b/json.gemspec index 24795b2795353d4a837a593396a00387f589a13e..e2e4f4a8909078b8f65b71e5726d37ae66c52e14 100644 GIT binary patch delta 17 YcmaE)^+;<%Jfp(I1UW{9jrEU306q8yfB*mh delta 17 YcmaE)^+;<%JR`%z1UW{AjrEU306Z85KmY&$ From 74691004894c7fa40162e227cdff5ac99e4a2134 Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Sun, 2 Dec 2018 14:26:15 +0900 Subject: [PATCH 215/312] Fix for bigdecimal updates `BigDecimal.new` is no longer available from bigdecimal-1.4.0. --- ext/json/ext/parser/parser.c | 21 +++++++++++++++++++-- ext/json/ext/parser/parser.rl | 21 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index d2e4eb668..d3c8fb261 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -91,12 +91,13 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static VALUE CNaN, CInfinity, CMinusInfinity; +static VALUE cBigDecimal = Qundef; static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class, i_array_class, i_decimal_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_aref, - i_leftshift, i_new; + i_leftshift, i_new, i_BigDecimal; #line 125 "parser.rl" @@ -985,6 +986,18 @@ enum {JSON_float_en_main = 1}; #line 340 "parser.rl" +static int is_bigdecimal_class(VALUE obj) +{ + if (cBigDecimal == Qundef) { + if (rb_const_defined(rb_cObject, i_BigDecimal)) { + cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); + } else { + return 0; + } + } + return obj == cBigDecimal; +} + static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; @@ -1136,7 +1149,11 @@ case 7: } else { VALUE text; text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); - *result = rb_funcall(json->decimal_class, i_new, 1, text); + if (is_bigdecimal_class(json->decimal_class)) { + *result = rb_funcall(Qnil, i_BigDecimal, 1, text); + } else { + *result = rb_funcall(json->decimal_class, i_new, 1, text); + } } return p + 1; } else { diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index 29900a4a4..cf43869d4 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -89,12 +89,13 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static VALUE CNaN, CInfinity, CMinusInfinity; +static VALUE cBigDecimal = Qundef; static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class, i_array_class, i_decimal_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_aref, - i_leftshift, i_new; + i_leftshift, i_new, i_BigDecimal; %%{ machine JSON_common; @@ -339,6 +340,18 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res ) (^[0-9Ee.\-]? @exit ); }%% +static int is_bigdecimal_class(VALUE obj) +{ + if (cBigDecimal == Qundef) { + if (rb_const_defined(rb_cObject, i_BigDecimal)) { + cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); + } else { + return 0; + } + } + return obj == cBigDecimal; +} + static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; @@ -357,7 +370,11 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul } else { VALUE text; text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); - *result = rb_funcall(json->decimal_class, i_new, 1, text); + if (is_bigdecimal_class(json->decimal_class)) { + *result = rb_funcall(Qnil, i_BigDecimal, 1, text); + } else { + *result = rb_funcall(json->decimal_class, i_new, 1, text); + } } return p + 1; } else { From 22579b3ed682e95c6228a0fdbac1adc3b1df4800 Mon Sep 17 00:00:00 2001 From: yui-knk Date: Mon, 10 Dec 2018 07:58:50 +0900 Subject: [PATCH 216/312] "load the" is duplicated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 720a1a5bf..5c7d71d2c 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ not been required yet. The JSON module doesn't extend `Exception` by default. If you convert an `Exception` object to JSON, it will by default only include the exception message. -To include the full details, you must either load the load the `json/add/core` mentioned +To include the full details, you must either load the `json/add/core` mentioned above, or specifically load the exception addition: ```ruby From f5ddeb6bf3319183859d0b7be3d2da1afc483877 Mon Sep 17 00:00:00 2001 From: yui-knk Date: Mon, 10 Dec 2018 08:05:31 +0900 Subject: [PATCH 217/312] Article is duplicated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c7d71d2c..1b15cf104 100644 --- a/README.md +++ b/README.md @@ -207,7 +207,7 @@ JSON representation later. In this case it's `Range`, but any namespace of the form `A::B` or `::A::B` will do. All other keys are arbitrary and can be used to store the necessary data to configure the object to be deserialised. -If a the key `json_class` is found in a JSON object, the JSON parser checks +If the key `json_class` is found in a JSON object, the JSON parser checks if the given class responds to the `json_create` class method. If so, it is called with the JSON object converted to a Ruby hash. So a range can be deserialised by implementing `Range.json_create` like this: From 5dcc4617a5263ea7ef418c4e41e92c6af167c3f5 Mon Sep 17 00:00:00 2001 From: Sho Hashimoto Date: Tue, 8 Jan 2019 00:34:39 +0900 Subject: [PATCH 218/312] fix JSON::Generator::State#ascii_only? document same as lib/json/pure/generator.rb. --- ext/json/ext/generator/generator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 2bf807456..a15f6530c 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -1267,7 +1267,7 @@ static VALUE cState_allow_nan_p(VALUE self) /* * call-seq: ascii_only? * - * Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise + * Returns true, if only ASCII characters should be generated. Otherwise * returns false. */ static VALUE cState_ascii_only_p(VALUE self) From 0e99a9aac5d589a0914886cc5a89583226212ac9 Mon Sep 17 00:00:00 2001 From: Sho Hashimoto Date: Tue, 8 Jan 2019 09:12:05 +0900 Subject: [PATCH 219/312] Add ascii_only option to JSON::Ext::Generator::State.new. --- ext/json/ext/generator/generator.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 2bf807456..10669d72e 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -970,6 +970,8 @@ static VALUE cState_generate(VALUE self, VALUE obj) * * *allow_nan*: true if NaN, Infinity, and -Infinity should be * generated, otherwise an exception is thrown, if these values are * encountered. This options defaults to false. + * * *ascii_only*: true if only ASCII characters should be generated. This + * ontions defaults to false. * * *buffer_initial_length*: sets the initial length of the generator's * internal buffer. */ From ae6ed758bd3c6dbf42158a7e8379320a42cc79b1 Mon Sep 17 00:00:00 2001 From: Sho Hashimoto Date: Wed, 9 Jan 2019 00:18:18 +0900 Subject: [PATCH 220/312] Fix a typo. --- lib/json/add/ostruct.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/add/ostruct.rb b/lib/json/add/ostruct.rb index e064c85ff..686cf0025 100644 --- a/lib/json/add/ostruct.rb +++ b/lib/json/add/ostruct.rb @@ -23,7 +23,7 @@ def as_json(*) } end - # Stores class name (OpenStruct) with this struct's values v as a + # Stores class name (OpenStruct) with this struct's values t as a # JSON string. def to_json(*args) as_json.to_json(*args) From 4123df7d561c60ad50456bfb203ceb02d66b78f2 Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 28 Nov 2018 12:45:01 +0100 Subject: [PATCH 221/312] [build] no need to clean on rake test_pure (similar to test_ext) --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index c6c195f9f..532aacb50 100644 --- a/Rakefile +++ b/Rakefile @@ -176,7 +176,7 @@ task :check_env do end desc "Testing library (pure ruby)" -task :test_pure => [ :clean, :check_env, :do_test_pure ] +task :test_pure => [ :check_env, :do_test_pure ] UndocumentedTestTask.new do |t| t.name = 'do_test_pure' From 645f36ed8a72bd31920efec0abacc0a24d3abe78 Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 28 Nov 2018 12:57:13 +0100 Subject: [PATCH 222/312] [build] let's build with Java 1.6 JRuby 1.7 was Java6+ compatible (9.2 is Java8+) --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 532aacb50..56edecc24 100644 --- a/Rakefile +++ b/Rakefile @@ -238,7 +238,7 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby' classpath = (Dir['java/lib/*.jar'] << 'java/src' << JRUBY_JAR) * ':' obj = src.sub(/\.java\Z/, '.class') file obj => src do - sh 'javac', '-classpath', classpath, '-source', '1.5', '-target', '1.5', src + sh 'javac', '-classpath', classpath, '-source', '1.6', '-target', '1.6', src end JAVA_CLASSES << obj end From 362a7c3eae107773fe7413549de167d532e0e7ae Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 28 Nov 2018 14:46:56 +0100 Subject: [PATCH 223/312] [build] make test_xxx work standalone + avoid bundle exec --- Rakefile | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Rakefile b/Rakefile index 56edecc24..e60cfc119 100644 --- a/Rakefile +++ b/Rakefile @@ -176,7 +176,8 @@ task :check_env do end desc "Testing library (pure ruby)" -task :test_pure => [ :check_env, :do_test_pure ] +task :test_pure => [ :set_env_pure, :check_env, :do_test_pure ] +task(:set_env_pure) { ENV['JSON'] = 'pure' } UndocumentedTestTask.new do |t| t.name = 'do_test_pure' @@ -187,10 +188,7 @@ UndocumentedTestTask.new do |t| end desc "Testing library (pure ruby and extension)" -task :test do - sh "env JSON=pure #{BUNDLE} exec rake test_pure" or exit 1 - sh "env JSON=ext #{BUNDLE} exec rake test_ext" or exit 1 -end +task :test => [ :test_pure, :test_ext ] namespace :gems do desc 'Install all development gems' @@ -257,7 +255,8 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby' end desc "Testing library (jruby)" - task :test_ext => [ :check_env, :create_jar, :do_test_ext ] + task :test_ext => [ :set_env_ext, :create_jar, :check_env, :do_test_ext ] + task(:set_env_ext) { ENV['JSON'] = 'ext' } UndocumentedTestTask.new do |t| t.name = 'do_test_ext' From 354937838cf6c39b4f33df51198db8be4dfd3aa5 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 21 Feb 2019 22:19:04 +0100 Subject: [PATCH 224/312] Add some missing ruby 2.6 changes --- .travis.yml | 1 + ext/json/ext/generator/generator.c | 1 + ext/json/ext/parser/parser.c | 163 +++++++++++++++-------------- ext/json/ext/parser/parser.rl | 18 ++-- json.gemspec | Bin 5474 -> 5503 bytes json_pure.gemspec | 6 +- 6 files changed, 98 insertions(+), 91 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2c493b9ee..1ac58d828 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ rvm: - 2.3 - 2.4 - 2.5 + - 2.6 - ruby-head - jruby matrix: diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 2bf807456..f061267f0 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -1335,6 +1335,7 @@ static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_l */ void Init_generator(void) { +#undef rb_intern rb_require("json/common"); mJSON = rb_define_module("JSON"); diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 595845b1e..f68676879 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -100,11 +100,11 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_leftshift, i_new, i_BigDecimal; -#line 125 "parser.rl" +#line 126 "parser.rl" -#line 107 "parser.c" +#line 108 "parser.c" enum {JSON_object_start = 1}; enum {JSON_object_first_final = 27}; enum {JSON_object_error = 0}; @@ -112,7 +112,7 @@ enum {JSON_object_error = 0}; enum {JSON_object_en_main = 1}; -#line 166 "parser.rl" +#line 167 "parser.rl" static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -128,14 +128,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class); -#line 131 "parser.c" +#line 132 "parser.c" { cs = JSON_object_start; } -#line 181 "parser.rl" +#line 182 "parser.rl" -#line 138 "parser.c" +#line 139 "parser.c" { if ( p == pe ) goto _test_eof; @@ -163,7 +163,7 @@ case 2: goto st2; goto st0; tr2: -#line 148 "parser.rl" +#line 149 "parser.rl" { char *np; json->parsing_name = 1; @@ -176,7 +176,7 @@ case 2: if ( ++p == pe ) goto _test_eof3; case 3: -#line 179 "parser.c" +#line 180 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -243,7 +243,7 @@ case 8: goto st8; goto st0; tr11: -#line 133 "parser.rl" +#line 134 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); @@ -263,7 +263,7 @@ case 8: if ( ++p == pe ) goto _test_eof9; case 9: -#line 266 "parser.c" +#line 267 "parser.c" switch( (*p) ) { case 13: goto st9; case 32: goto st9; @@ -352,14 +352,14 @@ case 18: goto st9; goto st18; tr4: -#line 156 "parser.rl" +#line 157 "parser.rl" { p--; {p++; cs = 27; goto _out;} } goto st27; st27: if ( ++p == pe ) goto _test_eof27; case 27: -#line 362 "parser.c" +#line 363 "parser.c" goto st0; st19: if ( ++p == pe ) @@ -457,7 +457,7 @@ case 26: _out: {} } -#line 182 "parser.rl" +#line 183 "parser.rl" if (cs >= JSON_object_first_final) { if (json->create_additions) { @@ -482,7 +482,7 @@ case 26: -#line 485 "parser.c" +#line 486 "parser.c" enum {JSON_value_start = 1}; enum {JSON_value_first_final = 29}; enum {JSON_value_error = 0}; @@ -490,7 +490,7 @@ enum {JSON_value_error = 0}; enum {JSON_value_en_main = 1}; -#line 282 "parser.rl" +#line 283 "parser.rl" static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -498,14 +498,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 501 "parser.c" +#line 502 "parser.c" { cs = JSON_value_start; } -#line 289 "parser.rl" +#line 290 "parser.rl" -#line 508 "parser.c" +#line 509 "parser.c" { if ( p == pe ) goto _test_eof; @@ -539,14 +539,14 @@ case 1: cs = 0; goto _out; tr2: -#line 234 "parser.rl" +#line 235 "parser.rl" { char *np = JSON_parse_string(json, p, pe, result); if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } goto st29; tr3: -#line 239 "parser.rl" +#line 240 "parser.rl" { char *np; if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) { @@ -566,7 +566,7 @@ cs = 0; } goto st29; tr7: -#line 257 "parser.rl" +#line 258 "parser.rl" { char *np; np = JSON_parse_array(json, p, pe, result, current_nesting + 1); @@ -574,7 +574,7 @@ cs = 0; } goto st29; tr11: -#line 263 "parser.rl" +#line 264 "parser.rl" { char *np; np = JSON_parse_object(json, p, pe, result, current_nesting + 1); @@ -582,7 +582,7 @@ cs = 0; } goto st29; tr25: -#line 227 "parser.rl" +#line 228 "parser.rl" { if (json->allow_nan) { *result = CInfinity; @@ -592,7 +592,7 @@ cs = 0; } goto st29; tr27: -#line 220 "parser.rl" +#line 221 "parser.rl" { if (json->allow_nan) { *result = CNaN; @@ -602,19 +602,19 @@ cs = 0; } goto st29; tr31: -#line 214 "parser.rl" +#line 215 "parser.rl" { *result = Qfalse; } goto st29; tr34: -#line 211 "parser.rl" +#line 212 "parser.rl" { *result = Qnil; } goto st29; tr37: -#line 217 "parser.rl" +#line 218 "parser.rl" { *result = Qtrue; } @@ -623,9 +623,9 @@ cs = 0; if ( ++p == pe ) goto _test_eof29; case 29: -#line 269 "parser.rl" +#line 270 "parser.rl" { p--; {p++; cs = 29; goto _out;} } -#line 628 "parser.c" +#line 629 "parser.c" switch( (*p) ) { case 13: goto st29; case 32: goto st29; @@ -866,7 +866,7 @@ case 28: _out: {} } -#line 290 "parser.rl" +#line 291 "parser.rl" if (cs >= JSON_value_first_final) { return p; @@ -876,7 +876,7 @@ case 28: } -#line 879 "parser.c" +#line 880 "parser.c" enum {JSON_integer_start = 1}; enum {JSON_integer_first_final = 3}; enum {JSON_integer_error = 0}; @@ -884,7 +884,7 @@ enum {JSON_integer_error = 0}; enum {JSON_integer_en_main = 1}; -#line 306 "parser.rl" +#line 307 "parser.rl" static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -892,15 +892,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res int cs = EVIL; -#line 895 "parser.c" +#line 896 "parser.c" { cs = JSON_integer_start; } -#line 313 "parser.rl" +#line 314 "parser.rl" json->memo = p; -#line 903 "parser.c" +#line 904 "parser.c" { if ( p == pe ) goto _test_eof; @@ -934,14 +934,14 @@ case 3: goto st0; goto tr4; tr4: -#line 303 "parser.rl" +#line 304 "parser.rl" { p--; {p++; cs = 4; goto _out;} } goto st4; st4: if ( ++p == pe ) goto _test_eof4; case 4: -#line 944 "parser.c" +#line 945 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -960,7 +960,7 @@ case 5: _out: {} } -#line 315 "parser.rl" +#line 316 "parser.rl" if (cs >= JSON_integer_first_final) { long len = p - json->memo; @@ -975,7 +975,7 @@ case 5: } -#line 978 "parser.c" +#line 979 "parser.c" enum {JSON_float_start = 1}; enum {JSON_float_first_final = 8}; enum {JSON_float_error = 0}; @@ -983,19 +983,20 @@ enum {JSON_float_error = 0}; enum {JSON_float_en_main = 1}; -#line 340 "parser.rl" +#line 341 "parser.rl" static int is_bigdecimal_class(VALUE obj) { - if (cBigDecimal == Qundef) { - if (rb_const_defined(rb_cObject, i_BigDecimal)) { - cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); - } else { - return 0; - } + if (cBigDecimal == Qundef) { + if (rb_const_defined(rb_cObject, i_BigDecimal)) { + cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); } - return obj == cBigDecimal; + else { + return 0; + } + } + return obj == cBigDecimal; } static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -1003,15 +1004,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 994 "parser.c" +#line 1008 "parser.c" { cs = JSON_float_start; } -#line 347 "parser.rl" +#line 361 "parser.rl" json->memo = p; -#line 1002 "parser.c" +#line 1016 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1069,14 +1070,14 @@ case 8: goto st0; goto tr9; tr9: -#line 334 "parser.rl" +#line 335 "parser.rl" { p--; {p++; cs = 9; goto _out;} } goto st9; st9: if ( ++p == pe ) goto _test_eof9; case 9: -#line 1067 "parser.c" +#line 1081 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -1137,7 +1138,7 @@ case 7: _out: {} } -#line 349 "parser.rl" +#line 363 "parser.rl" if (cs >= JSON_float_first_final) { long len = p - json->memo; @@ -1163,7 +1164,7 @@ case 7: -#line 1150 "parser.c" +#line 1168 "parser.c" enum {JSON_array_start = 1}; enum {JSON_array_first_final = 17}; enum {JSON_array_error = 0}; @@ -1171,7 +1172,7 @@ enum {JSON_array_error = 0}; enum {JSON_array_en_main = 1}; -#line 398 "parser.rl" +#line 416 "parser.rl" static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -1185,14 +1186,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); -#line 1172 "parser.c" +#line 1190 "parser.c" { cs = JSON_array_start; } -#line 411 "parser.rl" +#line 429 "parser.rl" -#line 1179 "parser.c" +#line 1197 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1231,7 +1232,7 @@ case 2: goto st2; goto st0; tr2: -#line 375 "parser.rl" +#line 393 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); @@ -1251,7 +1252,7 @@ case 2: if ( ++p == pe ) goto _test_eof3; case 3: -#line 1238 "parser.c" +#line 1256 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -1351,14 +1352,14 @@ case 12: goto st3; goto st12; tr4: -#line 390 "parser.rl" +#line 408 "parser.rl" { p--; {p++; cs = 17; goto _out;} } goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: -#line 1345 "parser.c" +#line 1363 "parser.c" goto st0; st13: if ( ++p == pe ) @@ -1414,7 +1415,7 @@ case 16: _out: {} } -#line 412 "parser.rl" +#line 430 "parser.rl" if(cs >= JSON_array_first_final) { return p + 1; @@ -1503,7 +1504,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1490 "parser.c" +#line 1508 "parser.c" enum {JSON_string_start = 1}; enum {JSON_string_first_final = 8}; enum {JSON_string_error = 0}; @@ -1511,7 +1512,7 @@ enum {JSON_string_error = 0}; enum {JSON_string_en_main = 1}; -#line 519 "parser.rl" +#line 537 "parser.rl" static int @@ -1533,15 +1534,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = rb_str_buf_new(0); -#line 1520 "parser.c" +#line 1538 "parser.c" { cs = JSON_string_start; } -#line 540 "parser.rl" +#line 558 "parser.rl" json->memo = p; -#line 1528 "parser.c" +#line 1546 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1566,7 +1567,7 @@ case 2: goto st0; goto st2; tr2: -#line 505 "parser.rl" +#line 523 "parser.rl" { *result = json_string_unescape(*result, json->memo + 1, p); if (NIL_P(*result)) { @@ -1577,14 +1578,14 @@ case 2: {p = (( p + 1))-1;} } } -#line 516 "parser.rl" +#line 534 "parser.rl" { p--; {p++; cs = 8; goto _out;} } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: -#line 1571 "parser.c" +#line 1589 "parser.c" goto st0; st3: if ( ++p == pe ) @@ -1660,7 +1661,7 @@ case 7: _out: {} } -#line 542 "parser.rl" +#line 560 "parser.rl" if (json->create_additions && RTEST(match_string = json->match_string)) { VALUE klass; @@ -1849,7 +1850,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1836 "parser.c" +#line 1854 "parser.c" enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1857,7 +1858,7 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; -#line 744 "parser.rl" +#line 762 "parser.rl" /* @@ -1874,16 +1875,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -#line 1861 "parser.c" +#line 1879 "parser.c" { cs = JSON_start; } -#line 760 "parser.rl" +#line 778 "parser.rl" p = json->source; pe = p + json->len; -#line 1870 "parser.c" +#line 1888 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1917,7 +1918,7 @@ case 1: cs = 0; goto _out; tr2: -#line 736 "parser.rl" +#line 754 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1927,7 +1928,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1914 "parser.c" +#line 1932 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2016,7 +2017,7 @@ case 9: _out: {} } -#line 763 "parser.rl" +#line 781 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -2083,6 +2084,7 @@ static VALUE cParser_source(VALUE self) void Init_parser(void) { +#undef rb_intern rb_require("json/common"); mJSON = rb_define_module("JSON"); mExt = rb_define_module_under(mJSON, "Ext"); @@ -2117,6 +2119,7 @@ void Init_parser(void) i_aref = rb_intern("[]"); i_leftshift = rb_intern("<<"); i_new = rb_intern("new"); + i_BigDecimal = rb_intern("BigDecimal"); } /* diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index c888d9c83..d4e7a60e9 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -342,14 +342,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res static int is_bigdecimal_class(VALUE obj) { - if (cBigDecimal == Qundef) { - if (rb_const_defined(rb_cObject, i_BigDecimal)) { - cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); - } else { - return 0; - } - } - return obj == cBigDecimal; + if (cBigDecimal == Qundef) { + if (rb_const_defined(rb_cObject, i_BigDecimal)) { + cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); + } + else { + return 0; + } + } + return obj == cBigDecimal; } static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -878,6 +879,7 @@ void Init_parser(void) i_aref = rb_intern("[]"); i_leftshift = rb_intern("<<"); i_new = rb_intern("new"); + i_BigDecimal = rb_intern("BigDecimal"); } /* diff --git a/json.gemspec b/json.gemspec index e2e4f4a8909078b8f65b71e5726d37ae66c52e14..32a04ae911dbc0ca40a06a64b8a7ef04399d6fae 100644 GIT binary patch delta 47 zcmaE)^WES9SWEatifW}7!KhH`9H=DN= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2017-06-21" + s.date = "2019-02-21" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] - s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] + s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/set.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] s.homepage = "http://flori.github.com/json".freeze s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] s.required_ruby_version = Gem::Requirement.new(">= 1.9".freeze) - s.rubygems_version = "2.6.11".freeze + s.rubygems_version = "3.0.1".freeze s.summary = "JSON Implementation for Ruby".freeze s.test_files = ["./tests/test_helper.rb".freeze] From ef2092f4d288ff666bcf10ffa43e58a91c649293 Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Sun, 2 Dec 2018 14:26:15 +0900 Subject: [PATCH 225/312] Fix for bigdecimal updates `BigDecimal.new` is no longer available from bigdecimal-1.4.0. --- ext/json/ext/parser/parser.c | 21 +++++++++++++++++++-- ext/json/ext/parser/parser.rl | 21 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index f41aac58d..595845b1e 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -91,12 +91,13 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static VALUE CNaN, CInfinity, CMinusInfinity; +static VALUE cBigDecimal = Qundef; static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class, i_array_class, i_decimal_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_aref, - i_leftshift, i_new; + i_leftshift, i_new, i_BigDecimal; #line 125 "parser.rl" @@ -985,6 +986,18 @@ enum {JSON_float_en_main = 1}; #line 340 "parser.rl" +static int is_bigdecimal_class(VALUE obj) +{ + if (cBigDecimal == Qundef) { + if (rb_const_defined(rb_cObject, i_BigDecimal)) { + cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); + } else { + return 0; + } + } + return obj == cBigDecimal; +} + static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; @@ -1136,7 +1149,11 @@ case 7: } else { VALUE text; text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); - *result = rb_funcall(json->decimal_class, i_new, 1, text); + if (is_bigdecimal_class(json->decimal_class)) { + *result = rb_funcall(Qnil, i_BigDecimal, 1, text); + } else { + *result = rb_funcall(json->decimal_class, i_new, 1, text); + } } return p + 1; } else { diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index edab32b78..c888d9c83 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -89,12 +89,13 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static VALUE CNaN, CInfinity, CMinusInfinity; +static VALUE cBigDecimal = Qundef; static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class, i_array_class, i_decimal_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_aref, - i_leftshift, i_new; + i_leftshift, i_new, i_BigDecimal; %%{ machine JSON_common; @@ -339,6 +340,18 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res ) (^[0-9Ee.\-]? @exit ); }%% +static int is_bigdecimal_class(VALUE obj) +{ + if (cBigDecimal == Qundef) { + if (rb_const_defined(rb_cObject, i_BigDecimal)) { + cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); + } else { + return 0; + } + } + return obj == cBigDecimal; +} + static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; @@ -357,7 +370,11 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul } else { VALUE text; text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); - *result = rb_funcall(json->decimal_class, i_new, 1, text); + if (is_bigdecimal_class(json->decimal_class)) { + *result = rb_funcall(Qnil, i_BigDecimal, 1, text); + } else { + *result = rb_funcall(json->decimal_class, i_new, 1, text); + } } return p + 1; } else { From bb80864914a79b1a9dc2d897e56d1d135324b638 Mon Sep 17 00:00:00 2001 From: Sho Hashimoto Date: Wed, 9 Jan 2019 00:18:18 +0900 Subject: [PATCH 226/312] Fix a typo. --- lib/json/add/ostruct.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/json/add/ostruct.rb b/lib/json/add/ostruct.rb index e064c85ff..686cf0025 100644 --- a/lib/json/add/ostruct.rb +++ b/lib/json/add/ostruct.rb @@ -23,7 +23,7 @@ def as_json(*) } end - # Stores class name (OpenStruct) with this struct's values v as a + # Stores class name (OpenStruct) with this struct's values t as a # JSON string. def to_json(*args) as_json.to_json(*args) From 3eb7e9ed605d7aa035a124cc7d5ad71c734dd81f Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 21 Feb 2019 22:19:04 +0100 Subject: [PATCH 227/312] Add some missing ruby 2.6 changes --- .travis.yml | 1 + ext/json/ext/generator/generator.c | 1 + ext/json/ext/parser/parser.c | 163 +++++++++++++++-------------- ext/json/ext/parser/parser.rl | 18 ++-- json.gemspec | Bin 5474 -> 5503 bytes json_pure.gemspec | 6 +- 6 files changed, 98 insertions(+), 91 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2c493b9ee..1ac58d828 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ rvm: - 2.3 - 2.4 - 2.5 + - 2.6 - ruby-head - jruby matrix: diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 2bf807456..f061267f0 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -1335,6 +1335,7 @@ static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_l */ void Init_generator(void) { +#undef rb_intern rb_require("json/common"); mJSON = rb_define_module("JSON"); diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 595845b1e..f68676879 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -100,11 +100,11 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_leftshift, i_new, i_BigDecimal; -#line 125 "parser.rl" +#line 126 "parser.rl" -#line 107 "parser.c" +#line 108 "parser.c" enum {JSON_object_start = 1}; enum {JSON_object_first_final = 27}; enum {JSON_object_error = 0}; @@ -112,7 +112,7 @@ enum {JSON_object_error = 0}; enum {JSON_object_en_main = 1}; -#line 166 "parser.rl" +#line 167 "parser.rl" static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -128,14 +128,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class); -#line 131 "parser.c" +#line 132 "parser.c" { cs = JSON_object_start; } -#line 181 "parser.rl" +#line 182 "parser.rl" -#line 138 "parser.c" +#line 139 "parser.c" { if ( p == pe ) goto _test_eof; @@ -163,7 +163,7 @@ case 2: goto st2; goto st0; tr2: -#line 148 "parser.rl" +#line 149 "parser.rl" { char *np; json->parsing_name = 1; @@ -176,7 +176,7 @@ case 2: if ( ++p == pe ) goto _test_eof3; case 3: -#line 179 "parser.c" +#line 180 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -243,7 +243,7 @@ case 8: goto st8; goto st0; tr11: -#line 133 "parser.rl" +#line 134 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); @@ -263,7 +263,7 @@ case 8: if ( ++p == pe ) goto _test_eof9; case 9: -#line 266 "parser.c" +#line 267 "parser.c" switch( (*p) ) { case 13: goto st9; case 32: goto st9; @@ -352,14 +352,14 @@ case 18: goto st9; goto st18; tr4: -#line 156 "parser.rl" +#line 157 "parser.rl" { p--; {p++; cs = 27; goto _out;} } goto st27; st27: if ( ++p == pe ) goto _test_eof27; case 27: -#line 362 "parser.c" +#line 363 "parser.c" goto st0; st19: if ( ++p == pe ) @@ -457,7 +457,7 @@ case 26: _out: {} } -#line 182 "parser.rl" +#line 183 "parser.rl" if (cs >= JSON_object_first_final) { if (json->create_additions) { @@ -482,7 +482,7 @@ case 26: -#line 485 "parser.c" +#line 486 "parser.c" enum {JSON_value_start = 1}; enum {JSON_value_first_final = 29}; enum {JSON_value_error = 0}; @@ -490,7 +490,7 @@ enum {JSON_value_error = 0}; enum {JSON_value_en_main = 1}; -#line 282 "parser.rl" +#line 283 "parser.rl" static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -498,14 +498,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 501 "parser.c" +#line 502 "parser.c" { cs = JSON_value_start; } -#line 289 "parser.rl" +#line 290 "parser.rl" -#line 508 "parser.c" +#line 509 "parser.c" { if ( p == pe ) goto _test_eof; @@ -539,14 +539,14 @@ case 1: cs = 0; goto _out; tr2: -#line 234 "parser.rl" +#line 235 "parser.rl" { char *np = JSON_parse_string(json, p, pe, result); if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} } goto st29; tr3: -#line 239 "parser.rl" +#line 240 "parser.rl" { char *np; if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) { @@ -566,7 +566,7 @@ cs = 0; } goto st29; tr7: -#line 257 "parser.rl" +#line 258 "parser.rl" { char *np; np = JSON_parse_array(json, p, pe, result, current_nesting + 1); @@ -574,7 +574,7 @@ cs = 0; } goto st29; tr11: -#line 263 "parser.rl" +#line 264 "parser.rl" { char *np; np = JSON_parse_object(json, p, pe, result, current_nesting + 1); @@ -582,7 +582,7 @@ cs = 0; } goto st29; tr25: -#line 227 "parser.rl" +#line 228 "parser.rl" { if (json->allow_nan) { *result = CInfinity; @@ -592,7 +592,7 @@ cs = 0; } goto st29; tr27: -#line 220 "parser.rl" +#line 221 "parser.rl" { if (json->allow_nan) { *result = CNaN; @@ -602,19 +602,19 @@ cs = 0; } goto st29; tr31: -#line 214 "parser.rl" +#line 215 "parser.rl" { *result = Qfalse; } goto st29; tr34: -#line 211 "parser.rl" +#line 212 "parser.rl" { *result = Qnil; } goto st29; tr37: -#line 217 "parser.rl" +#line 218 "parser.rl" { *result = Qtrue; } @@ -623,9 +623,9 @@ cs = 0; if ( ++p == pe ) goto _test_eof29; case 29: -#line 269 "parser.rl" +#line 270 "parser.rl" { p--; {p++; cs = 29; goto _out;} } -#line 628 "parser.c" +#line 629 "parser.c" switch( (*p) ) { case 13: goto st29; case 32: goto st29; @@ -866,7 +866,7 @@ case 28: _out: {} } -#line 290 "parser.rl" +#line 291 "parser.rl" if (cs >= JSON_value_first_final) { return p; @@ -876,7 +876,7 @@ case 28: } -#line 879 "parser.c" +#line 880 "parser.c" enum {JSON_integer_start = 1}; enum {JSON_integer_first_final = 3}; enum {JSON_integer_error = 0}; @@ -884,7 +884,7 @@ enum {JSON_integer_error = 0}; enum {JSON_integer_en_main = 1}; -#line 306 "parser.rl" +#line 307 "parser.rl" static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -892,15 +892,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res int cs = EVIL; -#line 895 "parser.c" +#line 896 "parser.c" { cs = JSON_integer_start; } -#line 313 "parser.rl" +#line 314 "parser.rl" json->memo = p; -#line 903 "parser.c" +#line 904 "parser.c" { if ( p == pe ) goto _test_eof; @@ -934,14 +934,14 @@ case 3: goto st0; goto tr4; tr4: -#line 303 "parser.rl" +#line 304 "parser.rl" { p--; {p++; cs = 4; goto _out;} } goto st4; st4: if ( ++p == pe ) goto _test_eof4; case 4: -#line 944 "parser.c" +#line 945 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -960,7 +960,7 @@ case 5: _out: {} } -#line 315 "parser.rl" +#line 316 "parser.rl" if (cs >= JSON_integer_first_final) { long len = p - json->memo; @@ -975,7 +975,7 @@ case 5: } -#line 978 "parser.c" +#line 979 "parser.c" enum {JSON_float_start = 1}; enum {JSON_float_first_final = 8}; enum {JSON_float_error = 0}; @@ -983,19 +983,20 @@ enum {JSON_float_error = 0}; enum {JSON_float_en_main = 1}; -#line 340 "parser.rl" +#line 341 "parser.rl" static int is_bigdecimal_class(VALUE obj) { - if (cBigDecimal == Qundef) { - if (rb_const_defined(rb_cObject, i_BigDecimal)) { - cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); - } else { - return 0; - } + if (cBigDecimal == Qundef) { + if (rb_const_defined(rb_cObject, i_BigDecimal)) { + cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); } - return obj == cBigDecimal; + else { + return 0; + } + } + return obj == cBigDecimal; } static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -1003,15 +1004,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 994 "parser.c" +#line 1008 "parser.c" { cs = JSON_float_start; } -#line 347 "parser.rl" +#line 361 "parser.rl" json->memo = p; -#line 1002 "parser.c" +#line 1016 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1069,14 +1070,14 @@ case 8: goto st0; goto tr9; tr9: -#line 334 "parser.rl" +#line 335 "parser.rl" { p--; {p++; cs = 9; goto _out;} } goto st9; st9: if ( ++p == pe ) goto _test_eof9; case 9: -#line 1067 "parser.c" +#line 1081 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -1137,7 +1138,7 @@ case 7: _out: {} } -#line 349 "parser.rl" +#line 363 "parser.rl" if (cs >= JSON_float_first_final) { long len = p - json->memo; @@ -1163,7 +1164,7 @@ case 7: -#line 1150 "parser.c" +#line 1168 "parser.c" enum {JSON_array_start = 1}; enum {JSON_array_first_final = 17}; enum {JSON_array_error = 0}; @@ -1171,7 +1172,7 @@ enum {JSON_array_error = 0}; enum {JSON_array_en_main = 1}; -#line 398 "parser.rl" +#line 416 "parser.rl" static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -1185,14 +1186,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); -#line 1172 "parser.c" +#line 1190 "parser.c" { cs = JSON_array_start; } -#line 411 "parser.rl" +#line 429 "parser.rl" -#line 1179 "parser.c" +#line 1197 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1231,7 +1232,7 @@ case 2: goto st2; goto st0; tr2: -#line 375 "parser.rl" +#line 393 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); @@ -1251,7 +1252,7 @@ case 2: if ( ++p == pe ) goto _test_eof3; case 3: -#line 1238 "parser.c" +#line 1256 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -1351,14 +1352,14 @@ case 12: goto st3; goto st12; tr4: -#line 390 "parser.rl" +#line 408 "parser.rl" { p--; {p++; cs = 17; goto _out;} } goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: -#line 1345 "parser.c" +#line 1363 "parser.c" goto st0; st13: if ( ++p == pe ) @@ -1414,7 +1415,7 @@ case 16: _out: {} } -#line 412 "parser.rl" +#line 430 "parser.rl" if(cs >= JSON_array_first_final) { return p + 1; @@ -1503,7 +1504,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1490 "parser.c" +#line 1508 "parser.c" enum {JSON_string_start = 1}; enum {JSON_string_first_final = 8}; enum {JSON_string_error = 0}; @@ -1511,7 +1512,7 @@ enum {JSON_string_error = 0}; enum {JSON_string_en_main = 1}; -#line 519 "parser.rl" +#line 537 "parser.rl" static int @@ -1533,15 +1534,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = rb_str_buf_new(0); -#line 1520 "parser.c" +#line 1538 "parser.c" { cs = JSON_string_start; } -#line 540 "parser.rl" +#line 558 "parser.rl" json->memo = p; -#line 1528 "parser.c" +#line 1546 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1566,7 +1567,7 @@ case 2: goto st0; goto st2; tr2: -#line 505 "parser.rl" +#line 523 "parser.rl" { *result = json_string_unescape(*result, json->memo + 1, p); if (NIL_P(*result)) { @@ -1577,14 +1578,14 @@ case 2: {p = (( p + 1))-1;} } } -#line 516 "parser.rl" +#line 534 "parser.rl" { p--; {p++; cs = 8; goto _out;} } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: -#line 1571 "parser.c" +#line 1589 "parser.c" goto st0; st3: if ( ++p == pe ) @@ -1660,7 +1661,7 @@ case 7: _out: {} } -#line 542 "parser.rl" +#line 560 "parser.rl" if (json->create_additions && RTEST(match_string = json->match_string)) { VALUE klass; @@ -1849,7 +1850,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1836 "parser.c" +#line 1854 "parser.c" enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1857,7 +1858,7 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; -#line 744 "parser.rl" +#line 762 "parser.rl" /* @@ -1874,16 +1875,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -#line 1861 "parser.c" +#line 1879 "parser.c" { cs = JSON_start; } -#line 760 "parser.rl" +#line 778 "parser.rl" p = json->source; pe = p + json->len; -#line 1870 "parser.c" +#line 1888 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1917,7 +1918,7 @@ case 1: cs = 0; goto _out; tr2: -#line 736 "parser.rl" +#line 754 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1927,7 +1928,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1914 "parser.c" +#line 1932 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2016,7 +2017,7 @@ case 9: _out: {} } -#line 763 "parser.rl" +#line 781 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -2083,6 +2084,7 @@ static VALUE cParser_source(VALUE self) void Init_parser(void) { +#undef rb_intern rb_require("json/common"); mJSON = rb_define_module("JSON"); mExt = rb_define_module_under(mJSON, "Ext"); @@ -2117,6 +2119,7 @@ void Init_parser(void) i_aref = rb_intern("[]"); i_leftshift = rb_intern("<<"); i_new = rb_intern("new"); + i_BigDecimal = rb_intern("BigDecimal"); } /* diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index c888d9c83..d4e7a60e9 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -342,14 +342,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res static int is_bigdecimal_class(VALUE obj) { - if (cBigDecimal == Qundef) { - if (rb_const_defined(rb_cObject, i_BigDecimal)) { - cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); - } else { - return 0; - } - } - return obj == cBigDecimal; + if (cBigDecimal == Qundef) { + if (rb_const_defined(rb_cObject, i_BigDecimal)) { + cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal); + } + else { + return 0; + } + } + return obj == cBigDecimal; } static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -878,6 +879,7 @@ void Init_parser(void) i_aref = rb_intern("[]"); i_leftshift = rb_intern("<<"); i_new = rb_intern("new"); + i_BigDecimal = rb_intern("BigDecimal"); } /* diff --git a/json.gemspec b/json.gemspec index e2e4f4a8909078b8f65b71e5726d37ae66c52e14..32a04ae911dbc0ca40a06a64b8a7ef04399d6fae 100644 GIT binary patch delta 47 zcmaE)^WES9SWEatifW}7!KhH`9H=DN= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] - s.date = "2017-06-21" + s.date = "2019-02-21" s.description = "This is a JSON implementation in pure Ruby.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze] - s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] + s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/set.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] s.homepage = "http://flori.github.com/json".freeze s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] s.required_ruby_version = Gem::Requirement.new(">= 1.9".freeze) - s.rubygems_version = "2.6.11".freeze + s.rubygems_version = "3.0.1".freeze s.summary = "JSON Implementation for Ruby".freeze s.test_files = ["./tests/test_helper.rb".freeze] From a0f3d125a4339b166bbe2432894517803732aca5 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 21 Feb 2019 22:28:30 +0100 Subject: [PATCH 228/312] Bump version to 2.2.0 --- CHANGES.md | 3 +++ VERSION | 2 +- json.gemspec | Bin 5503 -> 5503 bytes json_pure.gemspec | 6 +++--- lib/json/version.rb | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d96e9ae9d..92a192529 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,8 @@ # Changes +## 2019-02-21 (2.2.0) + * Adds support for 2.6 BigDecimal and ruby standard library Set datetype. + ## 2017-04-18 (2.1.0) * Allow passing of `decimal_class` option to specify a class as which to parse JSON float numbers. diff --git a/VERSION b/VERSION index 7ec1d6db4..ccbccc3dc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1.0 +2.2.0 diff --git a/json.gemspec b/json.gemspec index 32a04ae911dbc0ca40a06a64b8a7ef04399d6fae..f3c45f25bf6ce7e36484f7d98a5f48a598935a03 100644 GIT binary patch delta 24 gcmeyb^= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.licenses = ["Ruby".freeze] s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] s.required_ruby_version = Gem::Requirement.new(">= 1.9".freeze) - s.rubygems_version = "3.0.1".freeze + s.rubygems_version = "3.0.2".freeze s.summary = "JSON Implementation for Ruby".freeze s.test_files = ["./tests/test_helper.rb".freeze] diff --git a/lib/json/version.rb b/lib/json/version.rb index b65ed87f9..115eb5bb9 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module JSON # JSON version - VERSION = '2.1.0' + VERSION = '2.2.0' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: From 0e97fd419328dd8add71c451222fa219a8f8fa1e Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 21 Feb 2019 22:37:13 +0100 Subject: [PATCH 229/312] Upgrade version to 1.6 --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index c6c195f9f..2e0866ee4 100644 --- a/Rakefile +++ b/Rakefile @@ -238,7 +238,7 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby' classpath = (Dir['java/lib/*.jar'] << 'java/src' << JRUBY_JAR) * ':' obj = src.sub(/\.java\Z/, '.class') file obj => src do - sh 'javac', '-classpath', classpath, '-source', '1.5', '-target', '1.5', src + sh 'javac', '-classpath', classpath, '-source', '1.6', '-target', '1.6', src end JAVA_CLASSES << obj end From aff3d4b1fd7c13dac94dc936089a2c332747f593 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 21 Feb 2019 22:37:40 +0100 Subject: [PATCH 230/312] Always use underscore for match string --- java/src/json/ext/Parser.java | 6 +++--- java/src/json/ext/Parser.rl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index 2ba9f8fc2..647afca89 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -55,7 +55,7 @@ public class Parser extends RubyObject { private RubyClass objectClass; private RubyClass arrayClass; private RubyClass decimalClass; - private RubyHash matchString; + private RubyHash match_string; private static final int DEFAULT_MAX_NESTING = 100; @@ -165,7 +165,7 @@ public IRubyObject initialize(ThreadContext context, IRubyObject[] args) { this.objectClass = opts.getClass("object_class", runtime.getHash()); this.arrayClass = opts.getClass("array_class", runtime.getArray()); this.decimalClass = opts.getClass("decimal_class", null); - this.matchString = opts.getHash("match_string"); + this.match_string = opts.getHash("match_string"); if(symbolizeNames && createAdditions) { throw runtime.newArgumentError( @@ -1437,7 +1437,7 @@ else if ( data[p] > _JSON_string_trans_keys[_mid+1] ) // line 608 "Parser.rl" if (parser.createAdditions) { - RubyHash matchString = parser.matchString; + RubyHash matchString = parser.match_string; if (matchString != null) { final IRubyObject[] memoArray = { result, null }; try { diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 4d170e1d8..c0c72adc1 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -607,7 +607,7 @@ public class Parser extends RubyObject { %% write exec; if (parser.createAdditions) { - RubyHash matchString = parser.matchString; + RubyHash matchString = parser.match_string; if (matchString != null) { final IRubyObject[] memoArray = { result, null }; try { From 81fbce0aa66738b3ea9758db2aee44b80bb8f9a5 Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 28 Nov 2018 14:13:24 +0100 Subject: [PATCH 231/312] [fix] 2.5 compat on JRuby 9.2 Fixnum/Bignum -> Integer slightly ugly but the only way to still compile under 1.7 once Ruby 1.9.3 gets dropped this should get ironed out ! resolves GH-336 --- java/src/json/ext/Generator.java | 43 ++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/java/src/json/ext/Generator.java b/java/src/json/ext/Generator.java index 96a5e7e4f..24bf04974 100644 --- a/java/src/json/ext/Generator.java +++ b/java/src/json/ext/Generator.java @@ -7,6 +7,7 @@ import org.jruby.Ruby; import org.jruby.RubyArray; +import org.jruby.RubyBasicObject; import org.jruby.RubyBignum; import org.jruby.RubyBoolean; import org.jruby.RubyClass; @@ -15,6 +16,7 @@ import org.jruby.RubyHash; import org.jruby.RubyNumeric; import org.jruby.RubyString; +import org.jruby.runtime.ClassIndex; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; @@ -57,6 +59,19 @@ private Generator() { return handler.generateNew(session, object); } + // NOTE: drop this once Ruby 1.9.3 support is gone! + private static final int FIXNUM = 1; + private static final int BIGNUM = 2; + private static final int ARRAY = 3; + private static final int STRING = 4; + private static final int NIL = 5; + private static final int TRUE = 6; + private static final int FALSE = 7; + private static final int HASH = 10; + private static final int FLOAT = 11; + // hard-coded due JRuby 1.7 compatibility + // https://github.com/jruby/jruby/blob/1.7.27/core/src/main/java/org/jruby/runtime/ClassIndex.java + /** * Returns the best serialization handler for the given object. */ @@ -65,16 +80,24 @@ private Generator() { @SuppressWarnings("unchecked") private static Handler getHandlerFor(Ruby runtime, T object) { - RubyClass metaClass = object.getMetaClass(); - if (metaClass == runtime.getString()) return (Handler)STRING_HANDLER; - if (metaClass == runtime.getFixnum()) return (Handler)FIXNUM_HANDLER; - if (metaClass == runtime.getHash()) return (Handler)HASH_HANDLER; - if (metaClass == runtime.getArray()) return (Handler)ARRAY_HANDLER; - if (object.isNil()) return (Handler)NIL_HANDLER; - if (object == runtime.getTrue()) return (Handler)TRUE_HANDLER; - if (object == runtime.getFalse()) return (Handler)FALSE_HANDLER; - if (metaClass == runtime.getFloat()) return (Handler)FLOAT_HANDLER; - if (metaClass == runtime.getBignum()) return (Handler)BIGNUM_HANDLER; + switch (((RubyBasicObject) object).getNativeTypeIndex()) { + // can not use getNativeClassIndex due 1.7 compatibility + case NIL : return (Handler) NIL_HANDLER; + case TRUE : return (Handler) TRUE_HANDLER; + case FALSE : return (Handler) FALSE_HANDLER; + case FLOAT : return (Handler) FLOAT_HANDLER; + case FIXNUM : return (Handler) FIXNUM_HANDLER; + case BIGNUM : return (Handler) BIGNUM_HANDLER; + case STRING : + if (((RubyBasicObject) object).getMetaClass() != runtime.getString()) break; + return (Handler) STRING_HANDLER; + case ARRAY : + if (((RubyBasicObject) object).getMetaClass() != runtime.getArray()) break; + return (Handler) ARRAY_HANDLER; + case HASH : + if (((RubyBasicObject) object).getMetaClass() != runtime.getHash()) break; + return (Handler) HASH_HANDLER; + } return GENERIC_HANDLER; } From 3631dad29db6f6e940dc781b2867485bdff37648 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 21 Feb 2019 22:50:11 +0100 Subject: [PATCH 232/312] Use which to resolve to actual path --- Rakefile | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Rakefile b/Rakefile index 2e0866ee4..ce390952d 100644 --- a/Rakefile +++ b/Rakefile @@ -23,8 +23,13 @@ class UndocumentedTestTask < Rake::TestTask def desc(*) end end -MAKE = ENV['MAKE'] || %w[gmake make].find { |c| system(c, '-v') } -BUNDLE = ENV['BUNDLE'] || %w[bundle].find { |c| system(c, '-v') } +which = lambda { |c| + w = `which #{c}` + break w.chomp unless w.empty? +} + +MAKE = ENV['MAKE'] || %w[gmake make].find(&which) +BUNDLE = ENV['BUNDLE'] || %w[bundle].find(&which) PKG_NAME = 'json' PKG_TITLE = 'JSON Implementation for Ruby' PKG_VERSION = File.read('VERSION').chomp @@ -47,8 +52,8 @@ JAVA_CLASSES = [] JRUBY_PARSER_JAR = File.expand_path("lib/json/ext/parser.jar") JRUBY_GENERATOR_JAR = File.expand_path("lib/json/ext/generator.jar") -RAGEL_CODEGEN = %w[rlcodegen rlgen-cd ragel].find { |c| system(c, '-v') } -RAGEL_DOTGEN = %w[rlgen-dot rlgen-cd ragel].find { |c| system(c, '-v') } +RAGEL_CODEGEN = %w[rlcodegen rlgen-cd ragel].find(&which) +RAGEL_DOTGEN = %w[rlgen-dot rlgen-cd ragel].find(&which) desc "Installing library (pure)" task :install_pure => :version do From f53a0e36dc165f769ea8c03549d293fa3cc2a377 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Thu, 21 Feb 2019 23:00:56 +0100 Subject: [PATCH 233/312] It's more trouble than it's worth. --- data/example.json | 1 - data/index.html | 38 - data/prototype.js | 4184 --------------------------------------------- json.gemspec | Bin 5503 -> 5421 bytes json_pure.gemspec | 2 +- 5 files changed, 1 insertion(+), 4224 deletions(-) delete mode 100644 data/example.json delete mode 100644 data/index.html delete mode 100644 data/prototype.js diff --git a/data/example.json b/data/example.json deleted file mode 100644 index 88b4e8265..000000000 --- a/data/example.json +++ /dev/null @@ -1 +0,0 @@ -{"a":2,"b":3.141,"TIME":"2007-03-14T11:52:40","c":"c","d":[1,"b",3.14],"COUNT":666,"e":{"foo":"bar"},"foo":"B\u00e4r","g":"\u677e\u672c\u884c\u5f18","h":1000.0,"bar":"\u00a9 \u2260 \u20ac!","i":0.001,"j":"\ud840\udc01"} diff --git a/data/index.html b/data/index.html deleted file mode 100644 index abe6fdbfa..000000000 --- a/data/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - Codestin Search App - - - - - -

Fetching object from server

-
- Wait...
- -
- - - diff --git a/data/prototype.js b/data/prototype.js deleted file mode 100644 index 5c7346294..000000000 --- a/data/prototype.js +++ /dev/null @@ -1,4184 +0,0 @@ -/* Prototype JavaScript framework, version 1.6.0 - * (c) 2005-2007 Sam Stephenson - * - * Prototype is freely distributable under the terms of an MIT-style license. - * For details, see the Prototype web site: http://www.prototypejs.org/ - * - *--------------------------------------------------------------------------*/ - -var Prototype = { - Version: '1.6.0', - - Browser: { - IE: !!(window.attachEvent && !window.opera), - Opera: !!window.opera, - WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, - Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1, - MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) - }, - - BrowserFeatures: { - XPath: !!document.evaluate, - ElementExtensions: !!window.HTMLElement, - SpecificElementExtensions: - document.createElement('div').__proto__ && - document.createElement('div').__proto__ !== - document.createElement('form').__proto__ - }, - - ScriptFragment: ']*>([\\S\\s]*?)<\/script>', - JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, - - emptyFunction: function() { }, - K: function(x) { return x } -}; - -if (Prototype.Browser.MobileSafari) - Prototype.BrowserFeatures.SpecificElementExtensions = false; - -if (Prototype.Browser.WebKit) - Prototype.BrowserFeatures.XPath = false; - -/* Based on Alex Arnell's inheritance implementation. */ -var Class = { - create: function() { - var parent = null, properties = $A(arguments); - if (Object.isFunction(properties[0])) - parent = properties.shift(); - - function klass() { - this.initialize.apply(this, arguments); - } - - Object.extend(klass, Class.Methods); - klass.superclass = parent; - klass.subclasses = []; - - if (parent) { - var subclass = function() { }; - subclass.prototype = parent.prototype; - klass.prototype = new subclass; - parent.subclasses.push(klass); - } - - for (var i = 0; i < properties.length; i++) - klass.addMethods(properties[i]); - - if (!klass.prototype.initialize) - klass.prototype.initialize = Prototype.emptyFunction; - - klass.prototype.constructor = klass; - - return klass; - } -}; - -Class.Methods = { - addMethods: function(source) { - var ancestor = this.superclass && this.superclass.prototype; - var properties = Object.keys(source); - - if (!Object.keys({ toString: true }).length) - properties.push("toString", "valueOf"); - - for (var i = 0, length = properties.length; i < length; i++) { - var property = properties[i], value = source[property]; - if (ancestor && Object.isFunction(value) && - value.argumentNames().first() == "$super") { - var method = value, value = Object.extend((function(m) { - return function() { return ancestor[m].apply(this, arguments) }; - })(property).wrap(method), { - valueOf: function() { return method }, - toString: function() { return method.toString() } - }); - } - this.prototype[property] = value; - } - - return this; - } -}; - -var Abstract = { }; - -Object.extend = function(destination, source) { - for (var property in source) - destination[property] = source[property]; - return destination; -}; - -Object.extend(Object, { - inspect: function(object) { - try { - if (object === undefined) return 'undefined'; - if (object === null) return 'null'; - return object.inspect ? object.inspect() : object.toString(); - } catch (e) { - if (e instanceof RangeError) return '...'; - throw e; - } - }, - - toJSON: function(object) { - var type = typeof object; - switch (type) { - case 'undefined': - case 'function': - case 'unknown': return; - case 'boolean': return object.toString(); - } - - if (object === null) return 'null'; - if (object.toJSON) return object.toJSON(); - if (Object.isElement(object)) return; - - var results = []; - for (var property in object) { - var value = Object.toJSON(object[property]); - if (value !== undefined) - results.push(property.toJSON() + ': ' + value); - } - - return '{' + results.join(', ') + '}'; - }, - - toQueryString: function(object) { - return $H(object).toQueryString(); - }, - - toHTML: function(object) { - return object && object.toHTML ? object.toHTML() : String.interpret(object); - }, - - keys: function(object) { - var keys = []; - for (var property in object) - keys.push(property); - return keys; - }, - - values: function(object) { - var values = []; - for (var property in object) - values.push(object[property]); - return values; - }, - - clone: function(object) { - return Object.extend({ }, object); - }, - - isElement: function(object) { - return object && object.nodeType == 1; - }, - - isArray: function(object) { - return object && object.constructor === Array; - }, - - isHash: function(object) { - return object instanceof Hash; - }, - - isFunction: function(object) { - return typeof object == "function"; - }, - - isString: function(object) { - return typeof object == "string"; - }, - - isNumber: function(object) { - return typeof object == "number"; - }, - - isUndefined: function(object) { - return typeof object == "undefined"; - } -}); - -Object.extend(Function.prototype, { - argumentNames: function() { - var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip"); - return names.length == 1 && !names[0] ? [] : names; - }, - - bind: function() { - if (arguments.length < 2 && arguments[0] === undefined) return this; - var __method = this, args = $A(arguments), object = args.shift(); - return function() { - return __method.apply(object, args.concat($A(arguments))); - } - }, - - bindAsEventListener: function() { - var __method = this, args = $A(arguments), object = args.shift(); - return function(event) { - return __method.apply(object, [event || window.event].concat(args)); - } - }, - - curry: function() { - if (!arguments.length) return this; - var __method = this, args = $A(arguments); - return function() { - return __method.apply(this, args.concat($A(arguments))); - } - }, - - delay: function() { - var __method = this, args = $A(arguments), timeout = args.shift() * 1000; - return window.setTimeout(function() { - return __method.apply(__method, args); - }, timeout); - }, - - wrap: function(wrapper) { - var __method = this; - return function() { - return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); - } - }, - - methodize: function() { - if (this._methodized) return this._methodized; - var __method = this; - return this._methodized = function() { - return __method.apply(null, [this].concat($A(arguments))); - }; - } -}); - -Function.prototype.defer = Function.prototype.delay.curry(0.01); - -Date.prototype.toJSON = function() { - return '"' + this.getUTCFullYear() + '-' + - (this.getUTCMonth() + 1).toPaddedString(2) + '-' + - this.getUTCDate().toPaddedString(2) + 'T' + - this.getUTCHours().toPaddedString(2) + ':' + - this.getUTCMinutes().toPaddedString(2) + ':' + - this.getUTCSeconds().toPaddedString(2) + 'Z"'; -}; - -var Try = { - these: function() { - var returnValue; - - for (var i = 0, length = arguments.length; i < length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) { } - } - - return returnValue; - } -}; - -RegExp.prototype.match = RegExp.prototype.test; - -RegExp.escape = function(str) { - return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); -}; - -/*--------------------------------------------------------------------------*/ - -var PeriodicalExecuter = Class.create({ - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - execute: function() { - this.callback(this); - }, - - stop: function() { - if (!this.timer) return; - clearInterval(this.timer); - this.timer = null; - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.execute(); - } finally { - this.currentlyExecuting = false; - } - } - } -}); -Object.extend(String, { - interpret: function(value) { - return value == null ? '' : String(value); - }, - specialChar: { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '\\': '\\\\' - } -}); - -Object.extend(String.prototype, { - gsub: function(pattern, replacement) { - var result = '', source = this, match; - replacement = arguments.callee.prepareReplacement(replacement); - - while (source.length > 0) { - if (match = source.match(pattern)) { - result += source.slice(0, match.index); - result += String.interpret(replacement(match)); - source = source.slice(match.index + match[0].length); - } else { - result += source, source = ''; - } - } - return result; - }, - - sub: function(pattern, replacement, count) { - replacement = this.gsub.prepareReplacement(replacement); - count = count === undefined ? 1 : count; - - return this.gsub(pattern, function(match) { - if (--count < 0) return match[0]; - return replacement(match); - }); - }, - - scan: function(pattern, iterator) { - this.gsub(pattern, iterator); - return String(this); - }, - - truncate: function(length, truncation) { - length = length || 30; - truncation = truncation === undefined ? '...' : truncation; - return this.length > length ? - this.slice(0, length - truncation.length) + truncation : String(this); - }, - - strip: function() { - return this.replace(/^\s+/, '').replace(/\s+$/, ''); - }, - - stripTags: function() { - return this.replace(/<\/?[^>]+>/gi, ''); - }, - - stripScripts: function() { - return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); - }, - - extractScripts: function() { - var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); - var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); - return (this.match(matchAll) || []).map(function(scriptTag) { - return (scriptTag.match(matchOne) || ['', ''])[1]; - }); - }, - - evalScripts: function() { - return this.extractScripts().map(function(script) { return eval(script) }); - }, - - escapeHTML: function() { - var self = arguments.callee; - self.text.data = this; - return self.div.innerHTML; - }, - - unescapeHTML: function() { - var div = new Element('div'); - div.innerHTML = this.stripTags(); - return div.childNodes[0] ? (div.childNodes.length > 1 ? - $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : - div.childNodes[0].nodeValue) : ''; - }, - - toQueryParams: function(separator) { - var match = this.strip().match(/([^?#]*)(#.*)?$/); - if (!match) return { }; - - return match[1].split(separator || '&').inject({ }, function(hash, pair) { - if ((pair = pair.split('='))[0]) { - var key = decodeURIComponent(pair.shift()); - var value = pair.length > 1 ? pair.join('=') : pair[0]; - if (value != undefined) value = decodeURIComponent(value); - - if (key in hash) { - if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; - hash[key].push(value); - } - else hash[key] = value; - } - return hash; - }); - }, - - toArray: function() { - return this.split(''); - }, - - succ: function() { - return this.slice(0, this.length - 1) + - String.fromCharCode(this.charCodeAt(this.length - 1) + 1); - }, - - times: function(count) { - return count < 1 ? '' : new Array(count + 1).join(this); - }, - - camelize: function() { - var parts = this.split('-'), len = parts.length; - if (len == 1) return parts[0]; - - var camelized = this.charAt(0) == '-' - ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) - : parts[0]; - - for (var i = 1; i < len; i++) - camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); - - return camelized; - }, - - capitalize: function() { - return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); - }, - - underscore: function() { - return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); - }, - - dasherize: function() { - return this.gsub(/_/,'-'); - }, - - inspect: function(useDoubleQuotes) { - var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { - var character = String.specialChar[match[0]]; - return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); - }); - if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; - return "'" + escapedString.replace(/'/g, '\\\'') + "'"; - }, - - toJSON: function() { - return this.inspect(true); - }, - - unfilterJSON: function(filter) { - return this.sub(filter || Prototype.JSONFilter, '#{1}'); - }, - - isJSON: function() { - var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); - return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); - }, - - evalJSON: function(sanitize) { - var json = this.unfilterJSON(); - try { - if (!sanitize || json.isJSON()) return eval('(' + json + ')'); - } catch (e) { } - throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); - }, - - include: function(pattern) { - return this.indexOf(pattern) > -1; - }, - - startsWith: function(pattern) { - return this.indexOf(pattern) === 0; - }, - - endsWith: function(pattern) { - var d = this.length - pattern.length; - return d >= 0 && this.lastIndexOf(pattern) === d; - }, - - empty: function() { - return this == ''; - }, - - blank: function() { - return /^\s*$/.test(this); - }, - - interpolate: function(object, pattern) { - return new Template(this, pattern).evaluate(object); - } -}); - -if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { - escapeHTML: function() { - return this.replace(/&/g,'&').replace(//g,'>'); - }, - unescapeHTML: function() { - return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); - } -}); - -String.prototype.gsub.prepareReplacement = function(replacement) { - if (Object.isFunction(replacement)) return replacement; - var template = new Template(replacement); - return function(match) { return template.evaluate(match) }; -}; - -String.prototype.parseQuery = String.prototype.toQueryParams; - -Object.extend(String.prototype.escapeHTML, { - div: document.createElement('div'), - text: document.createTextNode('') -}); - -with (String.prototype.escapeHTML) div.appendChild(text); - -var Template = Class.create({ - initialize: function(template, pattern) { - this.template = template.toString(); - this.pattern = pattern || Template.Pattern; - }, - - evaluate: function(object) { - if (Object.isFunction(object.toTemplateReplacements)) - object = object.toTemplateReplacements(); - - return this.template.gsub(this.pattern, function(match) { - if (object == null) return ''; - - var before = match[1] || ''; - if (before == '\\') return match[2]; - - var ctx = object, expr = match[3]; - var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr); - if (match == null) return before; - - while (match != null) { - var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; - ctx = ctx[comp]; - if (null == ctx || '' == match[3]) break; - expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); - match = pattern.exec(expr); - } - - return before + String.interpret(ctx); - }.bind(this)); - } -}); -Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; - -var $break = { }; - -var Enumerable = { - each: function(iterator, context) { - var index = 0; - iterator = iterator.bind(context); - try { - this._each(function(value) { - iterator(value, index++); - }); - } catch (e) { - if (e != $break) throw e; - } - return this; - }, - - eachSlice: function(number, iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var index = -number, slices = [], array = this.toArray(); - while ((index += number) < array.length) - slices.push(array.slice(index, index+number)); - return slices.collect(iterator, context); - }, - - all: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result = true; - this.each(function(value, index) { - result = result && !!iterator(value, index); - if (!result) throw $break; - }); - return result; - }, - - any: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result = false; - this.each(function(value, index) { - if (result = !!iterator(value, index)) - throw $break; - }); - return result; - }, - - collect: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var results = []; - this.each(function(value, index) { - results.push(iterator(value, index)); - }); - return results; - }, - - detect: function(iterator, context) { - iterator = iterator.bind(context); - var result; - this.each(function(value, index) { - if (iterator(value, index)) { - result = value; - throw $break; - } - }); - return result; - }, - - findAll: function(iterator, context) { - iterator = iterator.bind(context); - var results = []; - this.each(function(value, index) { - if (iterator(value, index)) - results.push(value); - }); - return results; - }, - - grep: function(filter, iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var results = []; - - if (Object.isString(filter)) - filter = new RegExp(filter); - - this.each(function(value, index) { - if (filter.match(value)) - results.push(iterator(value, index)); - }); - return results; - }, - - include: function(object) { - if (Object.isFunction(this.indexOf)) - if (this.indexOf(object) != -1) return true; - - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - }, - - inGroupsOf: function(number, fillWith) { - fillWith = fillWith === undefined ? null : fillWith; - return this.eachSlice(number, function(slice) { - while(slice.length < number) slice.push(fillWith); - return slice; - }); - }, - - inject: function(memo, iterator, context) { - iterator = iterator.bind(context); - this.each(function(value, index) { - memo = iterator(memo, value, index); - }); - return memo; - }, - - invoke: function(method) { - var args = $A(arguments).slice(1); - return this.map(function(value) { - return value[method].apply(value, args); - }); - }, - - max: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result; - this.each(function(value, index) { - value = iterator(value, index); - if (result == undefined || value >= result) - result = value; - }); - return result; - }, - - min: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result; - this.each(function(value, index) { - value = iterator(value, index); - if (result == undefined || value < result) - result = value; - }); - return result; - }, - - partition: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var trues = [], falses = []; - this.each(function(value, index) { - (iterator(value, index) ? - trues : falses).push(value); - }); - return [trues, falses]; - }, - - pluck: function(property) { - var results = []; - this.each(function(value) { - results.push(value[property]); - }); - return results; - }, - - reject: function(iterator, context) { - iterator = iterator.bind(context); - var results = []; - this.each(function(value, index) { - if (!iterator(value, index)) - results.push(value); - }); - return results; - }, - - sortBy: function(iterator, context) { - iterator = iterator.bind(context); - return this.map(function(value, index) { - return {value: value, criteria: iterator(value, index)}; - }).sort(function(left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }).pluck('value'); - }, - - toArray: function() { - return this.map(); - }, - - zip: function() { - var iterator = Prototype.K, args = $A(arguments); - if (Object.isFunction(args.last())) - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - return iterator(collections.pluck(index)); - }); - }, - - size: function() { - return this.toArray().length; - }, - - inspect: function() { - return '#'; - } -}; - -Object.extend(Enumerable, { - map: Enumerable.collect, - find: Enumerable.detect, - select: Enumerable.findAll, - filter: Enumerable.findAll, - member: Enumerable.include, - entries: Enumerable.toArray, - every: Enumerable.all, - some: Enumerable.any -}); -function $A(iterable) { - if (!iterable) return []; - if (iterable.toArray) return iterable.toArray(); - var length = iterable.length, results = new Array(length); - while (length--) results[length] = iterable[length]; - return results; -} - -if (Prototype.Browser.WebKit) { - function $A(iterable) { - if (!iterable) return []; - if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') && - iterable.toArray) return iterable.toArray(); - var length = iterable.length, results = new Array(length); - while (length--) results[length] = iterable[length]; - return results; - } -} - -Array.from = $A; - -Object.extend(Array.prototype, Enumerable); - -if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; - -Object.extend(Array.prototype, { - _each: function(iterator) { - for (var i = 0, length = this.length; i < length; i++) - iterator(this[i]); - }, - - clear: function() { - this.length = 0; - return this; - }, - - first: function() { - return this[0]; - }, - - last: function() { - return this[this.length - 1]; - }, - - compact: function() { - return this.select(function(value) { - return value != null; - }); - }, - - flatten: function() { - return this.inject([], function(array, value) { - return array.concat(Object.isArray(value) ? - value.flatten() : [value]); - }); - }, - - without: function() { - var values = $A(arguments); - return this.select(function(value) { - return !values.include(value); - }); - }, - - reverse: function(inline) { - return (inline !== false ? this : this.toArray())._reverse(); - }, - - reduce: function() { - return this.length > 1 ? this : this[0]; - }, - - uniq: function(sorted) { - return this.inject([], function(array, value, index) { - if (0 == index || (sorted ? array.last() != value : !array.include(value))) - array.push(value); - return array; - }); - }, - - intersect: function(array) { - return this.uniq().findAll(function(item) { - return array.detect(function(value) { return item === value }); - }); - }, - - clone: function() { - return [].concat(this); - }, - - size: function() { - return this.length; - }, - - inspect: function() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - }, - - toJSON: function() { - var results = []; - this.each(function(object) { - var value = Object.toJSON(object); - if (value !== undefined) results.push(value); - }); - return '[' + results.join(', ') + ']'; - } -}); - -// use native browser JS 1.6 implementation if available -if (Object.isFunction(Array.prototype.forEach)) - Array.prototype._each = Array.prototype.forEach; - -if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) { - i || (i = 0); - var length = this.length; - if (i < 0) i = length + i; - for (; i < length; i++) - if (this[i] === item) return i; - return -1; -}; - -if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) { - i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; - var n = this.slice(0, i).reverse().indexOf(item); - return (n < 0) ? n : i - n - 1; -}; - -Array.prototype.toArray = Array.prototype.clone; - -function $w(string) { - if (!Object.isString(string)) return []; - string = string.strip(); - return string ? string.split(/\s+/) : []; -} - -if (Prototype.Browser.Opera){ - Array.prototype.concat = function() { - var array = []; - for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); - for (var i = 0, length = arguments.length; i < length; i++) { - if (Object.isArray(arguments[i])) { - for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) - array.push(arguments[i][j]); - } else { - array.push(arguments[i]); - } - } - return array; - }; -} -Object.extend(Number.prototype, { - toColorPart: function() { - return this.toPaddedString(2, 16); - }, - - succ: function() { - return this + 1; - }, - - times: function(iterator) { - $R(0, this, true).each(iterator); - return this; - }, - - toPaddedString: function(length, radix) { - var string = this.toString(radix || 10); - return '0'.times(length - string.length) + string; - }, - - toJSON: function() { - return isFinite(this) ? this.toString() : 'null'; - } -}); - -$w('abs round ceil floor').each(function(method){ - Number.prototype[method] = Math[method].methodize(); -}); -function $H(object) { - return new Hash(object); -}; - -var Hash = Class.create(Enumerable, (function() { - if (function() { - var i = 0, Test = function(value) { this.key = value }; - Test.prototype.key = 'foo'; - for (var property in new Test('bar')) i++; - return i > 1; - }()) { - function each(iterator) { - var cache = []; - for (var key in this._object) { - var value = this._object[key]; - if (cache.include(key)) continue; - cache.push(key); - var pair = [key, value]; - pair.key = key; - pair.value = value; - iterator(pair); - } - } - } else { - function each(iterator) { - for (var key in this._object) { - var value = this._object[key], pair = [key, value]; - pair.key = key; - pair.value = value; - iterator(pair); - } - } - } - - function toQueryPair(key, value) { - if (Object.isUndefined(value)) return key; - return key + '=' + encodeURIComponent(String.interpret(value)); - } - - return { - initialize: function(object) { - this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); - }, - - _each: each, - - set: function(key, value) { - return this._object[key] = value; - }, - - get: function(key) { - return this._object[key]; - }, - - unset: function(key) { - var value = this._object[key]; - delete this._object[key]; - return value; - }, - - toObject: function() { - return Object.clone(this._object); - }, - - keys: function() { - return this.pluck('key'); - }, - - values: function() { - return this.pluck('value'); - }, - - index: function(value) { - var match = this.detect(function(pair) { - return pair.value === value; - }); - return match && match.key; - }, - - merge: function(object) { - return this.clone().update(object); - }, - - update: function(object) { - return new Hash(object).inject(this, function(result, pair) { - result.set(pair.key, pair.value); - return result; - }); - }, - - toQueryString: function() { - return this.map(function(pair) { - var key = encodeURIComponent(pair.key), values = pair.value; - - if (values && typeof values == 'object') { - if (Object.isArray(values)) - return values.map(toQueryPair.curry(key)).join('&'); - } - return toQueryPair(key, values); - }).join('&'); - }, - - inspect: function() { - return '#'; - }, - - toJSON: function() { - return Object.toJSON(this.toObject()); - }, - - clone: function() { - return new Hash(this); - } - } -})()); - -Hash.prototype.toTemplateReplacements = Hash.prototype.toObject; -Hash.from = $H; -var ObjectRange = Class.create(Enumerable, { - initialize: function(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - }, - - _each: function(iterator) { - var value = this.start; - while (this.include(value)) { - iterator(value); - value = value.succ(); - } - }, - - include: function(value) { - if (value < this.start) - return false; - if (this.exclusive) - return value < this.end; - return value <= this.end; - } -}); - -var $R = function(start, end, exclusive) { - return new ObjectRange(start, end, exclusive); -}; - -var Ajax = { - getTransport: function() { - return Try.these( - function() {return new XMLHttpRequest()}, - function() {return new ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')} - ) || false; - }, - - activeRequestCount: 0 -}; - -Ajax.Responders = { - responders: [], - - _each: function(iterator) { - this.responders._each(iterator); - }, - - register: function(responder) { - if (!this.include(responder)) - this.responders.push(responder); - }, - - unregister: function(responder) { - this.responders = this.responders.without(responder); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (Object.isFunction(responder[callback])) { - try { - responder[callback].apply(responder, [request, transport, json]); - } catch (e) { } - } - }); - } -}; - -Object.extend(Ajax.Responders, Enumerable); - -Ajax.Responders.register({ - onCreate: function() { Ajax.activeRequestCount++ }, - onComplete: function() { Ajax.activeRequestCount-- } -}); - -Ajax.Base = Class.create({ - initialize: function(options) { - this.options = { - method: 'post', - asynchronous: true, - contentType: 'application/x-www-form-urlencoded', - encoding: 'UTF-8', - parameters: '', - evalJSON: true, - evalJS: true - }; - Object.extend(this.options, options || { }); - - this.options.method = this.options.method.toLowerCase(); - if (Object.isString(this.options.parameters)) - this.options.parameters = this.options.parameters.toQueryParams(); - } -}); - -Ajax.Request = Class.create(Ajax.Base, { - _complete: false, - - initialize: function($super, url, options) { - $super(options); - this.transport = Ajax.getTransport(); - this.request(url); - }, - - request: function(url) { - this.url = url; - this.method = this.options.method; - var params = Object.clone(this.options.parameters); - - if (!['get', 'post'].include(this.method)) { - // simulate other verbs over post - params['_method'] = this.method; - this.method = 'post'; - } - - this.parameters = params; - - if (params = Object.toQueryString(params)) { - // when GET, append parameters to URL - if (this.method == 'get') - this.url += (this.url.include('?') ? '&' : '?') + params; - else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) - params += '&_='; - } - - try { - var response = new Ajax.Response(this); - if (this.options.onCreate) this.options.onCreate(response); - Ajax.Responders.dispatch('onCreate', this, response); - - this.transport.open(this.method.toUpperCase(), this.url, - this.options.asynchronous); - - if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); - - this.transport.onreadystatechange = this.onStateChange.bind(this); - this.setRequestHeaders(); - - this.body = this.method == 'post' ? (this.options.postBody || params) : null; - this.transport.send(this.body); - - /* Force Firefox to handle ready state 4 for synchronous requests */ - if (!this.options.asynchronous && this.transport.overrideMimeType) - this.onStateChange(); - - } - catch (e) { - this.dispatchException(e); - } - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState > 1 && !((readyState == 4) && this._complete)) - this.respondToReadyState(this.transport.readyState); - }, - - setRequestHeaders: function() { - var headers = { - 'X-Requested-With': 'XMLHttpRequest', - 'X-Prototype-Version': Prototype.Version, - 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' - }; - - if (this.method == 'post') { - headers['Content-type'] = this.options.contentType + - (this.options.encoding ? '; charset=' + this.options.encoding : ''); - - /* Force "Connection: close" for older Mozilla browsers to work - * around a bug where XMLHttpRequest sends an incorrect - * Content-length header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType && - (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) - headers['Connection'] = 'close'; - } - - // user-defined headers - if (typeof this.options.requestHeaders == 'object') { - var extras = this.options.requestHeaders; - - if (Object.isFunction(extras.push)) - for (var i = 0, length = extras.length; i < length; i += 2) - headers[extras[i]] = extras[i+1]; - else - $H(extras).each(function(pair) { headers[pair.key] = pair.value }); - } - - for (var name in headers) - this.transport.setRequestHeader(name, headers[name]); - }, - - success: function() { - var status = this.getStatus(); - return !status || (status >= 200 && status < 300); - }, - - getStatus: function() { - try { - return this.transport.status || 0; - } catch (e) { return 0 } - }, - - respondToReadyState: function(readyState) { - var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); - - if (state == 'Complete') { - try { - this._complete = true; - (this.options['on' + response.status] - || this.options['on' + (this.success() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - var contentType = response.getHeader('Content-type'); - if (this.options.evalJS == 'force' - || (this.options.evalJS && contentType - && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) - this.evalResponse(); - } - - try { - (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); - Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - if (state == 'Complete') { - // avoid memory leak in MSIE: clean up - this.transport.onreadystatechange = Prototype.emptyFunction; - } - }, - - getHeader: function(name) { - try { - return this.transport.getResponseHeader(name); - } catch (e) { return null } - }, - - evalResponse: function() { - try { - return eval((this.transport.responseText || '').unfilterJSON()); - } catch (e) { - this.dispatchException(e); - } - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - -Ajax.Response = Class.create({ - initialize: function(request){ - this.request = request; - var transport = this.transport = request.transport, - readyState = this.readyState = transport.readyState; - - if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { - this.status = this.getStatus(); - this.statusText = this.getStatusText(); - this.responseText = String.interpret(transport.responseText); - this.headerJSON = this._getHeaderJSON(); - } - - if(readyState == 4) { - var xml = transport.responseXML; - this.responseXML = xml === undefined ? null : xml; - this.responseJSON = this._getResponseJSON(); - } - }, - - status: 0, - statusText: '', - - getStatus: Ajax.Request.prototype.getStatus, - - getStatusText: function() { - try { - return this.transport.statusText || ''; - } catch (e) { return '' } - }, - - getHeader: Ajax.Request.prototype.getHeader, - - getAllHeaders: function() { - try { - return this.getAllResponseHeaders(); - } catch (e) { return null } - }, - - getResponseHeader: function(name) { - return this.transport.getResponseHeader(name); - }, - - getAllResponseHeaders: function() { - return this.transport.getAllResponseHeaders(); - }, - - _getHeaderJSON: function() { - var json = this.getHeader('X-JSON'); - if (!json) return null; - json = decodeURIComponent(escape(json)); - try { - return json.evalJSON(this.request.options.sanitizeJSON); - } catch (e) { - this.request.dispatchException(e); - } - }, - - _getResponseJSON: function() { - var options = this.request.options; - if (!options.evalJSON || (options.evalJSON != 'force' && - !(this.getHeader('Content-type') || '').include('application/json'))) - return null; - try { - return this.transport.responseText.evalJSON(options.sanitizeJSON); - } catch (e) { - this.request.dispatchException(e); - } - } -}); - -Ajax.Updater = Class.create(Ajax.Request, { - initialize: function($super, container, url, options) { - this.container = { - success: (container.success || container), - failure: (container.failure || (container.success ? null : container)) - }; - - options = options || { }; - var onComplete = options.onComplete; - options.onComplete = (function(response, param) { - this.updateContent(response.responseText); - if (Object.isFunction(onComplete)) onComplete(response, param); - }).bind(this); - - $super(url, options); - }, - - updateContent: function(responseText) { - var receiver = this.container[this.success() ? 'success' : 'failure'], - options = this.options; - - if (!options.evalScripts) responseText = responseText.stripScripts(); - - if (receiver = $(receiver)) { - if (options.insertion) { - if (Object.isString(options.insertion)) { - var insertion = { }; insertion[options.insertion] = responseText; - receiver.insert(insertion); - } - else options.insertion(receiver, responseText); - } - else receiver.update(responseText); - } - - if (this.success()) { - if (this.onComplete) this.onComplete.bind(this).defer(); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { - initialize: function($super, container, url, options) { - $super(options); - this.onComplete = this.options.onComplete; - - this.frequency = (this.options.frequency || 2); - this.decay = (this.options.decay || 1); - - this.updater = { }; - this.container = container; - this.url = url; - - this.start(); - }, - - start: function() { - this.options.onComplete = this.updateComplete.bind(this); - this.onTimerEvent(); - }, - - stop: function() { - this.updater.options.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(response) { - if (this.options.decay) { - this.decay = (response.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = response.responseText; - } - this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); -function $(element) { - if (arguments.length > 1) { - for (var i = 0, elements = [], length = arguments.length; i < length; i++) - elements.push($(arguments[i])); - return elements; - } - if (Object.isString(element)) - element = document.getElementById(element); - return Element.extend(element); -} - -if (Prototype.BrowserFeatures.XPath) { - document._getElementsByXPath = function(expression, parentElement) { - var results = []; - var query = document.evaluate(expression, $(parentElement) || document, - null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - for (var i = 0, length = query.snapshotLength; i < length; i++) - results.push(Element.extend(query.snapshotItem(i))); - return results; - }; -} - -/*--------------------------------------------------------------------------*/ - -if (!window.Node) var Node = { }; - -if (!Node.ELEMENT_NODE) { - // DOM level 2 ECMAScript Language Binding - Object.extend(Node, { - ELEMENT_NODE: 1, - ATTRIBUTE_NODE: 2, - TEXT_NODE: 3, - CDATA_SECTION_NODE: 4, - ENTITY_REFERENCE_NODE: 5, - ENTITY_NODE: 6, - PROCESSING_INSTRUCTION_NODE: 7, - COMMENT_NODE: 8, - DOCUMENT_NODE: 9, - DOCUMENT_TYPE_NODE: 10, - DOCUMENT_FRAGMENT_NODE: 11, - NOTATION_NODE: 12 - }); -} - -(function() { - var element = this.Element; - this.Element = function(tagName, attributes) { - attributes = attributes || { }; - tagName = tagName.toLowerCase(); - var cache = Element.cache; - if (Prototype.Browser.IE && attributes.name) { - tagName = '<' + tagName + ' name="' + attributes.name + '">'; - delete attributes.name; - return Element.writeAttribute(document.createElement(tagName), attributes); - } - if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); - return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); - }; - Object.extend(this.Element, element || { }); -}).call(window); - -Element.cache = { }; - -Element.Methods = { - visible: function(element) { - return $(element).style.display != 'none'; - }, - - toggle: function(element) { - element = $(element); - Element[Element.visible(element) ? 'hide' : 'show'](element); - return element; - }, - - hide: function(element) { - $(element).style.display = 'none'; - return element; - }, - - show: function(element) { - $(element).style.display = ''; - return element; - }, - - remove: function(element) { - element = $(element); - element.parentNode.removeChild(element); - return element; - }, - - update: function(element, content) { - element = $(element); - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) return element.update().insert(content); - content = Object.toHTML(content); - element.innerHTML = content.stripScripts(); - content.evalScripts.bind(content).defer(); - return element; - }, - - replace: function(element, content) { - element = $(element); - if (content && content.toElement) content = content.toElement(); - else if (!Object.isElement(content)) { - content = Object.toHTML(content); - var range = element.ownerDocument.createRange(); - range.selectNode(element); - content.evalScripts.bind(content).defer(); - content = range.createContextualFragment(content.stripScripts()); - } - element.parentNode.replaceChild(content, element); - return element; - }, - - insert: function(element, insertions) { - element = $(element); - - if (Object.isString(insertions) || Object.isNumber(insertions) || - Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) - insertions = {bottom:insertions}; - - var content, t, range; - - for (position in insertions) { - content = insertions[position]; - position = position.toLowerCase(); - t = Element._insertionTranslations[position]; - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - t.insert(element, content); - continue; - } - - content = Object.toHTML(content); - - range = element.ownerDocument.createRange(); - t.initializeRange(element, range); - t.insert(element, range.createContextualFragment(content.stripScripts())); - - content.evalScripts.bind(content).defer(); - } - - return element; - }, - - wrap: function(element, wrapper, attributes) { - element = $(element); - if (Object.isElement(wrapper)) - $(wrapper).writeAttribute(attributes || { }); - else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); - else wrapper = new Element('div', wrapper); - if (element.parentNode) - element.parentNode.replaceChild(wrapper, element); - wrapper.appendChild(element); - return wrapper; - }, - - inspect: function(element) { - element = $(element); - var result = '<' + element.tagName.toLowerCase(); - $H({'id': 'id', 'className': 'class'}).each(function(pair) { - var property = pair.first(), attribute = pair.last(); - var value = (element[property] || '').toString(); - if (value) result += ' ' + attribute + '=' + value.inspect(true); - }); - return result + '>'; - }, - - recursivelyCollect: function(element, property) { - element = $(element); - var elements = []; - while (element = element[property]) - if (element.nodeType == 1) - elements.push(Element.extend(element)); - return elements; - }, - - ancestors: function(element) { - return $(element).recursivelyCollect('parentNode'); - }, - - descendants: function(element) { - return $A($(element).getElementsByTagName('*')).each(Element.extend); - }, - - firstDescendant: function(element) { - element = $(element).firstChild; - while (element && element.nodeType != 1) element = element.nextSibling; - return $(element); - }, - - immediateDescendants: function(element) { - if (!(element = $(element).firstChild)) return []; - while (element && element.nodeType != 1) element = element.nextSibling; - if (element) return [element].concat($(element).nextSiblings()); - return []; - }, - - previousSiblings: function(element) { - return $(element).recursivelyCollect('previousSibling'); - }, - - nextSiblings: function(element) { - return $(element).recursivelyCollect('nextSibling'); - }, - - siblings: function(element) { - element = $(element); - return element.previousSiblings().reverse().concat(element.nextSiblings()); - }, - - match: function(element, selector) { - if (Object.isString(selector)) - selector = new Selector(selector); - return selector.match($(element)); - }, - - up: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(element.parentNode); - var ancestors = element.ancestors(); - return expression ? Selector.findElement(ancestors, expression, index) : - ancestors[index || 0]; - }, - - down: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return element.firstDescendant(); - var descendants = element.descendants(); - return expression ? Selector.findElement(descendants, expression, index) : - descendants[index || 0]; - }, - - previous: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); - var previousSiblings = element.previousSiblings(); - return expression ? Selector.findElement(previousSiblings, expression, index) : - previousSiblings[index || 0]; - }, - - next: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); - var nextSiblings = element.nextSiblings(); - return expression ? Selector.findElement(nextSiblings, expression, index) : - nextSiblings[index || 0]; - }, - - select: function() { - var args = $A(arguments), element = $(args.shift()); - return Selector.findChildElements(element, args); - }, - - adjacent: function() { - var args = $A(arguments), element = $(args.shift()); - return Selector.findChildElements(element.parentNode, args).without(element); - }, - - identify: function(element) { - element = $(element); - var id = element.readAttribute('id'), self = arguments.callee; - if (id) return id; - do { id = 'anonymous_element_' + self.counter++ } while ($(id)); - element.writeAttribute('id', id); - return id; - }, - - readAttribute: function(element, name) { - element = $(element); - if (Prototype.Browser.IE) { - var t = Element._attributeTranslations.read; - if (t.values[name]) return t.values[name](element, name); - if (t.names[name]) name = t.names[name]; - if (name.include(':')) { - return (!element.attributes || !element.attributes[name]) ? null : - element.attributes[name].value; - } - } - return element.getAttribute(name); - }, - - writeAttribute: function(element, name, value) { - element = $(element); - var attributes = { }, t = Element._attributeTranslations.write; - - if (typeof name == 'object') attributes = name; - else attributes[name] = value === undefined ? true : value; - - for (var attr in attributes) { - var name = t.names[attr] || attr, value = attributes[attr]; - if (t.values[attr]) name = t.values[attr](element, value); - if (value === false || value === null) - element.removeAttribute(name); - else if (value === true) - element.setAttribute(name, name); - else element.setAttribute(name, value); - } - return element; - }, - - getHeight: function(element) { - return $(element).getDimensions().height; - }, - - getWidth: function(element) { - return $(element).getDimensions().width; - }, - - classNames: function(element) { - return new Element.ClassNames(element); - }, - - hasClassName: function(element, className) { - if (!(element = $(element))) return; - var elementClassName = element.className; - return (elementClassName.length > 0 && (elementClassName == className || - new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); - }, - - addClassName: function(element, className) { - if (!(element = $(element))) return; - if (!element.hasClassName(className)) - element.className += (element.className ? ' ' : '') + className; - return element; - }, - - removeClassName: function(element, className) { - if (!(element = $(element))) return; - element.className = element.className.replace( - new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); - return element; - }, - - toggleClassName: function(element, className) { - if (!(element = $(element))) return; - return element[element.hasClassName(className) ? - 'removeClassName' : 'addClassName'](className); - }, - - // removes whitespace-only text node children - cleanWhitespace: function(element) { - element = $(element); - var node = element.firstChild; - while (node) { - var nextNode = node.nextSibling; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - element.removeChild(node); - node = nextNode; - } - return element; - }, - - empty: function(element) { - return $(element).innerHTML.blank(); - }, - - descendantOf: function(element, ancestor) { - element = $(element), ancestor = $(ancestor); - - if (element.compareDocumentPosition) - return (element.compareDocumentPosition(ancestor) & 8) === 8; - - if (element.sourceIndex && !Prototype.Browser.Opera) { - var e = element.sourceIndex, a = ancestor.sourceIndex, - nextAncestor = ancestor.nextSibling; - if (!nextAncestor) { - do { ancestor = ancestor.parentNode; } - while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode); - } - if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex); - } - - while (element = element.parentNode) - if (element == ancestor) return true; - return false; - }, - - scrollTo: function(element) { - element = $(element); - var pos = element.cumulativeOffset(); - window.scrollTo(pos[0], pos[1]); - return element; - }, - - getStyle: function(element, style) { - element = $(element); - style = style == 'float' ? 'cssFloat' : style.camelize(); - var value = element.style[style]; - if (!value) { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css[style] : null; - } - if (style == 'opacity') return value ? parseFloat(value) : 1.0; - return value == 'auto' ? null : value; - }, - - getOpacity: function(element) { - return $(element).getStyle('opacity'); - }, - - setStyle: function(element, styles) { - element = $(element); - var elementStyle = element.style, match; - if (Object.isString(styles)) { - element.style.cssText += ';' + styles; - return styles.include('opacity') ? - element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; - } - for (var property in styles) - if (property == 'opacity') element.setOpacity(styles[property]); - else - elementStyle[(property == 'float' || property == 'cssFloat') ? - (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') : - property] = styles[property]; - - return element; - }, - - setOpacity: function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - return element; - }, - - getDimensions: function(element) { - element = $(element); - var display = $(element).getStyle('display'); - if (display != 'none' && display != null) // Safari bug - return {width: element.offsetWidth, height: element.offsetHeight}; - - // All *Width and *Height properties give 0 on elements with display none, - // so enable the element temporarily - var els = element.style; - var originalVisibility = els.visibility; - var originalPosition = els.position; - var originalDisplay = els.display; - els.visibility = 'hidden'; - els.position = 'absolute'; - els.display = 'block'; - var originalWidth = element.clientWidth; - var originalHeight = element.clientHeight; - els.display = originalDisplay; - els.position = originalPosition; - els.visibility = originalVisibility; - return {width: originalWidth, height: originalHeight}; - }, - - makePositioned: function(element) { - element = $(element); - var pos = Element.getStyle(element, 'position'); - if (pos == 'static' || !pos) { - element._madePositioned = true; - element.style.position = 'relative'; - // Opera returns the offset relative to the positioning context, when an - // element is position relative but top and left have not been defined - if (window.opera) { - element.style.top = 0; - element.style.left = 0; - } - } - return element; - }, - - undoPositioned: function(element) { - element = $(element); - if (element._madePositioned) { - element._madePositioned = undefined; - element.style.position = - element.style.top = - element.style.left = - element.style.bottom = - element.style.right = ''; - } - return element; - }, - - makeClipping: function(element) { - element = $(element); - if (element._overflow) return element; - element._overflow = Element.getStyle(element, 'overflow') || 'auto'; - if (element._overflow !== 'hidden') - element.style.overflow = 'hidden'; - return element; - }, - - undoClipping: function(element) { - element = $(element); - if (!element._overflow) return element; - element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; - element._overflow = null; - return element; - }, - - cumulativeOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - positionedOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - if (element.tagName == 'BODY') break; - var p = Element.getStyle(element, 'position'); - if (p == 'relative' || p == 'absolute') break; - } - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - absolutize: function(element) { - element = $(element); - if (element.getStyle('position') == 'absolute') return; - // Position.prepare(); // To be done manually by Scripty when it needs it. - - var offsets = element.positionedOffset(); - var top = offsets[1]; - var left = offsets[0]; - var width = element.clientWidth; - var height = element.clientHeight; - - element._originalLeft = left - parseFloat(element.style.left || 0); - element._originalTop = top - parseFloat(element.style.top || 0); - element._originalWidth = element.style.width; - element._originalHeight = element.style.height; - - element.style.position = 'absolute'; - element.style.top = top + 'px'; - element.style.left = left + 'px'; - element.style.width = width + 'px'; - element.style.height = height + 'px'; - return element; - }, - - relativize: function(element) { - element = $(element); - if (element.getStyle('position') == 'relative') return; - // Position.prepare(); // To be done manually by Scripty when it needs it. - - element.style.position = 'relative'; - var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); - var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); - - element.style.top = top + 'px'; - element.style.left = left + 'px'; - element.style.height = element._originalHeight; - element.style.width = element._originalWidth; - return element; - }, - - cumulativeScrollOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - getOffsetParent: function(element) { - if (element.offsetParent) return $(element.offsetParent); - if (element == document.body) return $(element); - - while ((element = element.parentNode) && element != document.body) - if (Element.getStyle(element, 'position') != 'static') - return $(element); - - return $(document.body); - }, - - viewportOffset: function(forElement) { - var valueT = 0, valueL = 0; - - var element = forElement; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - - // Safari fix - if (element.offsetParent == document.body && - Element.getStyle(element, 'position') == 'absolute') break; - - } while (element = element.offsetParent); - - element = forElement; - do { - if (!Prototype.Browser.Opera || element.tagName == 'BODY') { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } - } while (element = element.parentNode); - - return Element._returnOffset(valueL, valueT); - }, - - clonePosition: function(element, source) { - var options = Object.extend({ - setLeft: true, - setTop: true, - setWidth: true, - setHeight: true, - offsetTop: 0, - offsetLeft: 0 - }, arguments[2] || { }); - - // find page position of source - source = $(source); - var p = source.viewportOffset(); - - // find coordinate system to use - element = $(element); - var delta = [0, 0]; - var parent = null; - // delta [0,0] will do fine with position: fixed elements, - // position:absolute needs offsetParent deltas - if (Element.getStyle(element, 'position') == 'absolute') { - parent = element.getOffsetParent(); - delta = parent.viewportOffset(); - } - - // correct by body offsets (fixes Safari) - if (parent == document.body) { - delta[0] -= document.body.offsetLeft; - delta[1] -= document.body.offsetTop; - } - - // set position - if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; - if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; - if (options.setWidth) element.style.width = source.offsetWidth + 'px'; - if (options.setHeight) element.style.height = source.offsetHeight + 'px'; - return element; - } -}; - -Element.Methods.identify.counter = 1; - -Object.extend(Element.Methods, { - getElementsBySelector: Element.Methods.select, - childElements: Element.Methods.immediateDescendants -}); - -Element._attributeTranslations = { - write: { - names: { - className: 'class', - htmlFor: 'for' - }, - values: { } - } -}; - - -if (!document.createRange || Prototype.Browser.Opera) { - Element.Methods.insert = function(element, insertions) { - element = $(element); - - if (Object.isString(insertions) || Object.isNumber(insertions) || - Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) - insertions = { bottom: insertions }; - - var t = Element._insertionTranslations, content, position, pos, tagName; - - for (position in insertions) { - content = insertions[position]; - position = position.toLowerCase(); - pos = t[position]; - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - pos.insert(element, content); - continue; - } - - content = Object.toHTML(content); - tagName = ((position == 'before' || position == 'after') - ? element.parentNode : element).tagName.toUpperCase(); - - if (t.tags[tagName]) { - var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - if (position == 'top' || position == 'after') fragments.reverse(); - fragments.each(pos.insert.curry(element)); - } - else element.insertAdjacentHTML(pos.adjacency, content.stripScripts()); - - content.evalScripts.bind(content).defer(); - } - - return element; - }; -} - -if (Prototype.Browser.Opera) { - Element.Methods._getStyle = Element.Methods.getStyle; - Element.Methods.getStyle = function(element, style) { - switch(style) { - case 'left': - case 'top': - case 'right': - case 'bottom': - if (Element._getStyle(element, 'position') == 'static') return null; - default: return Element._getStyle(element, style); - } - }; - Element.Methods._readAttribute = Element.Methods.readAttribute; - Element.Methods.readAttribute = function(element, attribute) { - if (attribute == 'title') return element.title; - return Element._readAttribute(element, attribute); - }; -} - -else if (Prototype.Browser.IE) { - $w('positionedOffset getOffsetParent viewportOffset').each(function(method) { - Element.Methods[method] = Element.Methods[method].wrap( - function(proceed, element) { - element = $(element); - var position = element.getStyle('position'); - if (position != 'static') return proceed(element); - element.setStyle({ position: 'relative' }); - var value = proceed(element); - element.setStyle({ position: position }); - return value; - } - ); - }); - - Element.Methods.getStyle = function(element, style) { - element = $(element); - style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); - var value = element.style[style]; - if (!value && element.currentStyle) value = element.currentStyle[style]; - - if (style == 'opacity') { - if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) - if (value[1]) return parseFloat(value[1]) / 100; - return 1.0; - } - - if (value == 'auto') { - if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) - return element['offset' + style.capitalize()] + 'px'; - return null; - } - return value; - }; - - Element.Methods.setOpacity = function(element, value) { - function stripAlpha(filter){ - return filter.replace(/alpha\([^\)]*\)/gi,''); - } - element = $(element); - var currentStyle = element.currentStyle; - if ((currentStyle && !currentStyle.hasLayout) || - (!currentStyle && element.style.zoom == 'normal')) - element.style.zoom = 1; - - var filter = element.getStyle('filter'), style = element.style; - if (value == 1 || value === '') { - (filter = stripAlpha(filter)) ? - style.filter = filter : style.removeAttribute('filter'); - return element; - } else if (value < 0.00001) value = 0; - style.filter = stripAlpha(filter) + - 'alpha(opacity=' + (value * 100) + ')'; - return element; - }; - - Element._attributeTranslations = { - read: { - names: { - 'class': 'className', - 'for': 'htmlFor' - }, - values: { - _getAttr: function(element, attribute) { - return element.getAttribute(attribute, 2); - }, - _getAttrNode: function(element, attribute) { - var node = element.getAttributeNode(attribute); - return node ? node.value : ""; - }, - _getEv: function(element, attribute) { - var attribute = element.getAttribute(attribute); - return attribute ? attribute.toString().slice(23, -2) : null; - }, - _flag: function(element, attribute) { - return $(element).hasAttribute(attribute) ? attribute : null; - }, - style: function(element) { - return element.style.cssText.toLowerCase(); - }, - title: function(element) { - return element.title; - } - } - } - }; - - Element._attributeTranslations.write = { - names: Object.clone(Element._attributeTranslations.read.names), - values: { - checked: function(element, value) { - element.checked = !!value; - }, - - style: function(element, value) { - element.style.cssText = value ? value : ''; - } - } - }; - - Element._attributeTranslations.has = {}; - - $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + - 'encType maxLength readOnly longDesc').each(function(attr) { - Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; - Element._attributeTranslations.has[attr.toLowerCase()] = attr; - }); - - (function(v) { - Object.extend(v, { - href: v._getAttr, - src: v._getAttr, - type: v._getAttr, - action: v._getAttrNode, - disabled: v._flag, - checked: v._flag, - readonly: v._flag, - multiple: v._flag, - onload: v._getEv, - onunload: v._getEv, - onclick: v._getEv, - ondblclick: v._getEv, - onmousedown: v._getEv, - onmouseup: v._getEv, - onmouseover: v._getEv, - onmousemove: v._getEv, - onmouseout: v._getEv, - onfocus: v._getEv, - onblur: v._getEv, - onkeypress: v._getEv, - onkeydown: v._getEv, - onkeyup: v._getEv, - onsubmit: v._getEv, - onreset: v._getEv, - onselect: v._getEv, - onchange: v._getEv - }); - })(Element._attributeTranslations.read.values); -} - -else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { - Element.Methods.setOpacity = function(element, value) { - element = $(element); - element.style.opacity = (value == 1) ? 0.999999 : - (value === '') ? '' : (value < 0.00001) ? 0 : value; - return element; - }; -} - -else if (Prototype.Browser.WebKit) { - Element.Methods.setOpacity = function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - - if (value == 1) - if(element.tagName == 'IMG' && element.width) { - element.width++; element.width--; - } else try { - var n = document.createTextNode(' '); - element.appendChild(n); - element.removeChild(n); - } catch (e) { } - - return element; - }; - - // Safari returns margins on body which is incorrect if the child is absolutely - // positioned. For performance reasons, redefine Position.cumulativeOffset for - // KHTML/WebKit only. - Element.Methods.cumulativeOffset = function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - if (element.offsetParent == document.body) - if (Element.getStyle(element, 'position') == 'absolute') break; - - element = element.offsetParent; - } while (element); - - return Element._returnOffset(valueL, valueT); - }; -} - -if (Prototype.Browser.IE || Prototype.Browser.Opera) { - // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements - Element.Methods.update = function(element, content) { - element = $(element); - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) return element.update().insert(content); - - content = Object.toHTML(content); - var tagName = element.tagName.toUpperCase(); - - if (tagName in Element._insertionTranslations.tags) { - $A(element.childNodes).each(function(node) { element.removeChild(node) }); - Element._getContentFromAnonymousElement(tagName, content.stripScripts()) - .each(function(node) { element.appendChild(node) }); - } - else element.innerHTML = content.stripScripts(); - - content.evalScripts.bind(content).defer(); - return element; - }; -} - -if (document.createElement('div').outerHTML) { - Element.Methods.replace = function(element, content) { - element = $(element); - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - element.parentNode.replaceChild(content, element); - return element; - } - - content = Object.toHTML(content); - var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); - - if (Element._insertionTranslations.tags[tagName]) { - var nextSibling = element.next(); - var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - parent.removeChild(element); - if (nextSibling) - fragments.each(function(node) { parent.insertBefore(node, nextSibling) }); - else - fragments.each(function(node) { parent.appendChild(node) }); - } - else element.outerHTML = content.stripScripts(); - - content.evalScripts.bind(content).defer(); - return element; - }; -} - -Element._returnOffset = function(l, t) { - var result = [l, t]; - result.left = l; - result.top = t; - return result; -}; - -Element._getContentFromAnonymousElement = function(tagName, html) { - var div = new Element('div'), t = Element._insertionTranslations.tags[tagName]; - div.innerHTML = t[0] + html + t[1]; - t[2].times(function() { div = div.firstChild }); - return $A(div.childNodes); -}; - -Element._insertionTranslations = { - before: { - adjacency: 'beforeBegin', - insert: function(element, node) { - element.parentNode.insertBefore(node, element); - }, - initializeRange: function(element, range) { - range.setStartBefore(element); - } - }, - top: { - adjacency: 'afterBegin', - insert: function(element, node) { - element.insertBefore(node, element.firstChild); - }, - initializeRange: function(element, range) { - range.selectNodeContents(element); - range.collapse(true); - } - }, - bottom: { - adjacency: 'beforeEnd', - insert: function(element, node) { - element.appendChild(node); - } - }, - after: { - adjacency: 'afterEnd', - insert: function(element, node) { - element.parentNode.insertBefore(node, element.nextSibling); - }, - initializeRange: function(element, range) { - range.setStartAfter(element); - } - }, - tags: { - TABLE: ['', '
', 1], - TBODY: ['', '
', 2], - TR: ['', '
', 3], - TD: ['
', '
', 4], - SELECT: ['', 1] - } -}; - -(function() { - this.bottom.initializeRange = this.top.initializeRange; - Object.extend(this.tags, { - THEAD: this.tags.TBODY, - TFOOT: this.tags.TBODY, - TH: this.tags.TD - }); -}).call(Element._insertionTranslations); - -Element.Methods.Simulated = { - hasAttribute: function(element, attribute) { - attribute = Element._attributeTranslations.has[attribute] || attribute; - var node = $(element).getAttributeNode(attribute); - return node && node.specified; - } -}; - -Element.Methods.ByTag = { }; - -Object.extend(Element, Element.Methods); - -if (!Prototype.BrowserFeatures.ElementExtensions && - document.createElement('div').__proto__) { - window.HTMLElement = { }; - window.HTMLElement.prototype = document.createElement('div').__proto__; - Prototype.BrowserFeatures.ElementExtensions = true; -} - -Element.extend = (function() { - if (Prototype.BrowserFeatures.SpecificElementExtensions) - return Prototype.K; - - var Methods = { }, ByTag = Element.Methods.ByTag; - - var extend = Object.extend(function(element) { - if (!element || element._extendedByPrototype || - element.nodeType != 1 || element == window) return element; - - var methods = Object.clone(Methods), - tagName = element.tagName, property, value; - - // extend methods for specific tags - if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); - - for (property in methods) { - value = methods[property]; - if (Object.isFunction(value) && !(property in element)) - element[property] = value.methodize(); - } - - element._extendedByPrototype = Prototype.emptyFunction; - return element; - - }, { - refresh: function() { - // extend methods for all tags (Safari doesn't need this) - if (!Prototype.BrowserFeatures.ElementExtensions) { - Object.extend(Methods, Element.Methods); - Object.extend(Methods, Element.Methods.Simulated); - } - } - }); - - extend.refresh(); - return extend; -})(); - -Element.hasAttribute = function(element, attribute) { - if (element.hasAttribute) return element.hasAttribute(attribute); - return Element.Methods.Simulated.hasAttribute(element, attribute); -}; - -Element.addMethods = function(methods) { - var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; - - if (!methods) { - Object.extend(Form, Form.Methods); - Object.extend(Form.Element, Form.Element.Methods); - Object.extend(Element.Methods.ByTag, { - "FORM": Object.clone(Form.Methods), - "INPUT": Object.clone(Form.Element.Methods), - "SELECT": Object.clone(Form.Element.Methods), - "TEXTAREA": Object.clone(Form.Element.Methods) - }); - } - - if (arguments.length == 2) { - var tagName = methods; - methods = arguments[1]; - } - - if (!tagName) Object.extend(Element.Methods, methods || { }); - else { - if (Object.isArray(tagName)) tagName.each(extend); - else extend(tagName); - } - - function extend(tagName) { - tagName = tagName.toUpperCase(); - if (!Element.Methods.ByTag[tagName]) - Element.Methods.ByTag[tagName] = { }; - Object.extend(Element.Methods.ByTag[tagName], methods); - } - - function copy(methods, destination, onlyIfAbsent) { - onlyIfAbsent = onlyIfAbsent || false; - for (var property in methods) { - var value = methods[property]; - if (!Object.isFunction(value)) continue; - if (!onlyIfAbsent || !(property in destination)) - destination[property] = value.methodize(); - } - } - - function findDOMClass(tagName) { - var klass; - var trans = { - "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", - "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", - "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", - "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", - "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": - "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": - "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": - "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": - "FrameSet", "IFRAME": "IFrame" - }; - if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName.capitalize() + 'Element'; - if (window[klass]) return window[klass]; - - window[klass] = { }; - window[klass].prototype = document.createElement(tagName).__proto__; - return window[klass]; - } - - if (F.ElementExtensions) { - copy(Element.Methods, HTMLElement.prototype); - copy(Element.Methods.Simulated, HTMLElement.prototype, true); - } - - if (F.SpecificElementExtensions) { - for (var tag in Element.Methods.ByTag) { - var klass = findDOMClass(tag); - if (Object.isUndefined(klass)) continue; - copy(T[tag], klass.prototype); - } - } - - Object.extend(Element, Element.Methods); - delete Element.ByTag; - - if (Element.extend.refresh) Element.extend.refresh(); - Element.cache = { }; -}; - -document.viewport = { - getDimensions: function() { - var dimensions = { }; - $w('width height').each(function(d) { - var D = d.capitalize(); - dimensions[d] = self['inner' + D] || - (document.documentElement['client' + D] || document.body['client' + D]); - }); - return dimensions; - }, - - getWidth: function() { - return this.getDimensions().width; - }, - - getHeight: function() { - return this.getDimensions().height; - }, - - getScrollOffsets: function() { - return Element._returnOffset( - window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, - window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); - } -}; -/* Portions of the Selector class are derived from Jack Slocum’s DomQuery, - * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style - * license. Please see http://www.yui-ext.com/ for more information. */ - -var Selector = Class.create({ - initialize: function(expression) { - this.expression = expression.strip(); - this.compileMatcher(); - }, - - compileMatcher: function() { - // Selectors with namespaced attributes can't use the XPath version - if (Prototype.BrowserFeatures.XPath && !(/(\[[\w-]*?:|:checked)/).test(this.expression)) - return this.compileXPathMatcher(); - - var e = this.expression, ps = Selector.patterns, h = Selector.handlers, - c = Selector.criteria, le, p, m; - - if (Selector._cache[e]) { - this.matcher = Selector._cache[e]; - return; - } - - this.matcher = ["this.matcher = function(root) {", - "var r = root, h = Selector.handlers, c = false, n;"]; - - while (e && le != e && (/\S/).test(e)) { - le = e; - for (var i in ps) { - p = ps[i]; - if (m = e.match(p)) { - this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : - new Template(c[i]).evaluate(m)); - e = e.replace(m[0], ''); - break; - } - } - } - - this.matcher.push("return h.unique(n);\n}"); - eval(this.matcher.join('\n')); - Selector._cache[this.expression] = this.matcher; - }, - - compileXPathMatcher: function() { - var e = this.expression, ps = Selector.patterns, - x = Selector.xpath, le, m; - - if (Selector._cache[e]) { - this.xpath = Selector._cache[e]; return; - } - - this.matcher = ['.//*']; - while (e && le != e && (/\S/).test(e)) { - le = e; - for (var i in ps) { - if (m = e.match(ps[i])) { - this.matcher.push(Object.isFunction(x[i]) ? x[i](m) : - new Template(x[i]).evaluate(m)); - e = e.replace(m[0], ''); - break; - } - } - } - - this.xpath = this.matcher.join(''); - Selector._cache[this.expression] = this.xpath; - }, - - findElements: function(root) { - root = root || document; - if (this.xpath) return document._getElementsByXPath(this.xpath, root); - return this.matcher(root); - }, - - match: function(element) { - this.tokens = []; - - var e = this.expression, ps = Selector.patterns, as = Selector.assertions; - var le, p, m; - - while (e && le !== e && (/\S/).test(e)) { - le = e; - for (var i in ps) { - p = ps[i]; - if (m = e.match(p)) { - // use the Selector.assertions methods unless the selector - // is too complex. - if (as[i]) { - this.tokens.push([i, Object.clone(m)]); - e = e.replace(m[0], ''); - } else { - // reluctantly do a document-wide search - // and look for a match in the array - return this.findElements(document).include(element); - } - } - } - } - - var match = true, name, matches; - for (var i = 0, token; token = this.tokens[i]; i++) { - name = token[0], matches = token[1]; - if (!Selector.assertions[name](element, matches)) { - match = false; break; - } - } - - return match; - }, - - toString: function() { - return this.expression; - }, - - inspect: function() { - return "#"; - } -}); - -Object.extend(Selector, { - _cache: { }, - - xpath: { - descendant: "//*", - child: "/*", - adjacent: "/following-sibling::*[1]", - laterSibling: '/following-sibling::*', - tagName: function(m) { - if (m[1] == '*') return ''; - return "[local-name()='" + m[1].toLowerCase() + - "' or local-name()='" + m[1].toUpperCase() + "']"; - }, - className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", - id: "[@id='#{1}']", - attrPresence: "[@#{1}]", - attr: function(m) { - m[3] = m[5] || m[6]; - return new Template(Selector.xpath.operators[m[2]]).evaluate(m); - }, - pseudo: function(m) { - var h = Selector.xpath.pseudos[m[1]]; - if (!h) return ''; - if (Object.isFunction(h)) return h(m); - return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); - }, - operators: { - '=': "[@#{1}='#{3}']", - '!=': "[@#{1}!='#{3}']", - '^=': "[starts-with(@#{1}, '#{3}')]", - '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", - '*=': "[contains(@#{1}, '#{3}')]", - '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", - '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" - }, - pseudos: { - 'first-child': '[not(preceding-sibling::*)]', - 'last-child': '[not(following-sibling::*)]', - 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', - 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]", - 'checked': "[@checked]", - 'disabled': "[@disabled]", - 'enabled': "[not(@disabled)]", - 'not': function(m) { - var e = m[6], p = Selector.patterns, - x = Selector.xpath, le, m, v; - - var exclusion = []; - while (e && le != e && (/\S/).test(e)) { - le = e; - for (var i in p) { - if (m = e.match(p[i])) { - v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m); - exclusion.push("(" + v.substring(1, v.length - 1) + ")"); - e = e.replace(m[0], ''); - break; - } - } - } - return "[not(" + exclusion.join(" and ") + ")]"; - }, - 'nth-child': function(m) { - return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); - }, - 'nth-last-child': function(m) { - return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); - }, - 'nth-of-type': function(m) { - return Selector.xpath.pseudos.nth("position() ", m); - }, - 'nth-last-of-type': function(m) { - return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); - }, - 'first-of-type': function(m) { - m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); - }, - 'last-of-type': function(m) { - m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); - }, - 'only-of-type': function(m) { - var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); - }, - nth: function(fragment, m) { - var mm, formula = m[6], predicate; - if (formula == 'even') formula = '2n+0'; - if (formula == 'odd') formula = '2n+1'; - if (mm = formula.match(/^(\d+)$/)) // digit only - return '[' + fragment + "= " + mm[1] + ']'; - if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b - if (mm[1] == "-") mm[1] = -1; - var a = mm[1] ? Number(mm[1]) : 1; - var b = mm[2] ? Number(mm[2]) : 0; - predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + - "((#{fragment} - #{b}) div #{a} >= 0)]"; - return new Template(predicate).evaluate({ - fragment: fragment, a: a, b: b }); - } - } - } - }, - - criteria: { - tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', - className: 'n = h.className(n, r, "#{1}", c); c = false;', - id: 'n = h.id(n, r, "#{1}", c); c = false;', - attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;', - attr: function(m) { - m[3] = (m[5] || m[6]); - return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m); - }, - pseudo: function(m) { - if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); - return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); - }, - descendant: 'c = "descendant";', - child: 'c = "child";', - adjacent: 'c = "adjacent";', - laterSibling: 'c = "laterSibling";' - }, - - patterns: { - // combinators must be listed first - // (and descendant needs to be last combinator) - laterSibling: /^\s*~\s*/, - child: /^\s*>\s*/, - adjacent: /^\s*\+\s*/, - descendant: /^\s/, - - // selectors follow - tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, - id: /^#([\w\-\*]+)(\b|$)/, - className: /^\.([\w\-\*]+)(\b|$)/, - pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/, - attrPresence: /^\[([\w]+)\]/, - attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ - }, - - // for Selector.match and Element#match - assertions: { - tagName: function(element, matches) { - return matches[1].toUpperCase() == element.tagName.toUpperCase(); - }, - - className: function(element, matches) { - return Element.hasClassName(element, matches[1]); - }, - - id: function(element, matches) { - return element.id === matches[1]; - }, - - attrPresence: function(element, matches) { - return Element.hasAttribute(element, matches[1]); - }, - - attr: function(element, matches) { - var nodeValue = Element.readAttribute(element, matches[1]); - return Selector.operators[matches[2]](nodeValue, matches[3]); - } - }, - - handlers: { - // UTILITY FUNCTIONS - // joins two collections - concat: function(a, b) { - for (var i = 0, node; node = b[i]; i++) - a.push(node); - return a; - }, - - // marks an array of nodes for counting - mark: function(nodes) { - for (var i = 0, node; node = nodes[i]; i++) - node._counted = true; - return nodes; - }, - - unmark: function(nodes) { - for (var i = 0, node; node = nodes[i]; i++) - node._counted = undefined; - return nodes; - }, - - // mark each child node with its position (for nth calls) - // "ofType" flag indicates whether we're indexing for nth-of-type - // rather than nth-child - index: function(parentNode, reverse, ofType) { - parentNode._counted = true; - if (reverse) { - for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { - var node = nodes[i]; - if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; - } - } else { - for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) - if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; - } - }, - - // filters out duplicates and extends all nodes - unique: function(nodes) { - if (nodes.length == 0) return nodes; - var results = [], n; - for (var i = 0, l = nodes.length; i < l; i++) - if (!(n = nodes[i])._counted) { - n._counted = true; - results.push(Element.extend(n)); - } - return Selector.handlers.unmark(results); - }, - - // COMBINATOR FUNCTIONS - descendant: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - h.concat(results, node.getElementsByTagName('*')); - return results; - }, - - child: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) { - for (var j = 0, children = [], child; child = node.childNodes[j]; j++) - if (child.nodeType == 1 && child.tagName != '!') results.push(child); - } - return results; - }, - - adjacent: function(nodes) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - var next = this.nextElementSibling(node); - if (next) results.push(next); - } - return results; - }, - - laterSibling: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - h.concat(results, Element.nextSiblings(node)); - return results; - }, - - nextElementSibling: function(node) { - while (node = node.nextSibling) - if (node.nodeType == 1) return node; - return null; - }, - - previousElementSibling: function(node) { - while (node = node.previousSibling) - if (node.nodeType == 1) return node; - return null; - }, - - // TOKEN FUNCTIONS - tagName: function(nodes, root, tagName, combinator) { - tagName = tagName.toUpperCase(); - var results = [], h = Selector.handlers; - if (nodes) { - if (combinator) { - // fastlane for ordinary descendant combinators - if (combinator == "descendant") { - for (var i = 0, node; node = nodes[i]; i++) - h.concat(results, node.getElementsByTagName(tagName)); - return results; - } else nodes = this[combinator](nodes); - if (tagName == "*") return nodes; - } - for (var i = 0, node; node = nodes[i]; i++) - if (node.tagName.toUpperCase() == tagName) results.push(node); - return results; - } else return root.getElementsByTagName(tagName); - }, - - id: function(nodes, root, id, combinator) { - var targetNode = $(id), h = Selector.handlers; - if (!targetNode) return []; - if (!nodes && root == document) return [targetNode]; - if (nodes) { - if (combinator) { - if (combinator == 'child') { - for (var i = 0, node; node = nodes[i]; i++) - if (targetNode.parentNode == node) return [targetNode]; - } else if (combinator == 'descendant') { - for (var i = 0, node; node = nodes[i]; i++) - if (Element.descendantOf(targetNode, node)) return [targetNode]; - } else if (combinator == 'adjacent') { - for (var i = 0, node; node = nodes[i]; i++) - if (Selector.handlers.previousElementSibling(targetNode) == node) - return [targetNode]; - } else nodes = h[combinator](nodes); - } - for (var i = 0, node; node = nodes[i]; i++) - if (node == targetNode) return [targetNode]; - return []; - } - return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; - }, - - className: function(nodes, root, className, combinator) { - if (nodes && combinator) nodes = this[combinator](nodes); - return Selector.handlers.byClassName(nodes, root, className); - }, - - byClassName: function(nodes, root, className) { - if (!nodes) nodes = Selector.handlers.descendant([root]); - var needle = ' ' + className + ' '; - for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { - nodeClassName = node.className; - if (nodeClassName.length == 0) continue; - if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) - results.push(node); - } - return results; - }, - - attrPresence: function(nodes, root, attr) { - if (!nodes) nodes = root.getElementsByTagName("*"); - var results = []; - for (var i = 0, node; node = nodes[i]; i++) - if (Element.hasAttribute(node, attr)) results.push(node); - return results; - }, - - attr: function(nodes, root, attr, value, operator) { - if (!nodes) nodes = root.getElementsByTagName("*"); - var handler = Selector.operators[operator], results = []; - for (var i = 0, node; node = nodes[i]; i++) { - var nodeValue = Element.readAttribute(node, attr); - if (nodeValue === null) continue; - if (handler(nodeValue, value)) results.push(node); - } - return results; - }, - - pseudo: function(nodes, name, value, root, combinator) { - if (nodes && combinator) nodes = this[combinator](nodes); - if (!nodes) nodes = root.getElementsByTagName("*"); - return Selector.pseudos[name](nodes, value, root); - } - }, - - pseudos: { - 'first-child': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - if (Selector.handlers.previousElementSibling(node)) continue; - results.push(node); - } - return results; - }, - 'last-child': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - if (Selector.handlers.nextElementSibling(node)) continue; - results.push(node); - } - return results; - }, - 'only-child': function(nodes, value, root) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) - results.push(node); - return results; - }, - 'nth-child': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root); - }, - 'nth-last-child': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, true); - }, - 'nth-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, false, true); - }, - 'nth-last-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, true, true); - }, - 'first-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, "1", root, false, true); - }, - 'last-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, "1", root, true, true); - }, - 'only-of-type': function(nodes, formula, root) { - var p = Selector.pseudos; - return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); - }, - - // handles the an+b logic - getIndices: function(a, b, total) { - if (a == 0) return b > 0 ? [b] : []; - return $R(1, total).inject([], function(memo, i) { - if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); - return memo; - }); - }, - - // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type - nth: function(nodes, formula, root, reverse, ofType) { - if (nodes.length == 0) return []; - if (formula == 'even') formula = '2n+0'; - if (formula == 'odd') formula = '2n+1'; - var h = Selector.handlers, results = [], indexed = [], m; - h.mark(nodes); - for (var i = 0, node; node = nodes[i]; i++) { - if (!node.parentNode._counted) { - h.index(node.parentNode, reverse, ofType); - indexed.push(node.parentNode); - } - } - if (formula.match(/^\d+$/)) { // just a number - formula = Number(formula); - for (var i = 0, node; node = nodes[i]; i++) - if (node.nodeIndex == formula) results.push(node); - } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b - if (m[1] == "-") m[1] = -1; - var a = m[1] ? Number(m[1]) : 1; - var b = m[2] ? Number(m[2]) : 0; - var indices = Selector.pseudos.getIndices(a, b, nodes.length); - for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { - for (var j = 0; j < l; j++) - if (node.nodeIndex == indices[j]) results.push(node); - } - } - h.unmark(nodes); - h.unmark(indexed); - return results; - }, - - 'empty': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - // IE treats comments as element nodes - if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue; - results.push(node); - } - return results; - }, - - 'not': function(nodes, selector, root) { - var h = Selector.handlers, selectorType, m; - var exclusions = new Selector(selector).findElements(root); - h.mark(exclusions); - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!node._counted) results.push(node); - h.unmark(exclusions); - return results; - }, - - 'enabled': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!node.disabled) results.push(node); - return results; - }, - - 'disabled': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (node.disabled) results.push(node); - return results; - }, - - 'checked': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (node.checked) results.push(node); - return results; - } - }, - - operators: { - '=': function(nv, v) { return nv == v; }, - '!=': function(nv, v) { return nv != v; }, - '^=': function(nv, v) { return nv.startsWith(v); }, - '$=': function(nv, v) { return nv.endsWith(v); }, - '*=': function(nv, v) { return nv.include(v); }, - '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, - '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } - }, - - matchElements: function(elements, expression) { - var matches = new Selector(expression).findElements(), h = Selector.handlers; - h.mark(matches); - for (var i = 0, results = [], element; element = elements[i]; i++) - if (element._counted) results.push(element); - h.unmark(matches); - return results; - }, - - findElement: function(elements, expression, index) { - if (Object.isNumber(expression)) { - index = expression; expression = false; - } - return Selector.matchElements(elements, expression || '*')[index || 0]; - }, - - findChildElements: function(element, expressions) { - var exprs = expressions.join(','), expressions = []; - exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { - expressions.push(m[1].strip()); - }); - var results = [], h = Selector.handlers; - for (var i = 0, l = expressions.length, selector; i < l; i++) { - selector = new Selector(expressions[i].strip()); - h.concat(results, selector.findElements(element)); - } - return (l > 1) ? h.unique(results) : results; - } -}); - -function $$() { - return Selector.findChildElements(document, $A(arguments)); -} -var Form = { - reset: function(form) { - $(form).reset(); - return form; - }, - - serializeElements: function(elements, options) { - if (typeof options != 'object') options = { hash: !!options }; - else if (options.hash === undefined) options.hash = true; - var key, value, submitted = false, submit = options.submit; - - var data = elements.inject({ }, function(result, element) { - if (!element.disabled && element.name) { - key = element.name; value = $(element).getValue(); - if (value != null && (element.type != 'submit' || (!submitted && - submit !== false && (!submit || key == submit) && (submitted = true)))) { - if (key in result) { - // a key is already present; construct an array of values - if (!Object.isArray(result[key])) result[key] = [result[key]]; - result[key].push(value); - } - else result[key] = value; - } - } - return result; - }); - - return options.hash ? data : Object.toQueryString(data); - } -}; - -Form.Methods = { - serialize: function(form, options) { - return Form.serializeElements(Form.getElements(form), options); - }, - - getElements: function(form) { - return $A($(form).getElementsByTagName('*')).inject([], - function(elements, child) { - if (Form.Element.Serializers[child.tagName.toLowerCase()]) - elements.push(Element.extend(child)); - return elements; - } - ); - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) return $A(inputs).map(Element.extend); - - for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || (name && input.name != name)) - continue; - matchingInputs.push(Element.extend(input)); - } - - return matchingInputs; - }, - - disable: function(form) { - form = $(form); - Form.getElements(form).invoke('disable'); - return form; - }, - - enable: function(form) { - form = $(form); - Form.getElements(form).invoke('enable'); - return form; - }, - - findFirstElement: function(form) { - var elements = $(form).getElements().findAll(function(element) { - return 'hidden' != element.type && !element.disabled; - }); - var firstByIndex = elements.findAll(function(element) { - return element.hasAttribute('tabIndex') && element.tabIndex >= 0; - }).sortBy(function(element) { return element.tabIndex }).first(); - - return firstByIndex ? firstByIndex : elements.find(function(element) { - return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); - }); - }, - - focusFirstElement: function(form) { - form = $(form); - form.findFirstElement().activate(); - return form; - }, - - request: function(form, options) { - form = $(form), options = Object.clone(options || { }); - - var params = options.parameters, action = form.readAttribute('action') || ''; - if (action.blank()) action = window.location.href; - options.parameters = form.serialize(true); - - if (params) { - if (Object.isString(params)) params = params.toQueryParams(); - Object.extend(options.parameters, params); - } - - if (form.hasAttribute('method') && !options.method) - options.method = form.method; - - return new Ajax.Request(action, options); - } -}; - -/*--------------------------------------------------------------------------*/ - -Form.Element = { - focus: function(element) { - $(element).focus(); - return element; - }, - - select: function(element) { - $(element).select(); - return element; - } -}; - -Form.Element.Methods = { - serialize: function(element) { - element = $(element); - if (!element.disabled && element.name) { - var value = element.getValue(); - if (value != undefined) { - var pair = { }; - pair[element.name] = value; - return Object.toQueryString(pair); - } - } - return ''; - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - return Form.Element.Serializers[method](element); - }, - - setValue: function(element, value) { - element = $(element); - var method = element.tagName.toLowerCase(); - Form.Element.Serializers[method](element, value); - return element; - }, - - clear: function(element) { - $(element).value = ''; - return element; - }, - - present: function(element) { - return $(element).value != ''; - }, - - activate: function(element) { - element = $(element); - try { - element.focus(); - if (element.select && (element.tagName.toLowerCase() != 'input' || - !['button', 'reset', 'submit'].include(element.type))) - element.select(); - } catch (e) { } - return element; - }, - - disable: function(element) { - element = $(element); - element.blur(); - element.disabled = true; - return element; - }, - - enable: function(element) { - element = $(element); - element.disabled = false; - return element; - } -}; - -/*--------------------------------------------------------------------------*/ - -var Field = Form.Element; -var $F = Form.Element.Methods.getValue; - -/*--------------------------------------------------------------------------*/ - -Form.Element.Serializers = { - input: function(element, value) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - return Form.Element.Serializers.inputSelector(element, value); - default: - return Form.Element.Serializers.textarea(element, value); - } - }, - - inputSelector: function(element, value) { - if (value === undefined) return element.checked ? element.value : null; - else element.checked = !!value; - }, - - textarea: function(element, value) { - if (value === undefined) return element.value; - else element.value = value; - }, - - select: function(element, index) { - if (index === undefined) - return this[element.type == 'select-one' ? - 'selectOne' : 'selectMany'](element); - else { - var opt, value, single = !Object.isArray(index); - for (var i = 0, length = element.length; i < length; i++) { - opt = element.options[i]; - value = this.optionValue(opt); - if (single) { - if (value == index) { - opt.selected = true; - return; - } - } - else opt.selected = index.include(value); - } - } - }, - - selectOne: function(element) { - var index = element.selectedIndex; - return index >= 0 ? this.optionValue(element.options[index]) : null; - }, - - selectMany: function(element) { - var values, length = element.length; - if (!length) return null; - - for (var i = 0, values = []; i < length; i++) { - var opt = element.options[i]; - if (opt.selected) values.push(this.optionValue(opt)); - } - return values; - }, - - optionValue: function(opt) { - // extend element because hasAttribute may not be native - return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; - } -}; - -/*--------------------------------------------------------------------------*/ - -Abstract.TimedObserver = Class.create(PeriodicalExecuter, { - initialize: function($super, element, frequency, callback) { - $super(callback, frequency); - this.element = $(element); - this.lastValue = this.getValue(); - }, - - execute: function() { - var value = this.getValue(); - if (Object.isString(this.lastValue) && Object.isString(value) ? - this.lastValue != value : String(this.lastValue) != String(value)) { - this.callback(this.element, value); - this.lastValue = value; - } - } -}); - -Form.Element.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = Class.create({ - initialize: function(element, callback) { - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - if (this.element.tagName.toLowerCase() == 'form') - this.registerFormCallbacks(); - else - this.registerCallback(this.element); - }, - - onElementEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - }, - - registerFormCallbacks: function() { - Form.getElements(this.element).each(this.registerCallback, this); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - default: - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -}); - -Form.Element.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); -if (!window.Event) var Event = { }; - -Object.extend(Event, { - KEY_BACKSPACE: 8, - KEY_TAB: 9, - KEY_RETURN: 13, - KEY_ESC: 27, - KEY_LEFT: 37, - KEY_UP: 38, - KEY_RIGHT: 39, - KEY_DOWN: 40, - KEY_DELETE: 46, - KEY_HOME: 36, - KEY_END: 35, - KEY_PAGEUP: 33, - KEY_PAGEDOWN: 34, - KEY_INSERT: 45, - - cache: { }, - - relatedTarget: function(event) { - var element; - switch(event.type) { - case 'mouseover': element = event.fromElement; break; - case 'mouseout': element = event.toElement; break; - default: return null; - } - return Element.extend(element); - } -}); - -Event.Methods = (function() { - var isButton; - - if (Prototype.Browser.IE) { - var buttonMap = { 0: 1, 1: 4, 2: 2 }; - isButton = function(event, code) { - return event.button == buttonMap[code]; - }; - - } else if (Prototype.Browser.WebKit) { - isButton = function(event, code) { - switch (code) { - case 0: return event.which == 1 && !event.metaKey; - case 1: return event.which == 1 && event.metaKey; - default: return false; - } - }; - - } else { - isButton = function(event, code) { - return event.which ? (event.which === code + 1) : (event.button === code); - }; - } - - return { - isLeftClick: function(event) { return isButton(event, 0) }, - isMiddleClick: function(event) { return isButton(event, 1) }, - isRightClick: function(event) { return isButton(event, 2) }, - - element: function(event) { - var node = Event.extend(event).target; - return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node); - }, - - findElement: function(event, expression) { - var element = Event.element(event); - return element.match(expression) ? element : element.up(expression); - }, - - pointer: function(event) { - return { - x: event.pageX || (event.clientX + - (document.documentElement.scrollLeft || document.body.scrollLeft)), - y: event.pageY || (event.clientY + - (document.documentElement.scrollTop || document.body.scrollTop)) - }; - }, - - pointerX: function(event) { return Event.pointer(event).x }, - pointerY: function(event) { return Event.pointer(event).y }, - - stop: function(event) { - Event.extend(event); - event.preventDefault(); - event.stopPropagation(); - event.stopped = true; - } - }; -})(); - -Event.extend = (function() { - var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { - m[name] = Event.Methods[name].methodize(); - return m; - }); - - if (Prototype.Browser.IE) { - Object.extend(methods, { - stopPropagation: function() { this.cancelBubble = true }, - preventDefault: function() { this.returnValue = false }, - inspect: function() { return "[object Event]" } - }); - - return function(event) { - if (!event) return false; - if (event._extendedByPrototype) return event; - - event._extendedByPrototype = Prototype.emptyFunction; - var pointer = Event.pointer(event); - Object.extend(event, { - target: event.srcElement, - relatedTarget: Event.relatedTarget(event), - pageX: pointer.x, - pageY: pointer.y - }); - return Object.extend(event, methods); - }; - - } else { - Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__; - Object.extend(Event.prototype, methods); - return Prototype.K; - } -})(); - -Object.extend(Event, (function() { - var cache = Event.cache; - - function getEventID(element) { - if (element._eventID) return element._eventID; - arguments.callee.id = arguments.callee.id || 1; - return element._eventID = ++arguments.callee.id; - } - - function getDOMEventName(eventName) { - if (eventName && eventName.include(':')) return "dataavailable"; - return eventName; - } - - function getCacheForID(id) { - return cache[id] = cache[id] || { }; - } - - function getWrappersForEventName(id, eventName) { - var c = getCacheForID(id); - return c[eventName] = c[eventName] || []; - } - - function createWrapper(element, eventName, handler) { - var id = getEventID(element); - var c = getWrappersForEventName(id, eventName); - if (c.pluck("handler").include(handler)) return false; - - var wrapper = function(event) { - if (!Event || !Event.extend || - (event.eventName && event.eventName != eventName)) - return false; - - Event.extend(event); - handler.call(element, event) - }; - - wrapper.handler = handler; - c.push(wrapper); - return wrapper; - } - - function findWrapper(id, eventName, handler) { - var c = getWrappersForEventName(id, eventName); - return c.find(function(wrapper) { return wrapper.handler == handler }); - } - - function destroyWrapper(id, eventName, handler) { - var c = getCacheForID(id); - if (!c[eventName]) return false; - c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); - } - - function destroyCache() { - for (var id in cache) - for (var eventName in cache[id]) - cache[id][eventName] = null; - } - - if (window.attachEvent) { - window.attachEvent("onunload", destroyCache); - } - - return { - observe: function(element, eventName, handler) { - element = $(element); - var name = getDOMEventName(eventName); - - var wrapper = createWrapper(element, eventName, handler); - if (!wrapper) return element; - - if (element.addEventListener) { - element.addEventListener(name, wrapper, false); - } else { - element.attachEvent("on" + name, wrapper); - } - - return element; - }, - - stopObserving: function(element, eventName, handler) { - element = $(element); - var id = getEventID(element), name = getDOMEventName(eventName); - - if (!handler && eventName) { - getWrappersForEventName(id, eventName).each(function(wrapper) { - element.stopObserving(eventName, wrapper.handler); - }); - return element; - - } else if (!eventName) { - Object.keys(getCacheForID(id)).each(function(eventName) { - element.stopObserving(eventName); - }); - return element; - } - - var wrapper = findWrapper(id, eventName, handler); - if (!wrapper) return element; - - if (element.removeEventListener) { - element.removeEventListener(name, wrapper, false); - } else { - element.detachEvent("on" + name, wrapper); - } - - destroyWrapper(id, eventName, handler); - - return element; - }, - - fire: function(element, eventName, memo) { - element = $(element); - if (element == document && document.createEvent && !element.dispatchEvent) - element = document.documentElement; - - if (document.createEvent) { - var event = document.createEvent("HTMLEvents"); - event.initEvent("dataavailable", true, true); - } else { - var event = document.createEventObject(); - event.eventType = "ondataavailable"; - } - - event.eventName = eventName; - event.memo = memo || { }; - - if (document.createEvent) { - element.dispatchEvent(event); - } else { - element.fireEvent(event.eventType, event); - } - - return event; - } - }; -})()); - -Object.extend(Event, Event.Methods); - -Element.addMethods({ - fire: Event.fire, - observe: Event.observe, - stopObserving: Event.stopObserving -}); - -Object.extend(document, { - fire: Element.Methods.fire.methodize(), - observe: Element.Methods.observe.methodize(), - stopObserving: Element.Methods.stopObserving.methodize() -}); - -(function() { - /* Support for the DOMContentLoaded event is based on work by Dan Webb, - Matthias Miller, Dean Edwards and John Resig. */ - - var timer, fired = false; - - function fireContentLoadedEvent() { - if (fired) return; - if (timer) window.clearInterval(timer); - document.fire("dom:loaded"); - fired = true; - } - - if (document.addEventListener) { - if (Prototype.Browser.WebKit) { - timer = window.setInterval(function() { - if (/loaded|complete/.test(document.readyState)) - fireContentLoadedEvent(); - }, 0); - - Event.observe(window, "load", fireContentLoadedEvent); - - } else { - document.addEventListener("DOMContentLoaded", - fireContentLoadedEvent, false); - } - - } else { - document.write("