ruby-changes:31652
From: naruse <ko1@a...>
Date: Wed, 20 Nov 2013 11:55:17 +0900 (JST)
Subject: [ruby-changes:31652] naruse:r43731 (trunk): * ext/json: merge JSON 1.8.1.
naruse 2013-11-20 11:55:08 +0900 (Wed, 20 Nov 2013) New Revision: 43731 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43731 Log: * ext/json: merge JSON 1.8.1. https://github.com/nurse/json/compare/002ac2771ce32776b32ccd2d06e5604de6c36dcd...e09ffc0d7da25d0393873936c118c188c78dbac3 * Remove Rubinius exception since transcoding should be working now. * Fix https://github.com/flori/json/issues/162 reported by Marc-Andre Lafortune <github_rocks@m...>. Thanks! * Applied patches by Yui NARUSE <naruse@a...> 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. Modified files: trunk/ChangeLog trunk/ext/json/fbuffer/fbuffer.h trunk/ext/json/generator/depend trunk/ext/json/generator/generator.c trunk/ext/json/lib/json/add/range.rb trunk/ext/json/lib/json/common.rb trunk/ext/json/lib/json/generic_object.rb trunk/ext/json/lib/json/version.rb trunk/ext/json/parser/depend trunk/test/json/test_json_generate.rb trunk/test/json/test_json_generic_object.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 43730) +++ ChangeLog (revision 43731) @@ -1,3 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Nov 20 11:46:38 2013 NARUSE, Yui <naruse@r...> + + * ext/json: merge JSON 1.8.1. + https://github.com/nurse/json/compare/002ac2771ce32776b32ccd2d06e5604de6c36dcd...e09ffc0d7da25d0393873936c118c188c78dbac3 + * Remove Rubinius exception since transcoding should be working now. + * Fix https://github.com/flori/json/issues/162 reported by Marc-Andre + Lafortune <github_rocks@m...>. Thanks! + * Applied patches by Yui NARUSE <naruse@a...> 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. + Wed Nov 20 01:39:02 2013 Nobuyoshi Nakada <nobu@r...> * lib/rdoc/constant.rb (RDoc::Constant#documented?): workaround for Index: ext/json/fbuffer/fbuffer.h =================================================================== --- ext/json/fbuffer/fbuffer.h (revision 43730) +++ ext/json/fbuffer/fbuffer.h (revision 43731) @@ -67,7 +67,7 @@ static VALUE fbuffer_to_s(FBuffer *fb); https://github.com/ruby/ruby/blob/trunk/ext/json/fbuffer/fbuffer.h#L67 static FBuffer *fbuffer_alloc(unsigned long initial_length) { FBuffer *fb; - if (initial_length == 0) initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT; + if (initial_length <= 0) initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT; fb = ALLOC(FBuffer); memset((void *) fb, 0, sizeof(FBuffer)); fb->initial_length = initial_length; @@ -117,9 +117,9 @@ static void fbuffer_append_str(FBuffer * https://github.com/ruby/ruby/blob/trunk/ext/json/fbuffer/fbuffer.h#L117 const char *newstr = StringValuePtr(str); unsigned long len = RSTRING_LEN(str); - fbuffer_append(fb, newstr, len); - RB_GC_GUARD(str); + + fbuffer_append(fb, newstr, len); } #endif Index: ext/json/generator/depend =================================================================== --- ext/json/generator/depend (revision 43730) +++ ext/json/generator/depend (revision 43731) @@ -1,5 +1 @@ -generator.o: generator.c $(HDRS) $(ruby_headers) $(srcdir)/../fbuffer/fbuffer.h \ - $(hdrdir)/ruby/encoding.h \ - $(hdrdir)/ruby/oniguruma.h \ - $(hdrdir)/ruby/re.h \ - $(hdrdir)/ruby/regex.h \ +generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h Index: ext/json/generator/generator.c =================================================================== --- ext/json/generator/generator.c (revision 43730) +++ ext/json/generator/generator.c (revision 43731) @@ -273,7 +273,18 @@ static void convert_UTF8_to_JSON(FBuffer https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L273 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; } @@ -288,7 +299,7 @@ static void convert_UTF8_to_JSON(FBuffer https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L299 static char *fstrndup(const char *ptr, unsigned long len) { char *result; - if (len == 0) return NULL; + if (len <= 0) return NULL; result = ALLOC_N(char, len); memccpy(result, ptr, 0, len); return result; @@ -511,11 +522,8 @@ static VALUE cState_configure(VALUE self https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L522 { 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)) { @@ -1178,11 +1186,11 @@ static VALUE cState_array_nl_set(VALUE s https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L1186 /* - * call-seq: check_circular? - * - * Returns true, if circular data structures should be checked, - * otherwise returns false. - */ +* call-seq: check_circular? +* +* Returns true, if circular data structures should be checked, +* otherwise returns false. +*/ static VALUE cState_check_circular_p(VALUE self) { GET_STATE(self); Index: ext/json/lib/json/generic_object.rb =================================================================== --- ext/json/lib/json/generic_object.rb (revision 43730) +++ ext/json/lib/json/generic_object.rb (revision 43731) @@ -31,6 +31,15 @@ module JSON https://github.com/ruby/ruby/blob/trunk/ext/json/lib/json/generic_object.rb#L31 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 Index: ext/json/lib/json/version.rb =================================================================== --- ext/json/lib/json/version.rb (revision 43730) +++ ext/json/lib/json/version.rb (revision 43731) @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ext/json/lib/json/version.rb#L1 module JSON # JSON version - VERSION = '1.7.7' + 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: Index: ext/json/lib/json/add/range.rb =================================================================== --- ext/json/lib/json/add/range.rb (revision 43730) +++ ext/json/lib/json/add/range.rb (revision 43731) @@ -16,7 +16,7 @@ class Range https://github.com/ruby/ruby/blob/trunk/ext/json/lib/json/add/range.rb#L16 def as_json(*) { JSON.create_id => self.class.name, - 'a' => [ first, self.end, exclude_end? ] + 'a' => [ first, last, exclude_end? ] } end Index: ext/json/lib/json/common.rb =================================================================== --- ext/json/lib/json/common.rb (revision 43730) +++ ext/json/lib/json/common.rb (revision 43731) @@ -179,10 +179,9 @@ module JSON https://github.com/ruby/ruby/blob/trunk/ext/json/lib/json/common.rb#L179 end # Generate a JSON document from the Ruby data structure _obj_ and return - # it. _state_ is - # * a JSON::State object, + # it. _state_ is * a JSON::State object, # * or a Hash like object (responding to to_hash), - # * or an object convertible into a hash by a to_h method, + # * an object convertible into a hash by a to_h method, # that is used as or to configure a State object. # # It defaults to a state object, that creates the shortest possible JSON text @@ -413,10 +412,7 @@ module JSON https://github.com/ruby/ruby/blob/trunk/ext/json/lib/json/common.rb#L412 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) Index: ext/json/parser/depend =================================================================== --- ext/json/parser/depend (revision 43730) +++ ext/json/parser/depend (revision 43731) @@ -1,3 +1 @@ -parser.o: parser.c parser.rl $(HDRS) $(ruby_headers) $(srcdir)/../fbuffer/fbuffer.h \ - $(hdrdir)/ruby/encoding.h \ - $(hdrdir)/ruby/oniguruma.h \ +parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h Index: test/json/test_json_generate.rb =================================================================== --- test/json/test_json_generate.rb (revision 43730) +++ test/json/test_json_generate.rb (revision 43731) @@ -3,7 +3,6 @@ https://github.com/ruby/ruby/blob/trunk/test/json/test_json_generate.rb#L3 require 'test/unit' require File.join(File.dirname(__FILE__), 'setup_variant') -require_relative '../ruby/envutil.rb' class TestJSONGenerate < Test::Unit::TestCase include JSON @@ -216,14 +215,15 @@ EOT https://github.com/ruby/ruby/blob/trunk/test/json/test_json_generate.rb#L215 end def test_gc - assert_separately %w[-rjson --disable-gems], <<-EOS, timeout: 5 + require_relative '../ruby/envutil.rb' + 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 + raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect end EOS end if GC.respond_to?(:stress=) @@ -252,15 +252,43 @@ EOT https://github.com/ruby/ruby/blob/trunk/test/json/test_json_generate.rb#L252 assert_equal '5', state2.array_nl end - def test_broken_bignum # [ruby-core:38867] - assert_separately %w[-rjson --disable-gems], <<-EOS, timeout: 5 - Bignum.class_eval do - def to_s + 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 + Bignum.class_eval do + def to_s + end + end + begin + JSON::Ext::Generator::State.new.generate(1<<64) + exit 1 + rescue TypeError + exit 0 end end - assert_raise(TypeError){ JSON::Ext::Generator::State.new.generate(1<<64) } - EOS - end if defined?(JSON::Ext::Generator) + _, status = Process.waitpid2(pid) + assert status.success? + rescue NotImplementedError + # forking to avoid modifying core class of a parent process and + # introducing race conditions of tests are run in parallel + end + end def test_hash_likeness_set_symbol state = JSON.state.new @@ -286,4 +314,10 @@ EOT https://github.com/ruby/ruby/blob/trunk/test/json/test_json_generate.rb#L314 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 Index: test/json/test_json_generic_object.rb =================================================================== --- test/json/test_json_generic_object.rb (revision 43730) +++ test/json/test_json_generic_object.rb (revision 43731) @@ -49,6 +49,21 @@ class TestJSONGenericObject < Test::Unit https://github.com/ruby/ruby/blob/trunk/test/json/test_json_generic_object.rb#L49 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 = '{"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(json), JSON('{"json_class":"JSON::GenericObject","hello":"world"}') + end + private def switch_json_creatable -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/