diff options
Diffstat (limited to 'ext/json/ext')
-rw-r--r-- | ext/json/ext/generator/generator.c | 71 | ||||
-rw-r--r-- | ext/json/ext/parser/parser.c | 205 | ||||
-rw-r--r-- | ext/json/ext/parser/parser.rl | 30 |
3 files changed, 212 insertions, 94 deletions
diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 1f48d3c780..108e80fd65 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -1,8 +1,33 @@ #include <string.h> #include "ruby.h" +#if HAVE_RUBY_ST_H +#include "ruby/st.h" +#endif +#if HAVE_ST_H +#include "st.h" +#endif #include "unicode.h" #include <math.h> +#ifndef RHASH_TBL +#define RHASH_TBL(hsh) (RHASH(hsh)->tbl) +#endif + +#ifndef RHASH_SIZE +#define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries) +#endif + +#ifndef RFLOAT_VALUE +#define RFLOAT_VALUE(val) (RFLOAT(val)->value) +#endif + +#ifdef HAVE_RUBY_ENCODING_H +#include "ruby/encoding.h" +#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding()) +#else +#define FORCE_UTF8(obj) +#endif + #define check_max_nesting(state, depth) do { \ long current_nesting = 1 + depth; \ if (state->max_nesting != 0 && current_nesting > state->max_nesting) \ @@ -163,6 +188,7 @@ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self) } } OBJ_INFECT(result, self); + FORCE_UTF8(result); return result; } @@ -260,6 +286,7 @@ static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) { result = mArray_json_transfrom(self, Vstate, Vdepth); } OBJ_INFECT(result, self); + FORCE_UTF8(result); return result; } @@ -270,7 +297,9 @@ static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) { */ static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self) { - return rb_funcall(self, i_to_s, 0); + VALUE result = rb_funcall(self, i_to_s, 0); + FORCE_UTF8(result); + return result; } /* @@ -281,27 +310,29 @@ static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self) static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self) { JSON_Generator_State *state = NULL; - VALUE Vstate, rest, tmp; + VALUE Vstate, rest, tmp, result; double value = RFLOAT_VALUE(self); rb_scan_args(argc, argv, "01*", &Vstate, &rest); if (!NIL_P(Vstate)) Data_Get_Struct(Vstate, JSON_Generator_State, state); if (isinf(value)) { if (!state || state->allow_nan) { - return rb_funcall(self, i_to_s, 0); + result = rb_funcall(self, i_to_s, 0); } else { tmp = rb_funcall(self, i_to_s, 0); rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp)); } } else if (isnan(value)) { if (!state || state->allow_nan) { - return rb_funcall(self, i_to_s, 0); + result = rb_funcall(self, i_to_s, 0); } else { tmp = rb_funcall(self, i_to_s, 0); rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp)); } } else { - return rb_funcall(self, i_to_s, 0); + result = rb_funcall(self, i_to_s, 0); } + FORCE_UTF8(result); + return result; } /* @@ -310,7 +341,9 @@ static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self) * Extends _modul_ with the String::Extend module. */ static VALUE mString_included_s(VALUE self, VALUE modul) { - return rb_funcall(modul, i_extend, 1, mString_Extend); + VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend); + FORCE_UTF8(result); + return result; } /* @@ -326,6 +359,7 @@ static VALUE mString_to_json(int argc, VALUE *argv, VALUE self) rb_str_buf_cat2(result, "\""); JSON_convert_UTF8_to_JSON(result, self, strictConversion); rb_str_buf_cat2(result, "\""); + FORCE_UTF8(result); return result; } @@ -343,6 +377,7 @@ static VALUE mString_to_json_raw_object(VALUE self) { rb_hash_aset(result, rb_funcall(mJSON, i_create_id, 0), rb_class_name(rb_obj_class(self))); ary = rb_funcall(self, i_unpack, 1, rb_str_new2("C*")); rb_hash_aset(result, rb_str_new2("raw"), ary); + FORCE_UTF8(result); return result; } @@ -353,9 +388,11 @@ static VALUE mString_to_json_raw_object(VALUE self) { * to_json_raw_object of this String. */ static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self) { - VALUE obj = mString_to_json_raw_object(self); + VALUE result, obj = mString_to_json_raw_object(self); Check_Type(obj, T_HASH); - return mHash_to_json(argc, argv, obj); + result = mHash_to_json(argc, argv, obj); + FORCE_UTF8(result); + return result; } /* @@ -378,7 +415,9 @@ static VALUE mString_Extend_json_create(VALUE self, VALUE o) { */ static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self) { - return rb_str_new2("true"); + VALUE result = rb_str_new2("true"); + FORCE_UTF8(result); + return result; } /* @@ -388,7 +427,9 @@ static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self) */ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self) { - return rb_str_new2("false"); + VALUE result = rb_str_new2("false"); + FORCE_UTF8(result); + return result; } /* @@ -397,7 +438,9 @@ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self) */ static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self) { - return rb_str_new2("null"); + VALUE result = rb_str_new2("null"); + FORCE_UTF8(result); + return result; } /* @@ -409,9 +452,11 @@ static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self) */ static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self) { - VALUE string = rb_funcall(self, i_to_s, 0); + VALUE result, string = rb_funcall(self, i_to_s, 0); Check_Type(string, T_STRING); - return mString_to_json(argc, argv, string); + result = mString_to_json(argc, argv, string); + FORCE_UTF8(result); + return result; } /* diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 9de618d0e6..6928eda9e5 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1,10 +1,30 @@ + #line 1 "parser.rl" #include "ruby.h" -#include "ruby/encoding.h" #include "unicode.h" +#if HAVE_RE_H +#include "re.h" +#endif +#if HAVE_RUBY_ST_H +#include "ruby/st.h" +#endif +#if HAVE_ST_H +#include "st.h" +#endif #define EVIL 0x666 +#ifndef RHASH_TBL +#define RHASH_TBL(hsh) (RHASH(hsh)->tbl) +#endif + +#ifdef HAVE_RUBY_ENCODING_H +#include "ruby/encoding.h" +#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding()) +#else +#define FORCE_UTF8(obj) +#endif + static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static VALUE CNaN, CInfinity, CMinusInfinity; @@ -35,18 +55,20 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul JSON_Parser *json; \ Data_Get_Struct(self, JSON_Parser, json); -#line 64 "parser.rl" +#line 82 "parser.rl" -#line 44 "parser.c" + +#line 64 "parser.c" 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 97 "parser.rl" + +#line 115 "parser.rl" static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -61,13 +83,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = rb_hash_new(); -#line 66 "parser.c" +#line 87 "parser.c" { cs = JSON_object_start; } -#line 111 "parser.rl" + +#line 129 "parser.rl" -#line 72 "parser.c" +#line 94 "parser.c" { if ( p == pe ) goto _test_eof; @@ -95,7 +118,7 @@ case 2: goto st2; goto st0; tr2: -#line 83 "parser.rl" +#line 101 "parser.rl" { char *np = JSON_parse_string(json, p, pe, &last_name); if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;} @@ -105,7 +128,7 @@ st3: if ( ++p == pe ) goto _test_eof3; case 3: -#line 110 "parser.c" +#line 132 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -172,7 +195,7 @@ case 8: goto st8; goto st0; tr11: -#line 72 "parser.rl" +#line 90 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v); @@ -188,7 +211,7 @@ st9: if ( ++p == pe ) goto _test_eof9; case 9: -#line 193 "parser.c" +#line 215 "parser.c" switch( (*p) ) { case 13: goto st9; case 32: goto st9; @@ -277,14 +300,14 @@ case 18: goto st9; goto st18; tr4: -#line 88 "parser.rl" +#line 106 "parser.rl" { p--; {p++; cs = 27; goto _out;} } goto st27; st27: if ( ++p == pe ) goto _test_eof27; case 27: -#line 289 "parser.c" +#line 311 "parser.c" goto st0; st19: if ( ++p == pe ) @@ -381,7 +404,8 @@ case 26: _test_eof: {} _out: {} } -#line 112 "parser.rl" + +#line 130 "parser.rl" if (cs >= JSON_object_first_final) { if (RTEST(json->create_id)) { @@ -400,14 +424,15 @@ case 26: } -#line 405 "parser.c" +#line 428 "parser.c" static const int JSON_value_start = 1; static const int JSON_value_first_final = 21; static const int JSON_value_error = 0; static const int JSON_value_en_main = 1; -#line 210 "parser.rl" + +#line 228 "parser.rl" static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -415,13 +440,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 420 "parser.c" +#line 444 "parser.c" { cs = JSON_value_start; } -#line 217 "parser.rl" + +#line 235 "parser.rl" -#line 426 "parser.c" +#line 451 "parser.c" { if ( p == pe ) goto _test_eof; @@ -446,14 +472,14 @@ st0: cs = 0; goto _out; tr0: -#line 158 "parser.rl" +#line 176 "parser.rl" { char *np = JSON_parse_string(json, p, pe, result); if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;} } goto st21; tr2: -#line 163 "parser.rl" +#line 181 "parser.rl" { char *np; if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) { @@ -473,7 +499,7 @@ tr2: } goto st21; tr5: -#line 181 "parser.rl" +#line 199 "parser.rl" { char *np; json->current_nesting++; @@ -483,7 +509,7 @@ tr5: } goto st21; tr9: -#line 189 "parser.rl" +#line 207 "parser.rl" { char *np; json->current_nesting++; @@ -493,7 +519,7 @@ tr9: } goto st21; tr16: -#line 151 "parser.rl" +#line 169 "parser.rl" { if (json->allow_nan) { *result = CInfinity; @@ -503,7 +529,7 @@ tr16: } goto st21; tr18: -#line 144 "parser.rl" +#line 162 "parser.rl" { if (json->allow_nan) { *result = CNaN; @@ -513,19 +539,19 @@ tr18: } goto st21; tr22: -#line 138 "parser.rl" +#line 156 "parser.rl" { *result = Qfalse; } goto st21; tr25: -#line 135 "parser.rl" +#line 153 "parser.rl" { *result = Qnil; } goto st21; tr28: -#line 141 "parser.rl" +#line 159 "parser.rl" { *result = Qtrue; } @@ -534,9 +560,9 @@ st21: if ( ++p == pe ) goto _test_eof21; case 21: -#line 197 "parser.rl" +#line 215 "parser.rl" { p--; {p++; cs = 21; goto _out;} } -#line 541 "parser.c" +#line 566 "parser.c" goto st0; st2: if ( ++p == pe ) @@ -696,7 +722,8 @@ case 20: _test_eof: {} _out: {} } -#line 218 "parser.rl" + +#line 236 "parser.rl" if (cs >= JSON_value_first_final) { return p; @@ -706,14 +733,15 @@ case 20: } -#line 711 "parser.c" +#line 737 "parser.c" static const int JSON_integer_start = 1; static const int JSON_integer_first_final = 5; static const int JSON_integer_error = 0; static const int JSON_integer_en_main = 1; -#line 234 "parser.rl" + +#line 252 "parser.rl" static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -721,14 +749,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res int cs = EVIL; -#line 726 "parser.c" +#line 753 "parser.c" { cs = JSON_integer_start; } -#line 241 "parser.rl" + +#line 259 "parser.rl" json->memo = p; -#line 733 "parser.c" +#line 761 "parser.c" { if ( p == pe ) goto _test_eof; @@ -762,14 +791,14 @@ case 3: goto st0; goto tr4; tr4: -#line 231 "parser.rl" +#line 249 "parser.rl" { p--; {p++; cs = 5; goto _out;} } goto st5; st5: if ( ++p == pe ) goto _test_eof5; case 5: -#line 774 "parser.c" +#line 802 "parser.c" goto st0; st4: if ( ++p == pe ) @@ -787,7 +816,8 @@ case 4: _test_eof: {} _out: {} } -#line 243 "parser.rl" + +#line 261 "parser.rl" if (cs >= JSON_integer_first_final) { long len = p - json->memo; @@ -799,14 +829,15 @@ case 4: } -#line 804 "parser.c" +#line 833 "parser.c" static const int JSON_float_start = 1; static const int JSON_float_first_final = 10; static const int JSON_float_error = 0; static const int JSON_float_en_main = 1; -#line 265 "parser.rl" + +#line 283 "parser.rl" static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -814,14 +845,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 819 "parser.c" +#line 849 "parser.c" { cs = JSON_float_start; } -#line 272 "parser.rl" + +#line 290 "parser.rl" json->memo = p; -#line 826 "parser.c" +#line 857 "parser.c" { if ( p == pe ) goto _test_eof; @@ -879,14 +911,14 @@ case 5: goto st0; goto tr7; tr7: -#line 259 "parser.rl" +#line 277 "parser.rl" { p--; {p++; cs = 10; goto _out;} } goto st10; st10: if ( ++p == pe ) goto _test_eof10; case 10: -#line 891 "parser.c" +#line 922 "parser.c" goto st0; st6: if ( ++p == pe ) @@ -946,7 +978,8 @@ case 9: _test_eof: {} _out: {} } -#line 274 "parser.rl" + +#line 292 "parser.rl" if (cs >= JSON_float_first_final) { long len = p - json->memo; @@ -959,14 +992,15 @@ case 9: -#line 964 "parser.c" +#line 996 "parser.c" 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 310 "parser.rl" + +#line 328 "parser.rl" static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -979,13 +1013,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul *result = rb_ary_new(); -#line 984 "parser.c" +#line 1017 "parser.c" { cs = JSON_array_start; } -#line 322 "parser.rl" + +#line 340 "parser.rl" -#line 990 "parser.c" +#line 1024 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1024,7 +1059,7 @@ case 2: goto st2; goto st0; tr2: -#line 291 "parser.rl" +#line 309 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v); @@ -1040,7 +1075,7 @@ st3: if ( ++p == pe ) goto _test_eof3; case 3: -#line 1045 "parser.c" +#line 1079 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -1140,14 +1175,14 @@ case 12: goto st3; goto st12; tr4: -#line 302 "parser.rl" +#line 320 "parser.rl" { p--; {p++; cs = 17; goto _out;} } goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: -#line 1152 "parser.c" +#line 1186 "parser.c" goto st0; st13: if ( ++p == pe ) @@ -1202,7 +1237,8 @@ case 16: _test_eof: {} _out: {} } -#line 323 "parser.rl" + +#line 341 "parser.rl" if(cs >= JSON_array_first_final) { return p + 1; @@ -1268,14 +1304,15 @@ static VALUE json_string_unescape(char *p, char *pe) } -#line 1273 "parser.c" +#line 1308 "parser.c" 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 401 "parser.rl" + +#line 425 "parser.rl" static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -1284,14 +1321,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = rb_str_new("", 0); -#line 1289 "parser.c" +#line 1325 "parser.c" { cs = JSON_string_start; } -#line 409 "parser.rl" + +#line 433 "parser.rl" json->memo = p; -#line 1296 "parser.c" +#line 1333 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1316,19 +1354,25 @@ case 2: goto st0; goto st2; tr2: -#line 393 "parser.rl" +#line 411 "parser.rl" { *result = json_string_unescape(json->memo + 1, p); - if (NIL_P(*result)) { p--; {p++; cs = 8; goto _out;} } else {p = (( p + 1))-1;} - } -#line 398 "parser.rl" + if (NIL_P(*result)) { + p--; + {p++; cs = 8; goto _out;} + } else { + FORCE_UTF8(*result); + {p = (( p + 1))-1;} + } + } +#line 422 "parser.rl" { p--; {p++; cs = 8; goto _out;} } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: -#line 1333 "parser.c" +#line 1376 "parser.c" goto st0; st3: if ( ++p == pe ) @@ -1403,11 +1447,11 @@ case 7: _test_eof: {} _out: {} } -#line 411 "parser.rl" + +#line 435 "parser.rl" if (cs >= JSON_string_first_final) { - rb_enc_associate(*result, rb_utf8_encoding()); - return p + 1; + return p + 1; } else { return NULL; } @@ -1415,14 +1459,15 @@ case 7: -#line 1419 "parser.c" +#line 1463 "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 445 "parser.rl" + +#line 469 "parser.rl" /* @@ -1545,15 +1590,16 @@ static VALUE cParser_parse(VALUE self) GET_STRUCT; -#line 1549 "parser.c" +#line 1594 "parser.c" { cs = JSON_start; } -#line 567 "parser.rl" + +#line 591 "parser.rl" p = json->source; pe = p + json->len; -#line 1557 "parser.c" +#line 1603 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1609,7 +1655,7 @@ case 5: goto st1; goto st5; tr3: -#line 434 "parser.rl" +#line 458 "parser.rl" { char *np; json->current_nesting = 1; @@ -1618,7 +1664,7 @@ tr3: } goto st10; tr4: -#line 427 "parser.rl" +#line 451 "parser.rl" { char *np; json->current_nesting = 1; @@ -1630,7 +1676,7 @@ st10: if ( ++p == pe ) goto _test_eof10; case 10: -#line 1634 "parser.c" +#line 1680 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -1686,7 +1732,8 @@ case 9: _test_eof: {} _out: {} } -#line 570 "parser.rl" + +#line 594 "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 8325a93795..ca1876a7fc 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -1,8 +1,28 @@ #include "ruby.h" #include "unicode.h" +#if HAVE_RE_H +#include "re.h" +#endif +#if HAVE_RUBY_ST_H +#include "ruby/st.h" +#endif +#if HAVE_ST_H +#include "st.h" +#endif #define EVIL 0x666 +#ifndef RHASH_TBL +#define RHASH_TBL(hsh) (RHASH(hsh)->tbl) +#endif + +#ifdef HAVE_RUBY_ENCODING_H +#include "ruby/encoding.h" +#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding()) +#else +#define FORCE_UTF8(obj) +#endif + static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static VALUE CNaN, CInfinity, CMinusInfinity; @@ -390,8 +410,14 @@ static VALUE json_string_unescape(char *p, char *pe) action parse_string { *result = json_string_unescape(json->memo + 1, p); - if (NIL_P(*result)) { fhold; fbreak; } else fexec p + 1; - } + if (NIL_P(*result)) { + fhold; + fbreak; + } else { + FORCE_UTF8(*result); + fexec p + 1; + } + } action exit { fhold; fbreak; } |