json 1.4.4 → 1.4.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of json might be problematic. Click here for more details.

data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ 2010-08-07 (1.4.5)
2
+ * Manage data structure nesting depth in state object during generation. This
3
+ should reduce problems with to_json method definіtions that only have one
4
+ argument.
5
+ * Some fixes in the state objects and additional tests.
1
6
  2010-08-06 (1.4.4)
2
7
  * Fixes build problem for rubinius under OS X, http://github.com/flori/json/issues/closed#issue/25
3
8
  * Fixes crashes described in http://github.com/flori/json/issues/closed#issue/21 and
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.4
1
+ 1.4.5
@@ -14,7 +14,7 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
14
14
  static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
15
15
  i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
16
16
  i_pack, i_unpack, i_create_id, i_extend, i_key_p, i_aref, i_send,
17
- i_respond_to_p, i_match, i_keys;
17
+ i_respond_to_p, i_match, i_keys, i_depth;
18
18
 
19
19
  /*
20
20
  * Copyright 2001-2004 Unicode, Inc.
@@ -417,13 +417,12 @@ static FBuffer *fbuffer_dup(FBuffer *fb)
417
417
  */
418
418
 
419
419
  /*
420
- * call-seq: to_json(state = nil, depth = 0)
420
+ * call-seq: to_json(state = nil)
421
421
  *
422
422
  * Returns a JSON string containing a JSON object, that is generated from
423
423
  * this Hash instance.
424
424
  * _state_ is a JSON::State object, that can also be used to configure the
425
425
  * produced JSON string output further.
426
- * _depth_ is used to find out nesting depth, to indent accordingly.
427
426
  */
428
427
  static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
429
428
  {
@@ -431,13 +430,12 @@ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
431
430
  }
432
431
 
433
432
  /*
434
- * call-seq: to_json(state = nil, depth = 0)
433
+ * call-seq: to_json(state = nil)
435
434
  *
436
435
  * Returns a JSON string containing a JSON array, that is generated from
437
436
  * this Array instance.
438
437
  * _state_ is a JSON::State object, that can also be used to configure the
439
438
  * produced JSON string output further.
440
- * _depth_ is used to find out nesting depth, to indent accordingly.
441
439
  */
442
440
  static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) {
443
441
  GENERATE_JSON(array);
@@ -578,12 +576,12 @@ static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
578
576
  */
579
577
  static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
580
578
  {
581
- VALUE state, depth;
579
+ VALUE state;
582
580
  VALUE string = rb_funcall(self, i_to_s, 0);
583
- rb_scan_args(argc, argv, "02", &state, &depth);
581
+ rb_scan_args(argc, argv, "01", &state);
584
582
  Check_Type(string, T_STRING);
585
583
  state = cState_from_state_s(cState, state);
586
- return cState_partial_generate(state, string, depth);
584
+ return cState_partial_generate(state, string);
587
585
  }
588
586
 
589
587
  static void State_free(JSON_Generator_State *state)
@@ -679,6 +677,17 @@ static VALUE cState_configure(VALUE self, VALUE opts)
679
677
  state->max_nesting = 0;
680
678
  }
681
679
  }
680
+ tmp = ID2SYM(i_depth);
681
+ state->depth = 0;
682
+ if (option_given_p(opts, tmp)) {
683
+ VALUE depth = rb_hash_aref(opts, tmp);
684
+ if (RTEST(depth)) {
685
+ Check_Type(depth, T_FIXNUM);
686
+ state->depth = FIX2LONG(depth);
687
+ } else {
688
+ state->depth = 0;
689
+ }
690
+ }
682
691
  tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan));
683
692
  state->allow_nan = RTEST(tmp);
684
693
  tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
@@ -704,6 +713,7 @@ static VALUE cState_to_h(VALUE self)
704
713
  rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
705
714
  rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
706
715
  rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
716
+ rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
707
717
  return result;
708
718
  }
709
719
 
@@ -722,7 +732,7 @@ static VALUE cState_aref(VALUE self, VALUE name)
722
732
  }
723
733
  }
724
734
 
