aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--ext/json/fbuffer/fbuffer.h6
-rw-r--r--ext/json/generator/depend6
-rw-r--r--ext/json/generator/generator.c30
-rw-r--r--ext/json/lib/json/add/range.rb2
-rw-r--r--ext/json/lib/json/common.rb10
-rw-r--r--ext/json/lib/json/generic_object.rb9
-rw-r--r--ext/json/lib/json/version.rb2
-rw-r--r--ext/json/parser/depend4
-rwxr-xr-xtest/json/test_json_generate.rb54
-rw-r--r--test/json/test_json_generic_object.rb15
11 files changed, 112 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index 815d8aa611..925fb581c5 100644
--- a/ChangeLog
+++ b/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>
* lib/rdoc/constant.rb (RDoc::Constant#documented?): workaround for
diff --git a/ext/json/fbuffer/fbuffer.h b/ext/json/fbuffer/fbuffer.h
index 952ab30fa6..af74187566 100644
--- a/ext/json/fbuffer/fbuffer.h
+++ b/ext/json/fbuffer/fbuffer.h
@@ -67,7 +67,7 @@ static VALUE fbuffer_to_s(FBuffer *fb);
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 *fb, VALUE str)
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
diff --git a/ext/json/generator/depend b/ext/json/generator/depend
index 82946d1097..1a042a2501 100644
--- a/ext/json/generator/depend
+++ b/ext/json/generator/depend
@@ -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
diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c
index 40c9e1e6df..ed7bb82887 100644
--- a/ext/json/generator/generator.c
+++ b/ext/json/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;
}
@@ -288,7 +299,7 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
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, 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)) {
@@ -1178,11 +1186,11 @@ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
/*
- * 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);
diff --git a/ext/json/lib/json/add/range.rb b/ext/json/lib/json/add/range.rb
index d2a5b335e0..e61e553cdb 100644
--- a/ext/json/lib/json/add/range.rb
+++ b/ext/json/lib/json/add/range.rb
@@ -16,7 +16,7 @@ class Range
def as_json(*)
{
JSON.create_id => self.class.name,
- 'a' => [ first, self.end, exclude_end? ]
+ 'a' => [ first, last, exclude_end? ]
}
end
diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb
index a547679962..e24f637f61 100644
--- a/ext/json/lib/json/common.rb
+++ b/ext/json/lib/json/common.rb
@@ -179,10 +179,9 @@ module JSON
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
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)
diff --git a/ext/json/lib/json/generic_object.rb b/ext/json/lib/json/generic_object.rb
index 8b1074c941..8b8fd53bef 100644
--- a/ext/json/lib/json/generic_object.rb
+++ b/ext/json/lib/json/generic_object.rb
@@ -31,6 +31,15 @@ module JSON
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/ext/json/lib/json/version.rb b/ext/json/lib/json/version.rb
index 1de3d696f2..47cdcd607c 100644
--- a/ext/json/lib/json/version.rb
+++ b/ext/json/lib/json/version.rb
@@ -1,6 +1,6 @@
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:
diff --git a/ext/json/parser/depend b/ext/json/parser/depend
index 748b4213ae..498ffa964c 100644
--- a/ext/json/parser/depend
+++ b/ext/json/parser/depend
@@ -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
diff --git a/test/json/test_json_generate.rb b/test/json/test_json_generate.rb
index 5c1042d956..618b933bac 100755
--- a/test/json/test_json_generate.rb
+++ b/test/json/test_json_generate.rb
@@ -3,7 +3,6 @@
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
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
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
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
diff --git a/test/json/test_json_generic_object.rb b/test/json/test_json_generic_object.rb
index 77ef22e6ae..c43c7762be 100644
--- a/test/json/test_json_generic_object.rb
+++ b/test/json/test_json_generic_object.rb
@@ -49,6 +49,21 @@ class TestJSONGenericObject < Test::Unit::TestCase
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