* ext/json: merge JSON 1.8.1.
002ac2771c...e09ffc0d7d
* Remove Rubinius exception since transcoding should be working now.
* Fix https://github.com/flori/json/issues/162 reported by Marc-Andre
Lafortune <github_rocks@marc-andre.ca>. Thanks!
* Applied patches by Yui NARUSE <naruse@airemix.jp> 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.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43731 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9d740ddebe
commit
14cab32596
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
Wed Nov 20 11:46:38 2013 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
|
* 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@marc-andre.ca>. Thanks!
|
||||||
|
* Applied patches by Yui NARUSE <naruse@airemix.jp> 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@ruby-lang.org>
|
Wed Nov 20 01:39:02 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* lib/rdoc/constant.rb (RDoc::Constant#documented?): workaround for
|
* lib/rdoc/constant.rb (RDoc::Constant#documented?): workaround for
|
||||||
|
@ -67,7 +67,7 @@ static VALUE fbuffer_to_s(FBuffer *fb);
|
|||||||
static FBuffer *fbuffer_alloc(unsigned long initial_length)
|
static FBuffer *fbuffer_alloc(unsigned long initial_length)
|
||||||
{
|
{
|
||||||
FBuffer *fb;
|
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);
|
fb = ALLOC(FBuffer);
|
||||||
memset((void *) fb, 0, sizeof(FBuffer));
|
memset((void *) fb, 0, sizeof(FBuffer));
|
||||||
fb->initial_length = initial_length;
|
fb->initial_length = initial_length;
|
||||||
@ -117,9 +117,9 @@ static void fbuffer_append_str(FBuffer *fb, VALUE str)
|
|||||||
const char *newstr = StringValuePtr(str);
|
const char *newstr = StringValuePtr(str);
|
||||||
unsigned long len = RSTRING_LEN(str);
|
unsigned long len = RSTRING_LEN(str);
|
||||||
|
|
||||||
fbuffer_append(fb, newstr, len);
|
|
||||||
|
|
||||||
RB_GC_GUARD(str);
|
RB_GC_GUARD(str);
|
||||||
|
|
||||||
|
fbuffer_append(fb, newstr, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,5 +1 @@
|
|||||||
generator.o: generator.c $(HDRS) $(ruby_headers) $(srcdir)/../fbuffer/fbuffer.h \
|
generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h
|
||||||
$(hdrdir)/ruby/encoding.h \
|
|
||||||
$(hdrdir)/ruby/oniguruma.h \
|
|
||||||
$(hdrdir)/ruby/re.h \
|
|
||||||
$(hdrdir)/ruby/regex.h \
|
|
||||||
|
@ -273,7 +273,18 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
|
|||||||
escape_len = 2;
|
escape_len = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -288,7 +299,7 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
|
|||||||
|
|
||||||
static char *fstrndup(const char *ptr, unsigned long len) {
|
static char *fstrndup(const char *ptr, unsigned long len) {
|
||||||
char *result;
|
char *result;
|
||||||
if (len == 0) return NULL;
|
if (len <= 0) return NULL;
|
||||||
result = ALLOC_N(char, len);
|
result = ALLOC_N(char, len);
|
||||||
memccpy(result, ptr, 0, len);
|
memccpy(result, ptr, 0, len);
|
||||||
return result;
|
return result;
|
||||||
@ -511,11 +522,8 @@ static VALUE cState_configure(VALUE self, VALUE opts)
|
|||||||
{
|
{
|
||||||
VALUE tmp;
|
VALUE tmp;
|
||||||
GET_STATE(self);
|
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)) 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;
|
opts = tmp;
|
||||||
tmp = rb_hash_aref(opts, ID2SYM(i_indent));
|
tmp = rb_hash_aref(opts, ID2SYM(i_indent));
|
||||||
if (RTEST(tmp)) {
|
if (RTEST(tmp)) {
|
||||||
@ -1178,11 +1186,11 @@ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq: check_circular?
|
* call-seq: check_circular?
|
||||||
*
|
*
|
||||||
* Returns true, if circular data structures should be checked,
|
* Returns true, if circular data structures should be checked,
|
||||||
* otherwise returns false.
|
* otherwise returns false.
|
||||||
*/
|
*/
|
||||||
static VALUE cState_check_circular_p(VALUE self)
|
static VALUE cState_check_circular_p(VALUE self)
|
||||||
{
|
{
|
||||||
GET_STATE(self);
|
GET_STATE(self);
|
||||||
|
@ -16,7 +16,7 @@ class Range
|
|||||||
def as_json(*)
|
def as_json(*)
|
||||||
{
|
{
|
||||||
JSON.create_id => self.class.name,
|
JSON.create_id => self.class.name,
|
||||||
'a' => [ first, self.end, exclude_end? ]
|
'a' => [ first, last, exclude_end? ]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -179,10 +179,9 @@ module JSON
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Generate a JSON document from the Ruby data structure _obj_ and return
|
# Generate a JSON document from the Ruby data structure _obj_ and return
|
||||||
# it. _state_ is
|
# it. _state_ is * a JSON::State object,
|
||||||
# * a JSON::State object,
|
|
||||||
# * or a Hash like object (responding to to_hash),
|
# * 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.
|
# that is used as or to configure a State object.
|
||||||
#
|
#
|
||||||
# It defaults to a state object, that creates the shortest possible JSON text
|
# It defaults to a state object, that creates the shortest possible JSON text
|
||||||
@ -413,10 +412,7 @@ module JSON
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Shortuct for iconv.
|
# Shortuct for iconv.
|
||||||
if ::String.method_defined?(:encode) &&
|
if ::String.method_defined?(:encode)
|
||||||
# XXX Rubinius doesn't support ruby 1.9 encoding yet
|
|
||||||
defined?(RUBY_ENGINE) && RUBY_ENGINE != 'rbx'
|
|
||||||
then
|
|
||||||
# Encodes string using Ruby's _String.encode_
|
# Encodes string using Ruby's _String.encode_
|
||||||
def self.iconv(to, from, string)
|
def self.iconv(to, from, string)
|
||||||
string.encode(to, from)
|
string.encode(to, from)
|
||||||
|
@ -31,6 +31,15 @@ module JSON
|
|||||||
object
|
object
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
self.json_creatable = false
|
self.json_creatable = false
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
module JSON
|
module JSON
|
||||||
# JSON version
|
# JSON version
|
||||||
VERSION = '1.7.7'
|
VERSION = '1.8.1'
|
||||||
VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
|
VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
|
||||||
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
|
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
|
||||||
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
|
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
|
||||||
|
@ -1,3 +1 @@
|
|||||||
parser.o: parser.c parser.rl $(HDRS) $(ruby_headers) $(srcdir)/../fbuffer/fbuffer.h \
|
parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h
|
||||||
$(hdrdir)/ruby/encoding.h \
|
|
||||||
$(hdrdir)/ruby/oniguruma.h \
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
require 'test/unit'
|
require 'test/unit'
|
||||||
require File.join(File.dirname(__FILE__), 'setup_variant')
|
require File.join(File.dirname(__FILE__), 'setup_variant')
|
||||||
require_relative '../ruby/envutil.rb'
|
|
||||||
|
|
||||||
class TestJSONGenerate < Test::Unit::TestCase
|
class TestJSONGenerate < Test::Unit::TestCase
|
||||||
include JSON
|
include JSON
|
||||||
@ -216,14 +215,15 @@ EOT
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_gc
|
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
|
bignum_too_long_to_embed_as_string = 1234567890123456789012345
|
||||||
expect = bignum_too_long_to_embed_as_string.to_s
|
expect = bignum_too_long_to_embed_as_string.to_s
|
||||||
GC.stress = true
|
GC.stress = true
|
||||||
|
|
||||||
10.times do |i|
|
10.times do |i|
|
||||||
tmp = bignum_too_long_to_embed_as_string.to_json
|
tmp = bignum_too_long_to_embed_as_string.to_json
|
||||||
assert_equal expect, tmp
|
raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect
|
||||||
end
|
end
|
||||||
EOS
|
EOS
|
||||||
end if GC.respond_to?(:stress=)
|
end if GC.respond_to?(:stress=)
|
||||||
@ -252,15 +252,43 @@ EOT
|
|||||||
assert_equal '5', state2.array_nl
|
assert_equal '5', state2.array_nl
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_broken_bignum # [ruby-core:38867]
|
def test_configure_hash_conversion
|
||||||
assert_separately %w[-rjson --disable-gems], <<-EOS, timeout: 5
|
state = JSON.state.new
|
||||||
Bignum.class_eval do
|
state.configure(:indent => '1')
|
||||||
def to_s
|
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
|
||||||
end
|
end
|
||||||
assert_raise(TypeError){ JSON::Ext::Generator::State.new.generate(1<<64) }
|
_, status = Process.waitpid2(pid)
|
||||||
EOS
|
assert status.success?
|
||||||
end if defined?(JSON::Ext::Generator)
|
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
|
def test_hash_likeness_set_symbol
|
||||||
state = JSON.state.new
|
state = JSON.state.new
|
||||||
@ -286,4 +314,10 @@ EOT
|
|||||||
assert_kind_of Hash, state_hash
|
assert_kind_of Hash, state_hash
|
||||||
assert_equal :bar, state_hash[:foo]
|
assert_equal :bar, state_hash[:foo]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_json_generate
|
||||||
|
assert_raise JSON::GeneratorError do
|
||||||
|
assert_equal true, JSON.generate(["\xea"])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -49,6 +49,21 @@ class TestJSONGenericObject < Test::Unit::TestCase
|
|||||||
assert_equal true, GenericObject.from_hash(true)
|
assert_equal true, GenericObject.from_hash(true)
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
def switch_json_creatable
|
def switch_json_creatable
|
||||||
|
Loading…
x
Reference in New Issue
Block a user