725
- static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
735
+ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
726
736
  {
727
737
  char *object_nl = state->object_nl;
728
738
  long object_nl_len = state->object_nl_len;
@@ -733,9 +743,9 @@ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
733
743
  long delim_len = FBUFFER_LEN(state->object_delim);
734
744
  char *delim2 = FBUFFER_PTR(state->object_delim2);
735
745
  long delim2_len = FBUFFER_LEN(state->object_delim2);
746
+ long depth = ++state->depth;
736
747
  int i, j;
737
748
  VALUE key, key_to_s, keys;
738
- depth++;
739
749
  if (max_nesting != 0 && depth > max_nesting) {
740
750
  fbuffer_free(buffer);
741
751
  rb_raise(eNestingError, "nesting of %ld is too deep", depth);
@@ -755,11 +765,11 @@ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
755
765
  key = rb_ary_entry(keys, i);
756
766
  key_to_s = rb_funcall(key, i_to_s, 0);
757
767
  Check_Type(key_to_s, T_STRING);
758
- generate_json(buffer, Vstate, state, key_to_s, depth);
768
+ generate_json(buffer, Vstate, state, key_to_s);
759
769
  fbuffer_append(buffer, delim2, delim2_len);
760
- generate_json(buffer, Vstate, state, rb_hash_aref(obj, key), depth);
770
+ generate_json(buffer, Vstate, state, rb_hash_aref(obj, key));
761
771
  }
762
- depth--;
772
+ depth = --state->depth;
763
773
  if (object_nl) {
764
774
  fbuffer_append(buffer, object_nl, object_nl_len);
765
775
  if (indent) {
@@ -771,7 +781,7 @@ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
771
781
  fbuffer_append_char(buffer, '}');
772
782
  }
773
783
 
774
- static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
784
+ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
775
785
  {
776
786
  char *array_nl = state->array_nl;
777
787
  long array_nl_len = state->array_nl_len;
@@ -780,8 +790,8 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
780
790
  long max_nesting = state->max_nesting;
781
791
  char *delim = FBUFFER_PTR(state->array_delim);
782
792
  long delim_len = FBUFFER_LEN(state->array_delim);
793
+ long depth = ++state->depth;
783
794
  int i, j;
784
- depth++;
785
795
  if (max_nesting != 0 && depth > max_nesting) {
786
796
  fbuffer_free(buffer);
787
797
  rb_raise(eNestingError, "nesting of %ld is too deep", depth);
@@ -795,9 +805,9 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
795
805
  fbuffer_append(buffer, indent, indent_len);
796
806
  }
797
807
  }
798
- generate_json(buffer, Vstate, state, rb_ary_entry(obj, i), depth);
808
+ generate_json(buffer, Vstate, state, rb_ary_entry(obj, i));
799
809
  }
800
- depth--;
810
+ state->depth = --depth;
801
811
  if (array_nl) {
802
812
  fbuffer_append(buffer, array_nl, array_nl_len);
803
813
  if (indent) {
@@ -809,7 +819,7 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
809
819
  fbuffer_append_char(buffer, ']');
810
820
  }
811
821
 
812
- static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
822
+ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
813
823
  {
814
824
  fbuffer_append_char(buffer, '"');
815
825
  #ifdef HAVE_RUBY_ENCODING_H
@@ -823,33 +833,33 @@ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
823
833
  fbuffer_append_char(buffer, '"');
824
834
  }
825
835
 
826
- static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
836
+ static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
827
837
  {
828
838
  fbuffer_append(buffer, "null", 4);
829
839
  }
830
840
 
831
- static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
841
+ static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
832
842
  {
833
843
  fbuffer_append(buffer, "false", 5);
834
844
  }
835
845
 
836
- static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
846
+ static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
837
847
  {
838
848
  fbuffer_append(buffer, "true", 4);
839
849
  }
840
850
 
841
- static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
851
+ static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
842
852
  {
843
853
  fbuffer_append_long(buffer, FIX2LONG(obj));
844
854
  }
845
855
 
846
- static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
856
+ static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
847
857
  {
848
858
  VALUE tmp = rb_funcall(obj, i_to_s, 0);
849
859
  fbuffer_append(buffer, RSTRING_PAIR(tmp));
850
860
  }
851
861
 
852
- static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
862
+ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
853
863
  {
854
864
  double value = RFLOAT_VALUE(obj);
855
865
  char allow_nan = state->allow_nan;
@@ -866,36 +876,36 @@ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
866
876
  fbuffer_append(buffer, RSTRING_PAIR(tmp));
867
877
  }
868
878
 
869
- static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
879
+ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
870
880
  {
871
881
  VALUE tmp;
872
882
  VALUE klass = CLASS_OF(obj);
873
883
  if (klass == rb_cHash) {
874
- generate_json_object(buffer, Vstate, state, obj, depth);
884
+ generate_json_object(buffer, Vstate, state, obj);
875
885
  } else if (klass == rb_cArray) {
876
- generate_json_array(buffer, Vstate, state, obj, depth);
886
+ generate_json_array(buffer, Vstate, state, obj);
877
887
  } else if (klass == rb_cString) {
878
- generate_json_string(buffer, Vstate, state, obj, depth);
888
+ generate_json_string(buffer, Vstate, state, obj);
879
889
  } else if (obj == Qnil) {
880
- generate_json_null(buffer, Vstate, state, obj, depth);
890
+ generate_json_null(buffer, Vstate, state, obj);
881
891
  } else if (obj == Qfalse) {
882
- generate_json_false(buffer, Vstate, state, obj, depth);
892
+ generate_json_false(buffer, Vstate, state, obj);
883
893
  } else if (obj == Qtrue) {
884
- generate_json_true(buffer, Vstate, state, obj, depth);
894
+ generate_json_true(buffer, Vstate, state, obj);
885
895
  } else if (klass == rb_cFixnum) {
886
- generate_json_fixnum(buffer, Vstate, state, obj, depth);
896
+ generate_json_fixnum(buffer, Vstate, state, obj);
887
897
  } else if (klass == rb_cBignum) {
888
- generate_json_bignum(buffer, Vstate, state, obj, depth);
898
+ generate_json_bignum(buffer, Vstate, state, obj);
889
899
  } else if (klass == rb_cFloat) {
890
- generate_json_float(buffer, Vstate, state, obj, depth);
900
+ generate_json_float(buffer, Vstate, state, obj);
891
901
  } else if (rb_respond_to(obj, i_to_json)) {
892
- tmp = rb_funcall(obj, i_to_json, 2, Vstate, INT2FIX(depth + 1));
902
+ tmp = rb_funcall(obj, i_to_json, 1, Vstate);
893
903
  Check_Type(tmp, T_STRING);
894
904
  fbuffer_append(buffer, RSTRING_PAIR(tmp));
895
905
  } else {
896
906
  tmp = rb_funcall(obj, i_to_s, 0);
897
907
  Check_Type(tmp, T_STRING);
898
- generate_json(buffer, Vstate, state, tmp, depth + 1);
908
+ generate_json(buffer, Vstate, state, tmp);
899
909
  }
900
910
  }
901
911
 
@@ -936,11 +946,11 @@ static VALUE fbuffer_to_s(FBuffer *fb)
936
946
  return result;
937
947
  }
938
948
 
939
- static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth)
949
+ static VALUE cState_partial_generate(VALUE self, VALUE obj)
940
950
  {
941
951
  FBuffer *buffer = cState_prepare_buffer(self);
942
952
  GET_STATE(self);
943
- generate_json(buffer, self, state, obj, NIL_P(depth) ? 0 : FIX2INT(depth));
953
+ generate_json(buffer, self, state, obj);
944
954
  return fbuffer_to_s(buffer);
945
955
  }
