From 5a00be2bf75939fd3bb05dabbdf46244eaa6bb43 Mon Sep 17 00:00:00 2001 From: naruse Date: Mon, 7 May 2012 16:00:49 +0000 Subject: * ext/json: Merge JSON 1.7.1. https://github.com/flori/json/commit/e5b9a9465c1159fae533bca320d950b772bcb4ac git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35568 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/json/fbuffer/fbuffer.h | 13 ++++++++++--- ext/json/generator/depend | 2 +- ext/json/generator/extconf.rb | 1 + ext/json/generator/generator.c | 26 +++++++++++++++++--------- ext/json/generator/generator.h | 2 +- ext/json/lib/json/common.rb | 1 + ext/json/lib/json/version.rb | 2 +- ext/json/parser/depend | 2 +- ext/json/parser/parser.c | 35 ++++++++++++++++++----------------- ext/json/parser/parser.rl | 1 + 10 files changed, 52 insertions(+), 33 deletions(-) (limited to 'ext/json') diff --git a/ext/json/fbuffer/fbuffer.h b/ext/json/fbuffer/fbuffer.h index 47e0c07004..f7c2b034b7 100644 --- a/ext/json/fbuffer/fbuffer.h +++ b/ext/json/fbuffer/fbuffer.h @@ -35,10 +35,14 @@ static FBuffer *fbuffer_alloc(unsigned long initial_length); static void fbuffer_free(FBuffer *fb); static void fbuffer_clear(FBuffer *fb); static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len); +#ifdef JSON_GENERATOR static void fbuffer_append_long(FBuffer *fb, long number); +#endif static void fbuffer_append_char(FBuffer *fb, char newchr); +#ifdef JSON_GENERATOR static FBuffer *fbuffer_dup(FBuffer *fb); static VALUE fbuffer_to_s(FBuffer *fb); +#endif static FBuffer *fbuffer_alloc(unsigned long initial_length) { @@ -68,7 +72,6 @@ static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested) if (!fb->ptr) { fb->ptr = ALLOC_N(char, fb->initial_length); fb->capa = fb->initial_length; - fb->len = 0; } for (required = fb->capa; requested > required - fb->len; required <<= 1); @@ -88,15 +91,17 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len) } } +#ifdef JSON_GENERATOR 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 static void fbuffer_append_char(FBuffer *fb, char newchr) { @@ -105,6 +110,7 @@ static void fbuffer_append_char(FBuffer *fb, char newchr) fb->len++; } +#ifdef JSON_GENERATOR static void freverse(char *start, char *end) { char c; @@ -155,3 +161,4 @@ static VALUE fbuffer_to_s(FBuffer *fb) return result; } #endif +#endif diff --git a/ext/json/generator/depend b/ext/json/generator/depend index bb76ad6400..1a042a2501 100644 --- a/ext/json/generator/depend +++ b/ext/json/generator/depend @@ -1 +1 @@ -generator.o: generator.c generator.h +generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h diff --git a/ext/json/generator/extconf.rb b/ext/json/generator/extconf.rb index 75c76ce15b..8627c5f4bd 100644 --- a/ext/json/generator/extconf.rb +++ b/ext/json/generator/extconf.rb @@ -1,3 +1,4 @@ require 'mkmf' +$defs << "-DJSON_GENERATOR" create_makefile 'json/ext/generator' diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 6eea7ff148..b1babb15f3 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -762,7 +762,6 @@ static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_S { VALUE tmp = rb_funcall(obj, i_to_s, 0); fbuffer_append_str(buffer, tmp); - RB_GC_GUARD(tmp); } static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) @@ -853,6 +852,21 @@ 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(*p); p++); + for (; q > p && isspace(*q); q--); + return *p == '[' && *q == ']' || *p == '{' && *q == '}'; +} + /* * call-seq: generate(obj) * @@ -863,15 +877,9 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj) static VALUE cState_generate(VALUE self, VALUE obj) { VALUE result = cState_partial_generate(self, obj); - VALUE re, args[2]; GET_STATE(self); - if (!state->quirks_mode) { - args[0] = rb_str_new2("\\A\\s*(?:\\[.*\\]|\\{.*\\})\\s*\\Z"); - args[1] = CRegexp_MULTILINE; - re = rb_class_new_instance(2, args, rb_cRegexp); - if (NIL_P(rb_funcall(re, i_match, 1, result))) { - rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed"); - } + if (!state->quirks_mode && !isArrayOrObject(result)) { + rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed"); } return result; } diff --git a/ext/json/generator/generator.h b/ext/json/generator/generator.h index 4958cf094d..901b62c251 100644 --- a/ext/json/generator/generator.h +++ b/ext/json/generator/generator.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "ruby.h" @@ -105,7 +106,6 @@ typedef struct JSON_Generator_StateStruct { Data_Get_Struct(Vstate, JSON_Generator_State, state); \ buffer = cState_prepare_buffer(Vstate); \ generate_json_##type(buffer, Vstate, state, self); \ - RB_GC_GUARD(Vstate); \ return fbuffer_to_s(buffer) static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self); diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb index cf7a8b9003..a30e4ce136 100644 --- a/ext/json/lib/json/common.rb +++ b/ext/json/lib/json/common.rb @@ -1,4 +1,5 @@ require 'json/version' +require 'json/generic_object' module JSON class << self diff --git a/ext/json/lib/json/version.rb b/ext/json/lib/json/version.rb index 63ebcf3195..b1cf47f295 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.6.6' + VERSION = '1.7.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 5eaf6dd040..498ffa964c 100644 --- a/ext/json/parser/depend +++ b/ext/json/parser/depend @@ -1 +1 @@ -parser.o: parser.c parser.h +parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c index d4adb8e620..c140fdb2fe 100644 --- a/ext/json/parser/parser.c +++ b/ext/json/parser/parser.c @@ -1721,6 +1721,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) source = convert_encoding(StringValue(source)); } json->current_nesting = 0; + StringValue(source); json->len = RSTRING_LEN(source); json->source = RSTRING_PTR(source);; json->Vsource = source; @@ -1728,7 +1729,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1732 "parser.c" +#line 1733 "parser.c" static const int JSON_start = 1; static const int JSON_first_final = 10; static const int JSON_error = 0; @@ -1736,7 +1737,7 @@ static const int JSON_error = 0; static const int JSON_en_main = 1; -#line 739 "parser.rl" +#line 740 "parser.rl" static VALUE cParser_parse_strict(VALUE self) @@ -1747,16 +1748,16 @@ static VALUE cParser_parse_strict(VALUE self) GET_PARSER; -#line 1751 "parser.c" +#line 1752 "parser.c" { cs = JSON_start; } -#line 749 "parser.rl" +#line 750 "parser.rl" p = json->source; pe = p + json->len; -#line 1760 "parser.c" +#line 1761 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1812,7 +1813,7 @@ case 5: goto st1; goto st5; tr3: -#line 728 "parser.rl" +#line 729 "parser.rl" { char *np; json->current_nesting = 1; @@ -1821,7 +1822,7 @@ tr3: } goto st10; tr4: -#line 721 "parser.rl" +#line 722 "parser.rl" { char *np; json->current_nesting = 1; @@ -1833,7 +1834,7 @@ st10: if ( ++p == pe ) goto _test_eof10; case 10: -#line 1837 "parser.c" +#line 1838 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1890,7 +1891,7 @@ case 9: _out: {} } -#line 752 "parser.rl" +#line 753 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -1902,7 +1903,7 @@ case 9: -#line 1906 "parser.c" +#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; @@ -1910,7 +1911,7 @@ static const int JSON_quirks_mode_error = 0; static const int JSON_quirks_mode_en_main = 1; -#line 777 "parser.rl" +#line 778 "parser.rl" static VALUE cParser_parse_quirks_mode(VALUE self) @@ -1921,16 +1922,16 @@ static VALUE cParser_parse_quirks_mode(VALUE self) GET_PARSER; -#line 1925 "parser.c" +#line 1926 "parser.c" { cs = JSON_quirks_mode_start; } -#line 787 "parser.rl" +#line 788 "parser.rl" p = json->source; pe = p + json->len; -#line 1934 "parser.c" +#line 1935 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1964,7 +1965,7 @@ st0: cs = 0; goto _out; tr2: -#line 769 "parser.rl" +#line 770 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1974,7 +1975,7 @@ st10: if ( ++p == pe ) goto _test_eof10; case 10: -#line 1978 "parser.c" +#line 1979 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2063,7 +2064,7 @@ case 9: _out: {} } -#line 790 "parser.rl" +#line 791 "parser.rl" if (cs >= JSON_quirks_mode_first_final && p == pe) { return result; diff --git a/ext/json/parser/parser.rl b/ext/json/parser/parser.rl index c96b0a8225..20ecc486e1 100644 --- a/ext/json/parser/parser.rl +++ b/ext/json/parser/parser.rl @@ -705,6 +705,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) source = convert_encoding(StringValue(source)); } json->current_nesting = 0; + StringValue(source); json->len = RSTRING_LEN(source); json->source = RSTRING_PTR(source);; json->Vsource = source; -- cgit v1.2.3