946
956
 
@@ -953,7 +963,7 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth)
953
963
  */
954
964
  static VALUE cState_generate(VALUE self, VALUE obj)
955
965
  {
956
- VALUE result = cState_partial_generate(self, obj, Qnil);
966
+ VALUE result = cState_partial_generate(self, obj);
957
967
  VALUE re, args[2];
958
968
  args[0] = rb_str_new2("\\A\\s*(?:\\[.*\\]|\\{.*\\})\\s*\\Z");
959
969
  args[1] = CRegexp_MULTILINE;
@@ -1055,16 +1065,20 @@ static VALUE cState_indent(VALUE self)
1055
1065
  */
1056
1066
  static VALUE cState_indent_set(VALUE self, VALUE indent)
1057
1067
  {
1068
+ int len;
1058
1069
  GET_STATE(self);
1059
1070
  Check_Type(indent, T_STRING);
1060
- if (RSTRING_LEN(indent) == 0) {
1071
+ len = RSTRING_LEN(indent);
1072
+ if (len == 0) {
1061
1073
  if (state->indent) {
1062
1074
  ruby_xfree(state->indent);
1063
1075
  state->indent = NULL;
1076
+ state->indent_len = 0;
1064
1077
  }
1065
1078
  } else {
1066
1079
  if (state->indent) ruby_xfree(state->indent);
1067
1080
  state->indent = strdup(RSTRING_PTR(indent));
1081
+ state->indent_len = len;
1068
1082
  }
1069
1083
  return Qnil;
1070
1084
  }
@@ -1089,16 +1103,20 @@ static VALUE cState_space(VALUE self)
1089
1103
  */
1090
1104
  static VALUE cState_space_set(VALUE self, VALUE space)
1091
1105
  {
1106
+ int len;
1092
1107
  GET_STATE(self);
1093
1108
  Check_Type(space, T_STRING);
1094
- if (RSTRING_LEN(space) == 0) {
1109
+ len = RSTRING_LEN(space);
1110
+ if (len == 0) {
1095
1111
  if (state->space) {
1096
1112
  ruby_xfree(state->space);
1097
1113
  state->space = NULL;
1114
+ state->space_len = 0;
1098
1115
  }
1099
1116
  } else {
1100
1117
  if (state->space) ruby_xfree(state->space);
1101
1118
  state->space = strdup(RSTRING_PTR(space));
1119
+ state->space_len = len;
1102
1120
  }
1103
1121
  return Qnil;
1104
1122
  }
@@ -1121,16 +1139,20 @@ static VALUE cState_space_before(VALUE self)
1121
1139
  */
1122
1140
  static VALUE cState_space_before_set(VALUE self, VALUE space_before)
1123
1141
  {
1142
+ int len;
1124
1143
  GET_STATE(self);
1125
1144
  Check_Type(space_before, T_STRING);
1126
- if (RSTRING_LEN(space_before) == 0) {
1145
+ len = RSTRING_LEN(space_before);
1146
+ if (len == 0) {
1127
1147
  if (state->space_before) {
1128
1148
  ruby_xfree(state->space_before);
1129
1149
  state->space_before = NULL;
1150
+ state->space_before_len = 0;
1130
1151
  }
1131
1152
  } else {
1132
1153
  if (state->space_before) ruby_xfree(state->space_before);
1133
1154
  state->space_before = strdup(RSTRING_PTR(space_before));
1155
+ state->space_before_len = len;
1134
1156
  }
1135
1157
  return Qnil;
1136
1158
  }
@@ -1155,9 +1177,11 @@ static VALUE cState_object_nl(VALUE self)
1155
1177
  */
1156
1178
  static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
1157
1179
  {
1180
+ int len;
1158
1181
  GET_STATE(self);
1159
1182
  Check_Type(object_nl, T_STRING);
1160
- if (RSTRING_LEN(object_nl) == 0) {
1183
+ len = RSTRING_LEN(object_nl);
1184
+ if (len == 0) {
1161
1185
  if (state->object_nl) {
1162
1186
  ruby_xfree(state->object_nl);
1163
1187
  state->object_nl = NULL;
@@ -1165,6 +1189,7 @@ static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
1165
1189
  } else {
1166
1190
  if (state->object_nl) ruby_xfree(state->object_nl);
1167
1191
  state->object_nl = strdup(RSTRING_PTR(object_nl));
1192
+ state->object_nl_len = len;
1168
1193
  }
1169
1194
  return Qnil;
1170
1195
  }
@@ -1187,9 +1212,11 @@ static VALUE cState_array_nl(VALUE self)
1187
1212
  */
1188
1213
  static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
1189
1214
  {
1215
+ int len;
1190
1216
  GET_STATE(self);
1191
1217
  Check_Type(array_nl, T_STRING);
1192
- if (RSTRING_LEN(array_nl) == 0) {
1218
+ len = RSTRING_LEN(array_nl);
1219
+ if (len == 0) {
1193
1220
  if (state->array_nl) {
1194
1221
  ruby_xfree(state->array_nl);
1195
1222
  state->array_nl = NULL;
@@ -1197,6 +1224,7 @@ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
1197
1224
  } else {
1198
1225
  if (state->array_nl) ruby_xfree(state->array_nl);
1199
1226
  state->array_nl = strdup(RSTRING_PTR(array_nl));
1227
+ state->array_nl_len = len;
1200
1228
  }
1201
1229
  return Qnil;
1202
1230
  }
@@ -1263,6 +1291,30 @@ static VALUE cState_ascii_only_p(VALUE self)
1263
1291
  return state->ascii_only ? Qtrue : Qfalse;
1264
1292
  }
1265
1293
 
1294
+ /*
1295
+ * call-seq: depth
1296
+ *
1297
+ * This integer returns the current depth of data structure nesting.
1298
+ */
1299
+ static VALUE cState_depth(VALUE self)
1300
+ {
1301
+ GET_STATE(self);
1302
+ return LONG2FIX(state->depth);
1303
+ }
1304
+
1305
+ /*
1306
+ * call-seq: depth=(depth)
1307
+ *
1308
+ * This sets the maximum level of data structure nesting in the generated JSON
1309
+ * to the integer depth, max_nesting = 0 if no maximum should be checked.
1310
+ */
1311
+ static VALUE cState_depth_set(VALUE self, VALUE depth)
1312
+ {
1313
+ GET_STATE(self);
1314
+ Check_Type(depth, T_FIXNUM);
1315
+ return state->depth = FIX2LONG(depth);
1316
+ }
1317
+
1266
1318
  /*
1267
1319
  *
1268
1320
  */
@@ -1297,6 +1349,8 @@ void Init_generator()
1297
1349
  rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
1298
1350
  rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
1299
1351
  rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
1352
+ rb_define_method(cState, "depth", cState_depth, 0);
1353
+ rb_define_method(cState, "depth=", cState_depth_set, 1);
1300
1354
  rb_define_method(cState, "configure", cState_configure, 1);
1301
1355
  rb_define_method(cState, "to_h", cState_to_h, 0);
1302
1356
  rb_define_method(cState, "[]", cState_aref, 1);
@@ -1341,6 +1395,7 @@ void Init_generator()
1341
1395
  i_max_nesting = rb_intern("max_nesting");
1342
1396
  i_allow_nan = rb_intern("allow_nan");
1343
1397
  i_ascii_only = rb_intern("ascii_only");
1398
+ i_depth = rb_intern("depth");
1344
1399
  i_pack = rb_intern("pack");
1345
1400
  i_unpack = rb_intern("unpack");
1346
1401
  i_create_id = rb_intern("create_id");
@@ -124,22 +124,23 @@ typedef struct JSON_Generator_StateStruct {
124
124
  long max_nesting;
125
125
  char allow_nan;
126
126
  char ascii_only;
127
+ long depth;
127
128
  } JSON_Generator_State;
128
129
 
129
130
  #define GET_STATE(self) \
130
131
  JSON_Generator_State *state; \
131
132
  Data_Get_Struct(self, JSON_Generator_State, state)
132
133
 
133
- #define GENERATE_JSON(type) \
134
+ #define GENERATE_JSON(type) \
134
135
  FBuffer *buffer; \
135
- VALUE Vstate, depth; \
136
+ VALUE Vstate; \
136
137
  JSON_Generator_State *state; \
137
138
  \
138
- rb_scan_args(argc, argv, "02", &Vstate, &depth); \
139
+ rb_scan_args(argc, argv, "01", &Vstate); \
139
140
  Vstate = cState_from_state_s(cState, Vstate); \
140
141
  Data_Get_Struct(Vstate, JSON_Generator_State, state); \
141
142
  buffer = cState_prepare_buffer(Vstate); \
142
- generate_json_##type(buffer, Vstate, state, self, NIL_P(depth) ? 0 : FIX2INT(depth)); \
143
+ generate_json_##type(buffer, Vstate, state, self); \
143
144
  return fbuffer_to_s(buffer)
144
145
 
145
146
  static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self);
@@ -161,17 +162,17 @@ static JSON_Generator_State *State_allocate();
161
162
  static VALUE cState_s_allocate(VALUE klass);
162
163
  static VALUE cState_configure(VALUE self, VALUE opts);
163
164
  static VALUE cState_to_h(VALUE self);
164
- static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
165
- static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
166
- static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
167
- static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
168
- static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
169
- static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
170
- static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
171
- static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
172
- static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
173
- static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
174
- static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth);
165
+ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
166
+ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
167
+ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
168
+ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
169
+ static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
170
+ static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
171
+ static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
172
+ static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
173
+ static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
174
+ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
175
+ static VALUE cState_partial_generate(VALUE self, VALUE obj);
175
176
  static VALUE cState_generate(VALUE self, VALUE obj);
176
177
  static VALUE cState_initialize(int argc, VALUE *argv, VALUE self);
177
178
  static VALUE cState_from_state_s(VALUE self, VALUE opts);
@@ -189,6 +190,8 @@ static VALUE cState_max_nesting(VALUE self);
189
190
  static VALUE cState_max_nesting_set(VALUE self, VALUE depth);
190
191
  static VALUE cState_allow_nan_p(VALUE self);
191
192
  static VALUE cState_ascii_only_p(VALUE self);
193
+ static VALUE cState_depth(VALUE self);
194
+ static VALUE cState_depth_set(VALUE self, VALUE depth);
192
195
  static FBuffer *cState_prepare_buffer(VALUE self);
193
196
 
194
197
  #endif
@@ -11,9 +11,9 @@ module JSON
11
11
  # generate and parse for their documentation.
12
12
  def [](object, opts = {})
13
13
  if object.respond_to? :to_str
14
- JSON.parse(object.to_str, opts => {})
14
+ JSON.parse(object.to_str, opts)
15
15
  else
16
- JSON.generate(object, opts => {})
16
+ JSON.generate(object, opts)
17
17
  end
18
18
  end
19
19
 
@@ -63,20 +63,20 @@ module JSON
63
63
  end
64
64
  self.state = generator::State
65
65
  const_set :State, self.state
66
- const_set :SAFE_STATE_PROTOTYPE, State.new.freeze
66
+ const_set :SAFE_STATE_PROTOTYPE, State.new
67
67
  const_set :FAST_STATE_PROTOTYPE, State.new(
68
68
  :indent => '',
69
69
  :space => '',
70
70
  :object_nl => "",
71
71
  :array_nl => "",
72
72
  :max_nesting => false
73
- ).freeze
73
+ )
74
74
  const_set :PRETTY_STATE_PROTOTYPE, State.new(
75
75
  :indent => ' ',
76
76
  :space => ' ',
77
77
  :object_nl => "\n",
78
78
  :array_nl => "\n"
79
- ).freeze
79
+ )
80
80
  end
81
81
 
82
82
  # Returns the JSON generator modul, that is used by JSON. This might be
@@ -196,6 +196,7 @@ module JSON
196
196
  # amount of sanity checks, and the pretty_generate method for some
197
197
  # defaults for a pretty output.
198
198
  def generate(obj, opts = nil)
199
+ state = SAFE_STATE_PROTOTYPE.dup
199
200
  if opts
200
201
  if opts.respond_to? :to_hash
201
202
  opts = opts.to_hash
@@ -204,10 +205,7 @@ module JSON
204
205
  else
205
206
  raise TypeError, "can't convert #{opts.class} into Hash"
206
207
  end
207
- state = SAFE_STATE_PROTOTYPE.dup
208
208
  state = state.configure(opts)
209
- else
210
- state = SAFE_STATE_PROTOTYPE
211
209
  end
212
210
  state.generate(obj)
213
211
  end
@@ -225,6 +223,7 @@ module JSON
225
223
  # *WARNING*: Be careful not to pass any Ruby data structures with circles as
226
224
  # _obj_ argument, because this will cause JSON to go into an infinite loop.
227
225
  def fast_generate(obj, opts = nil)
226
+ state = FAST_STATE_PROTOTYPE.dup
228
227
  if opts
229
228
  if opts.respond_to? :to_hash
230
229
  opts = opts.to_hash
@@ -233,10 +232,7 @@ module JSON
233
232
  else
234
233
  raise TypeError, "can't convert #{opts.class} into Hash"
235
234
  end
236
- state = FAST_STATE_PROTOTYPE.dup
237
235
  state.configure(opts)
238
- else
239
- state = FAST_STATE_PROTOTYPE
240
236
  end
241
237
  state.generate(obj)
242
238
  end
@@ -254,6 +250,7 @@ module JSON
254
250
  # The _opts_ argument can be used to configure the generator, see the
255
251
  # generate method for a more detailed explanation.
256
252
  def pretty_generate(obj, opts = nil)
253
+ state = PRETTY_STATE_PROTOTYPE.dup
257
254
  if opts
258
255
  if opts.respond_to? :to_hash
259
256
  opts = opts.to_hash
@@ -262,10 +259,7 @@ module JSON
262
259
  else
263
260
  raise TypeError, "can't convert #{opts.class} into Hash"
264
261
  end
265
- state = PRETTY_STATE_PROTOTYPE.dup
266
262
  state.configure(opts)
267
- else
268
- state = PRETTY_STATE_PROTOTYPE
269
263
  end
270
264
  state.generate(obj)
271
265
  end
@@ -377,11 +371,11 @@ module ::Kernel
377
371
  #
378
372
  # The _opts_ argument is passed through to generate/parse respectively, see
379
373
  # generate and parse for their documentation.
380
- def JSON(object, opts = {})
374
+ def JSON(object, *args)
381
375
  if object.respond_to? :to_str
382
- JSON.parse(object.to_str, opts)
376
+ JSON.parse(object.to_str, args.first)
383
377
  else
384
- JSON.generate(object, opts)
378
+ JSON.generate(object, args.first)
385
379
  end
386
380
  end
387
381
  end
@@ -163,6 +163,10 @@ module JSON
163
163
  # the generated JSON, max_nesting = 0 if no maximum is checked.
164
164
  attr_accessor :max_nesting
165
165
 
166
+ # This integer returns the current depth data structure nesting in the
167
+ # generated JSON.
168
+ attr_accessor :depth
169
+
166
170
  def check_max_nesting(depth) # :nodoc:
167
171
  return if @max_nesting.zero?
168
172
  current_nesting = depth + 1
@@ -196,6 +200,7 @@ module JSON
196
200
  @array_nl = opts[:array_nl] if opts.key?(:array_nl)
197
201
  @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
198
202
  @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
203
+ @depth = opts[:depth] || 0
199
204
  if !opts.key?(:max_nesting) # defaults to 19
200
205
  @max_nesting = 19
201
206
  elsif opts[:max_nesting]
@@ -210,7 +215,7 @@ module JSON
210
215
  # passed to the configure method.
211
216
  def to_h
212
217
  result = {}
213
- for iv in %w[indent space space_before object_nl array_nl allow_nan max_nesting]
218
+ for iv in %w[indent space space_before object_nl array_nl allow_nan max_nesting ascii_only depth]
214
219
  result[iv.intern] = instance_variable_get("@#{iv}")
215
220
  end
216
221
  result
@@ -69,41 +69,42 @@ module JSON
69
69
  # * *object_class*: Defaults to Hash
70
70
  # * *array_class*: Defaults to Array
71
71
  def initialize(source, opts = {})
72
- if defined?(::Encoding)
73
- if source.encoding == ::Encoding::ASCII_8BIT
74
- b = source[0, 4].bytes.to_a
75
- source = case
76
- when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
77
- source.dup.force_encoding(::Encoding::UTF_32BE).encode!(::Encoding::UTF_8)
78
- when b.size >= 4 && b[0] == 0 && b[2] == 0
79
- source.dup.force_encoding(::Encoding::UTF_16BE).encode!(::Encoding::UTF_8)
80
- when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
81
- source.dup.force_encoding(::Encoding::UTF_32LE).encode!(::Encoding::UTF_8)
82
-
83
- when b.size >= 4 && b[1] == 0 && b[3] == 0
84
- source.dup.force_encoding(::Encoding::UTF_16LE).encode!(::Encoding::UTF_8)
85
- else
86
- source.dup
87
- end
88
- else
89
- source = source.encode(::Encoding::UTF_8)
90
- end
91
- source.force_encoding(::Encoding::ASCII_8BIT)
92
- else
93
- b = source
72
+ opts ||= {}
73
+ if defined?(::Encoding)
74
+ if source.encoding == ::Encoding::ASCII_8BIT
75
+ b = source[0, 4].bytes.to_a
94
76
  source = case
95
77
  when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
96
- JSON.iconv('utf-8', 'utf-32be', b)
78
+ source.dup.force_encoding(::Encoding::UTF_32BE).encode!(::Encoding::UTF_8)
97
79
  when b.size >= 4 && b[0] == 0 && b[2] == 0
98
- JSON.iconv('utf-8', 'utf-16be', b)
80
+ source.dup.force_encoding(::Encoding::UTF_16BE).encode!(::Encoding::UTF_8)
99
81
  when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
100
- JSON.iconv('utf-8', 'utf-32le', b)
82
+ source.dup.force_encoding(::Encoding::UTF_32LE).encode!(::Encoding::UTF_8)
83
+
101
84
  when b.size >= 4 && b[1] == 0 && b[3] == 0
102
- JSON.iconv('utf-8', 'utf-16le', b)
85
+ source.dup.force_encoding(::Encoding::UTF_16LE).encode!(::Encoding::UTF_8)
103
86
  else
104
- b
87
+ source.dup
105
88
  end
89
+ else
90
+ source = source.encode(::Encoding::UTF_8)
106
91
  end
92
+ source.force_encoding(::Encoding::ASCII_8BIT)
93
+ else
94
+ b = source
95
+ source = case
96
+ when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
97
+ JSON.iconv('utf-8', 'utf-32be', b)
98
+ when b.size >= 4 && b[0] == 0 && b[2] == 0
99
+ JSON.iconv('utf-8', 'utf-16be', b)
100
+ when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
101
+ JSON.iconv('utf-8', 'utf-32le', b)
102
+ when b.size >= 4 && b[1] == 0 && b[3] == 0
103
+ JSON.iconv('utf-8', 'utf-16le', b)
104
+ else
105
+ b
106
+ end
107
+ end
107
108
  super source
108
109
  if !opts.key?(:max_nesting) # defaults to 19
109
110
  @max_nesting = 19
@@ -1,6 +1,6 @@
1
1
  module JSON
2
2
  # JSON version
3
- VERSION = '1.4.4'
3
+ VERSION = '1.4.5'
4
4
  VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
@@ -102,6 +102,51 @@ EOT
102
102
  assert s[:check_circular?]
103
103
  end
104
104
 
105
+ def test_pretty_state
106
+ state = PRETTY_STATE_PROTOTYPE.dup
107
+ assert_equal({
108
+ :allow_nan => false,
109
+ :array_nl => "\n",
110
+ :ascii_only => false,
111
+ :depth => 0,
112
+ :indent => " ",
113
+ :max_nesting => 19,
114
+ :object_nl => "\n",
115
+ :space => " ",
116
+ :space_before => "",
117
+ }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
118
+ end
119
+
120
+ def test_safe_state
121
+ state = SAFE_STATE_PROTOTYPE.dup
122
+ assert_equal({
123
+ :allow_nan => false,
124
+ :array_nl => "",
125
+ :ascii_only => false,
126
+ :depth => 0,
127
+ :indent => "",
128
+ :max_nesting => 19,
129
+ :object_nl => "",
130
+ :space => "",
131
+ :space_before => "",
132
+ }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
133
+ end
134
+
135
+ def test_fast_state
136
+ state = FAST_STATE_PROTOTYPE.dup
137
+ assert_equal({
138
+ :allow_nan => false,
139
+ :array_nl => "",
140
+ :ascii_only => false,
141
+ :depth => 0,
142
+ :indent => "",
143
+ :max_nesting => 0,
144
+ :object_nl => "",
145
+ :space => "",
146
+ :space_before => "",
147
+ }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
148
+ end
149
+
105
150
  def test_allow_nan
106
151
  assert_raises(GeneratorError) { generate([JSON::NaN]) }
107
152
  assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 13
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 4
9
- - 4
10
- version: 1.4.4
9
+ - 5
10
+ version: 1.4.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Florian Frank
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-06 00:00:00 +02:00
18
+ date: 2010-08-07 00:00:00 +02:00
19
19
  default_executable: edit_json.rb
20
20
  dependencies: []
21
21