oj 3.9.2 → 3.10.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/oj/buf.h +2 -30
  4. data/ext/oj/cache8.h +1 -29
  5. data/ext/oj/circarray.c +4 -8
  6. data/ext/oj/circarray.h +1 -4
  7. data/ext/oj/code.c +3 -6
  8. data/ext/oj/code.h +1 -4
  9. data/ext/oj/compat.c +6 -9
  10. data/ext/oj/custom.c +8 -7
  11. data/ext/oj/dump.c +33 -26
  12. data/ext/oj/dump.h +1 -4
  13. data/ext/oj/dump_compat.c +9 -14
  14. data/ext/oj/dump_leaf.c +2 -5
  15. data/ext/oj/dump_object.c +19 -15
  16. data/ext/oj/dump_strict.c +7 -9
  17. data/ext/oj/encode.h +1 -29
  18. data/ext/oj/err.c +1 -4
  19. data/ext/oj/err.h +1 -29
  20. data/ext/oj/extconf.rb +5 -0
  21. data/ext/oj/fast.c +14 -42
  22. data/ext/oj/hash.c +4 -32
  23. data/ext/oj/hash.h +1 -29
  24. data/ext/oj/hash_test.c +1 -29
  25. data/ext/oj/mimic_json.c +28 -10
  26. data/ext/oj/object.c +4 -6
  27. data/ext/oj/odd.c +1 -4
  28. data/ext/oj/odd.h +1 -4
  29. data/ext/oj/oj.c +74 -38
  30. data/ext/oj/oj.h +9 -7
  31. data/ext/oj/parse.c +127 -52
  32. data/ext/oj/parse.h +4 -5
  33. data/ext/oj/rails.c +38 -8
  34. data/ext/oj/rails.h +1 -4
  35. data/ext/oj/reader.c +5 -8
  36. data/ext/oj/reader.h +2 -5
  37. data/ext/oj/resolve.c +1 -4
  38. data/ext/oj/resolve.h +1 -4
  39. data/ext/oj/rxclass.c +3 -6
  40. data/ext/oj/rxclass.h +1 -4
  41. data/ext/oj/saj.c +6 -9
  42. data/ext/oj/scp.c +1 -4
  43. data/ext/oj/sparse.c +31 -26
  44. data/ext/oj/stream_writer.c +4 -9
  45. data/ext/oj/strict.c +3 -6
  46. data/ext/oj/string_writer.c +1 -4
  47. data/ext/oj/trace.c +5 -8
  48. data/ext/oj/trace.h +1 -4
  49. data/ext/oj/util.c +1 -1
  50. data/ext/oj/util.h +1 -1
  51. data/ext/oj/val_stack.c +1 -29
  52. data/ext/oj/val_stack.h +1 -29
  53. data/ext/oj/wab.c +10 -13
  54. data/lib/oj/mimic.rb +45 -1
  55. data/lib/oj/version.rb +1 -1
  56. data/lib/oj.rb +0 -8
  57. data/pages/Modes.md +1 -1
  58. data/pages/Options.md +15 -11
  59. data/pages/Rails.md +60 -21
  60. data/test/activesupport5/abstract_unit.rb +45 -0
  61. data/test/activesupport5/decoding_test.rb +68 -60
  62. data/test/activesupport5/encoding_test.rb +111 -96
  63. data/test/activesupport5/encoding_test_cases.rb +33 -25
  64. data/test/activesupport5/test_helper.rb +43 -21
  65. data/test/activesupport5/time_zone_test_helpers.rb +18 -3
  66. data/test/activesupport6/abstract_unit.rb +44 -0
  67. data/test/activesupport6/decoding_test.rb +133 -0
  68. data/test/activesupport6/encoding_test.rb +507 -0
  69. data/test/activesupport6/encoding_test_cases.rb +98 -0
  70. data/test/activesupport6/test_common.rb +17 -0
  71. data/test/activesupport6/test_helper.rb +163 -0
  72. data/test/activesupport6/time_zone_test_helpers.rb +39 -0
  73. data/test/bar.rb +21 -11
  74. data/test/baz.rb +16 -0
  75. data/test/foo.rb +39 -8
  76. data/test/json_gem/json_common_interface_test.rb +8 -3
  77. data/test/prec.rb +23 -0
  78. data/test/sample_json.rb +1 -1
  79. data/test/test_compat.rb +14 -8
  80. data/test/test_custom.rb +36 -6
  81. data/test/test_integer_range.rb +1 -2
  82. data/test/test_object.rb +12 -3
  83. data/test/test_rails.rb +35 -0
  84. data/test/test_strict.rb +24 -1
  85. data/test/test_various.rb +42 -64
  86. data/test/tests.rb +1 -0
  87. metadata +29 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52a998aa9f2273e995d9ef52e26df3f8998aae1a98d7d088f6973cf8234a444f
4
- data.tar.gz: 26647fb39df6d357074e5798bf263ca708a361cf910eba43c7c7a3d1ba905f51
3
+ metadata.gz: 764f297554e1e876cb8961737a5670c943cc344651ac950128568fbeb61609ba
4
+ data.tar.gz: 318dad71cb0e6ccb7f6f86d6e5e6f76dc1a86bf4aa82f07501c772ac60f73882
5
5
  SHA512:
6
- metadata.gz: 9dffec2bd8c447ca172aa4a647a719c1cc62eeedab91ea30b79943fa212e4b78a10b3e3ddfd69e873e632c3bdddce2d955d34aa106dfa7e4f43618ea842aa829
7
- data.tar.gz: 5dd30d0dcaf87e9b57c16ad13f0e7654ab8b8b02d8b3709f20614025283101bc44cedf4470bb2bb887b41a280d2e4b131f77a26a65a8e79447771a6bc5cca42d
6
+ metadata.gz: 1c6ad5cd4811b13fef7b5f2890e9335b5078cbee85ba4d8fcad6b91487c782949361b62fc8673f8b9d4bd602d738eb04e1414021f10e9c1247be347cdb4f4e50
7
+ data.tar.gz: a99166c591a9e9805fd516c4bc55a5dfc6512161560965fc44caa02a85375d3d771a0ab10ffc153ee789373e708aae207f1ee15ec3fd54a11a06c104d5b21346
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # [![{}j](http://www.ohler.com/dev/images/oj_comet_64.svg)](http://www.ohler.com/oj) gem
2
2
 
3
- [![Build Status](https://img.shields.io/travis/ohler55/oj/master.svg)](http://travis-ci.org/ohler55/oj?branch=master) [![AppVeyor](https://img.shields.io/appveyor/ci/ohler55/oj/master.svg)](https://ci.appveyor.com/project/ohler55/oj) ![Gem](https://img.shields.io/gem/v/oj.svg) ![Gem](https://img.shields.io/gem/dt/oj.svg) [![SemVer compatibility](https://api.dependabot.com/badges/compatibility_score?dependency-name=oj&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=oj&package-manager=bundler&version-scheme=semver) [![TideLift](https://tidelift.com/badges/github/ohler55/oj)](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme)
3
+ [![Build Status](https://img.shields.io/travis/ohler55/oj/master.svg?logo=travis)](http://travis-ci.org/ohler55/oj?branch=master) [![AppVeyor](https://img.shields.io/appveyor/ci/ohler55/oj/master.svg?logo=appveyor)](https://ci.appveyor.com/project/ohler55/oj) ![Gem](https://img.shields.io/gem/v/oj.svg) ![Gem](https://img.shields.io/gem/dt/oj.svg) [![SemVer compatibility](https://api.dependabot.com/badges/compatibility_score?dependency-name=oj&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=oj&package-manager=bundler&version-scheme=semver) [![TideLift](https://tidelift.com/badges/github/ohler55/oj)](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme)
4
4
 
5
5
  A *fast* JSON parser and Object marshaller as a Ruby gem.
6
6
 
@@ -42,7 +42,7 @@ gem 'oj'
42
42
 
43
43
  ## Support
44
44
 
45
- [Get supported Oj with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme)
45
+ [Get supported Oj with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme) Security updates are [supported](https://tidelift.com/security).
46
46
 
47
47
  ## Further Reading
48
48
 
data/ext/oj/buf.h CHANGED
@@ -1,32 +1,4 @@
1
- /* buf.h
2
- * Copyright (c) 2011, Peter Ohler
3
- * All rights reserved.
4
- *
5
- * Redistribution and use in source and binary forms, with or without
6
- * modification, are permitted provided that the following conditions are met:
7
- *
8
- * - Redistributions of source code must retain the above copyright notice, this
9
- * list of conditions and the following disclaimer.
10
- *
11
- * - Redistributions in binary form must reproduce the above copyright notice,
12
- * this list of conditions and the following disclaimer in the documentation
13
- * and/or other materials provided with the distribution.
14
- *
15
- * - Neither the name of Peter Ohler nor the names of its contributors may be
16
- * used to endorse or promote products derived from this software without
17
- * specific prior written permission.
18
- *
19
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
- */
1
+ // Copyright (c) 2011 Peter Ohler. All rights reserved.
30
2
 
31
3
  #ifndef OJ_BUF_H
32
4
  #define OJ_BUF_H
@@ -78,7 +50,7 @@ buf_append_string(Buf buf, const char *s, size_t slen) {
78
50
  memcpy(buf->tail, s, slen);
79
51
  buf->tail += slen;
80
52
  }
81
-
53
+
82
54
  inline static void
83
55
  buf_append(Buf buf, char c) {
84
56
  if (buf->end <= buf->tail) {
data/ext/oj/cache8.h CHANGED
@@ -1,32 +1,4 @@
1
- /* cache8.h
2
- * Copyright (c) 2011, Peter Ohler
3
- * All rights reserved.
4
- *
5
- * Redistribution and use in source and binary forms, with or without
6
- * modification, are permitted provided that the following conditions are met:
7
- *
8
- * - Redistributions of source code must retain the above copyright notice, this
9
- * list of conditions and the following disclaimer.
10
- *
11
- * - Redistributions in binary form must reproduce the above copyright notice,
12
- * this list of conditions and the following disclaimer in the documentation
13
- * and/or other materials provided with the distribution.
14
- *
15
- * - Neither the name of Peter Ohler nor the names of its contributors may be
16
- * used to endorse or promote products derived from this software without
17
- * specific prior written permission.
18
- *
19
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
- */
1
+ // Copyright (c) 2011 Peter Ohler. All rights reserved.
30
2
 
31
3
  #ifndef OJ_CACHE8_H
32
4
  #define OJ_CACHE8_H
data/ext/oj/circarray.c CHANGED
@@ -1,21 +1,18 @@
1
- /* circarray.c
2
- * Copyright (c) 2012, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2012 Peter Ohler. All rights reserved.
5
2
 
6
3
  #include "circarray.h"
7
4
 
8
5
  CircArray
9
6
  oj_circ_array_new() {
10
7
  CircArray ca;
11
-
8
+
12
9
  if (0 == (ca = ALLOC(struct _circArray))) {
13
10
  rb_raise(rb_eNoMemError, "not enough memory\n");
14
11
  }
15
12
  ca->objs = ca->obj_array;
16
13
  ca->size = sizeof(ca->obj_array) / sizeof(VALUE);
17
14
  ca->cnt = 0;
18
-
15
+
19
16
  return ca;
20
17
  }
21
18
 
@@ -40,7 +37,7 @@ oj_circ_array_set(CircArray ca, VALUE obj, unsigned long id) {
40
37
  rb_raise(rb_eNoMemError, "not enough memory\n");
41
38
  }
42
39
  memcpy(ca->objs, ca->obj_array, sizeof(VALUE) * ca->cnt);
43
- } else {
40
+ } else {
44
41
  REALLOC_N(ca->objs, VALUE, cnt);
45
42
  }
46
43
  ca->size = cnt;
@@ -65,4 +62,3 @@ oj_circ_array_get(CircArray ca, unsigned long id) {
65
62
  }
66
63
  return obj;
67
64
  }
68
-
data/ext/oj/circarray.h CHANGED
@@ -1,7 +1,4 @@
1
- /* circarray.h
2
- * Copyright (c) 2012, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2012 Peter Ohler. All rights reserved.
5
2
 
6
3
  #ifndef OJ_CIRCARRAY_H
7
4
  #define OJ_CIRCARRAY_H
data/ext/oj/code.c CHANGED
@@ -1,7 +1,4 @@
1
- /* code.c
2
- * Copyright (c) 2017, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2017 Peter Ohler. All rights reserved.
5
2
 
6
3
  #include "code.h"
7
4
  #include "dump.h"
@@ -140,7 +137,7 @@ oj_code_attrs(VALUE obj, Attr attrs, int depth, Out out, bool with_class) {
140
137
  size_t len = strlen(classname);
141
138
  size_t size = d2 * out->indent + 10 + len + out->opts->create_id_len + sep_len;
142
139
  bool no_comma = true;
143
-
140
+
144
141
  assure_size(out, size);
145
142
  *out->cur++ = '{';
146
143
 
@@ -201,7 +198,7 @@ oj_code_attrs(VALUE obj, Attr attrs, int depth, Out out, bool with_class) {
201
198
  char *b = buf + sizeof(buf) - 1;
202
199
  int neg = 0;
203
200
  long num = attrs->num;
204
-
201
+
205
202
  if (0 > num) {
206
203
  neg = 1;
207
204
  num = -num;
data/ext/oj/code.h CHANGED
@@ -1,7 +1,4 @@
1
- /* code.h
2
- * Copyright (c) 2017, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2017 Peter Ohler. All rights reserved.
5
2
 
6
3
  #ifndef OJ_CODE_H
7
4
  #define OJ_CODE_H
data/ext/oj/compat.c CHANGED
@@ -1,7 +1,4 @@
1
- /* compat.c
2
- * Copyright (c) 2012, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2012 Peter Ohler. All rights reserved.
5
2
 
6
3
  #include <stdio.h>
7
4
 
@@ -65,7 +62,7 @@ hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *o
65
62
  static VALUE
66
63
  start_hash(ParseInfo pi) {
67
64
  volatile VALUE h;
68
-
65
+
69
66
  if (Qnil != pi->options.hash_class) {
70
67
  h = rb_class_new_instance(0, NULL, pi->options.hash_class);
71
68
  } else {
@@ -87,7 +84,7 @@ end_hash(struct _parseInfo *pi) {
87
84
  clas = oj_name2class(pi, parent->classname, parent->clen, 0, rb_eArgError);
88
85
  if (Qundef != clas) { // else an error
89
86
  ID creatable = rb_intern("json_creatable?");
90
-
87
+
91
88
  if (!rb_respond_to(clas, creatable) || Qtrue == rb_funcall(clas, creatable, 0)) {
92
89
  parent->val = rb_funcall(clas, oj_json_create_id, 1, parent->val);
93
90
  }
@@ -146,7 +143,7 @@ add_num(ParseInfo pi, NumInfo ni) {
146
143
  static void
147
144
  hash_set_num(struct _parseInfo *pi, Val parent, NumInfo ni) {
148
145
  volatile VALUE rval = oj_num_as_value(ni);
149
-
146
+
150
147
  if (!oj_use_hash_alt && rb_cHash != rb_obj_class(parent->val)) {
151
148
  // The rb_hash_set would still work but the unit tests for the
152
149
  // json gem require the less efficient []= method be called to set
@@ -192,7 +189,7 @@ static void
192
189
  array_append_num(ParseInfo pi, NumInfo ni) {
193
190
  Val parent = stack_peek(&pi->stack);
194
191
  volatile VALUE rval = oj_num_as_value(ni);
195
-
192
+
196
193
  if (!oj_use_array_alt && rb_cArray != rb_obj_class(parent->val)) {
197
194
  // The rb_ary_push would still work but the unit tests for the json
198
195
  // gem require the less efficient << method be called to push the
@@ -274,7 +271,7 @@ oj_compat_load(int argc, VALUE *argv, VALUE self) {
274
271
  pi.options.nilnil = Yes;
275
272
  pi.options.empty_string = Yes;
276
273
  oj_set_compat_callbacks(&pi);
277
-
274
+
278
275
  if (T_STRING == rb_type(*argv)) {
279
276
  return oj_pi_parse(argc, argv, &pi, 0, 0, false);
280
277
  } else {
data/ext/oj/custom.c CHANGED
@@ -1,7 +1,4 @@
1
- /* custom.c
2
- * Copyright (c) 2012, 2017, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
5
2
 
6
3
  #include <stdint.h>
7
4
  #include <stdio.h>
@@ -297,7 +294,8 @@ static struct _code codes[] = {
297
294
  };
298
295
 
299
296
  static int
300
- hash_cb(VALUE key, VALUE value, Out out) {
297
+ hash_cb(VALUE key, VALUE value, VALUE ov) {
298
+ Out out = (Out)ov;
301
299
  int depth = out->depth;
302
300
 
303
301
  if (oj_dump_ignore(out->opts, value)) {
@@ -592,7 +590,8 @@ dump_common(VALUE obj, int depth, Out out) {
592
590
  }
593
591
 
594
592
  static int
595
- dump_attr_cb(ID key, VALUE value, Out out) {
593
+ dump_attr_cb(ID key, VALUE value, VALUE ov) {
594
+ Out out = (Out)ov;
596
595
  int depth = out->depth;
597
596
  size_t size;
598
597
  const char *attr;
@@ -609,6 +608,8 @@ dump_attr_cb(ID key, VALUE value, Out out) {
609
608
  // the key name is NULL. Not an empty string but NULL.
610
609
  if (NULL == attr) {
611
610
  attr = "";
611
+ } else if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
612
+ return ST_CONTINUE;
612
613
  }
613
614
  if (0 == strcmp("bt", attr) || 0 == strcmp("mesg", attr)) {
614
615
  return ST_CONTINUE;
@@ -1085,7 +1086,7 @@ hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
1085
1086
  // offset and then a conversion to UTC keeps makes the time
1086
1087
  // match the expected value.
1087
1088
  parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
1088
- } else if (ni->hasExp) {
1089
+ } else if (ni->has_exp) {
1089
1090
  int64_t t = (int64_t)(ni->i + ni->exp);
1090
1091
  struct _timeInfo ti;
1091
1092
  VALUE args[8];
data/ext/oj/dump.c CHANGED
@@ -1,7 +1,4 @@
1
- /* dump.c
2
- * Copyright (c) 2012, 2017, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
5
2
 
6
3
  #include <errno.h>
7
4
  #include <math.h>
@@ -111,7 +108,7 @@ static char rails_friendly_chars[256] = "\
111
108
  11111111111111111111111111111111\
112
109
  11111111111111111111111111111111\
113
110
  11111111111111111111111111111111\
114
- 11611111111111111111111111111111";
111
+ 11111111111111111111111111111111";
115
112
 
116
113
  static void
117
114
  raise_strict(VALUE obj) {
@@ -177,15 +174,20 @@ hixss_friendly_size(const uint8_t *str, size_t len) {
177
174
  return size - len * (size_t)'0' + check;
178
175
  }
179
176
 
180
- inline static size_t
177
+ inline static long
181
178
  rails_xss_friendly_size(const uint8_t *str, size_t len) {
182
- size_t size = 0;
179
+ long size = 0;
183
180
  size_t i = len;
181
+ uint8_t hi = 0;
184
182
 
185
183
  for (; 0 < i; str++, i--) {
186
184
  size += rails_xss_friendly_chars[*str];
185
+ hi |= *str & 0x80;
187
186
  }
188
- return size - len * (size_t)'0';
187
+ if (0 == hi) {
188
+ return size - len * (size_t)'0';
189
+ }
190
+ return -(size - len * (size_t)'0');
189
191
  }
190
192
 
191
193
  inline static size_t
@@ -252,7 +254,6 @@ dump_hex(uint8_t c, Out out) {
252
254
 
253
255
  static void
254
256
  raise_invalid_unicode(const char *str, int len, int pos) {
255
- char buf[len + 1];
256
257
  char c;
257
258
  char code[32];
258
259
  char *cp = code;
@@ -271,8 +272,7 @@ raise_invalid_unicode(const char *str, int len, int pos) {
271
272
  cp--;
272
273
  *cp++ = ']';
273
274
  *cp = '\0';
274
- strncpy(buf, str, len);
275
- rb_raise(oj_json_generator_error_class, "Invalid Unicode %s at %d in '%s'", code, pos, buf);
275
+ rb_raise(oj_json_generator_error_class, "Invalid Unicode %s at %d", code, pos);
276
276
  }
277
277
 
278
278
  static const char*
@@ -548,7 +548,7 @@ oj_dump_xml_time(VALUE obj, Out out) {
548
548
  tzhour = (int)(tzsecs / 3600);
549
549
  tzmin = (int)(tzsecs / 60) - (tzhour * 60);
550
550
  }
551
- if (0 == nsec || 0 == out->opts->sec_prec) {
551
+ if ((0 == nsec && !out->opts->sec_prec_set) || 0 == out->opts->sec_prec) {
552
552
  if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
553
553
  sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ", ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec);
554
554
  oj_dump_cstr(buf, 20, 0, 0, out);
@@ -770,6 +770,7 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
770
770
  size_t size;
771
771
  char *cmap;
772
772
  const char *orig = str;
773
+ bool has_hi = false;
773
774
 
774
775
  switch (out->opts->escape_mode) {
775
776
  case NLEsc:
@@ -788,10 +789,19 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
788
789
  cmap = hixss_friendly_chars;
789
790
  size = hixss_friendly_size((uint8_t*)str, cnt);
790
791
  break;
791
- case RailsXEsc:
792
+ case RailsXEsc: {
793
+ long sz;
794
+
792
795
  cmap = rails_xss_friendly_chars;
793
- size = rails_xss_friendly_size((uint8_t*)str, cnt);
796
+ sz = rails_xss_friendly_size((uint8_t*)str, cnt);
797
+ if (sz < 0) {
798
+ has_hi = true;
799
+ size = (size_t)-sz;
800
+ } else {
801
+ size = (size_t)sz;
802
+ }
794
803
  break;
804
+ }
795
805
  case RailsEsc:
796
806
  cmap = rails_friendly_chars;
797
807
  size = rails_friendly_size((uint8_t*)str, cnt);
@@ -815,7 +825,7 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
815
825
  str++;
816
826
  is_sym = 0; // just to make sure
817
827
  }
818
- if (cnt == size) {
828
+ if (cnt == size && !has_hi) {
819
829
  if (is_sym) {
820
830
  *out->cur++ = ':';
821
831
  }
@@ -1023,8 +1033,8 @@ oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1023
1033
  int neg = 0;
1024
1034
  bool dump_as_string = false;
1025
1035
 
1026
- if (out->opts->integer_range_max != 0 && out->opts->integer_range_min != 0 &&
1027
- (out->opts->integer_range_max < num || out->opts->integer_range_min > num)) {
1036
+ if (out->opts->int_range_max != 0 && out->opts->int_range_min != 0 &&
1037
+ (out->opts->int_range_max < num || out->opts->int_range_min > num)) {
1028
1038
  dump_as_string = true;
1029
1039
  }
1030
1040
  if (0 > num) {
@@ -1062,23 +1072,20 @@ void
1062
1072
  oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
1063
1073
  volatile VALUE rs = rb_big2str(obj, 10);
1064
1074
  int cnt = (int)RSTRING_LEN(rs);
1065
- bool dump_as_string = false;
1075
+ bool dump_as_string = false;
1066
1076
 
1067
- if (out->opts->integer_range_max != 0 || out->opts->integer_range_min != 0) { // Bignum cannot be inside of Fixnum range
1077
+ if (out->opts->int_range_max != 0 || out->opts->int_range_min != 0) { // Bignum cannot be inside of Fixnum range
1068
1078
  dump_as_string = true;
1069
1079
  assure_size(out, cnt + 2);
1070
1080
  *out->cur++ = '"';
1071
- } else {
1081
+ } else {
1072
1082
  assure_size(out, cnt);
1073
- }
1074
-
1083
+ }
1075
1084
  memcpy(out->cur, rb_string_value_ptr((VALUE*)&rs), cnt);
1076
1085
  out->cur += cnt;
1077
-
1078
- if(dump_as_string) {
1086
+ if (dump_as_string) {
1079
1087
  *out->cur++ = '"';
1080
- }
1081
-
1088
+ }
1082
1089
  *out->cur = '\0';
1083
1090
  }
1084
1091
 
data/ext/oj/dump.h CHANGED
@@ -1,7 +1,4 @@
1
- /* dump.h
2
- * Copyright (c) 2011, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2011 Peter Ohler. All rights reserved.
5
2
 
6
3
  #ifndef OJ_DUMP_H
7
4
  #define OJ_DUMP_H
data/ext/oj/dump_compat.c CHANGED
@@ -1,7 +1,4 @@
1
- /* dump_object.c
2
- * Copyright (c) 2012, 2017, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
5
2
 
6
3
  #include "code.h"
7
4
  #include "dump.h"
@@ -648,7 +645,8 @@ dump_float(VALUE obj, int depth, Out out, bool as_ok) {
648
645
  }
649
646
 
650
647
  static int
651
- hash_cb(VALUE key, VALUE value, Out out) {
648
+ hash_cb(VALUE key, VALUE value, VALUE ov) {
649
+ Out out = (Out)ov;
652
650
  int depth = out->depth;
653
651
 
654
652
  if (out->omit_nil && Qnil == value) {
@@ -870,7 +868,7 @@ dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
870
868
  // this must use to_s to pass the json gem unit tests.
871
869
  volatile VALUE rs;
872
870
  int cnt;
873
- bool dump_as_string = false;
871
+ bool dump_as_string = false;
874
872
 
875
873
  if (use_bignum_alt) {
876
874
  rs = rb_big2str(obj, 10);
@@ -880,21 +878,18 @@ dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
880
878
  rb_check_type(rs, T_STRING);
881
879
  cnt = (int)RSTRING_LEN(rs);
882
880
 
883
- if (out->opts->integer_range_min != 0 || out->opts->integer_range_max != 0) {
881
+ if (out->opts->int_range_min != 0 || out->opts->int_range_max != 0) {
884
882
  dump_as_string = true; // Bignum cannot be inside of Fixnum range
885
883
  assure_size(out, cnt + 2);
886
884
  *out->cur++ = '"';
887
- } else {
885
+ } else {
888
886
  assure_size(out, cnt);
889
- }
890
-
887
+ }
891
888
  memcpy(out->cur, rb_string_value_ptr((VALUE*)&rs), cnt);
892
889
  out->cur += cnt;
893
-
894
- if(dump_as_string) {
890
+ if (dump_as_string) {
895
891
  *out->cur++ = '"';
896
- }
897
-
892
+ }
898
893
  *out->cur = '\0';
899
894
  }
900
895
 
data/ext/oj/dump_leaf.c CHANGED
@@ -1,7 +1,4 @@
1
- /* dump_leaf.c
2
- * Copyright (c) 2012, 2017, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
5
2
 
6
3
  #include <errno.h>
7
4
 
@@ -15,7 +12,7 @@ grow(Out out, size_t len) {
15
12
  size_t size = out->end - out->buf;
16
13
  long pos = out->cur - out->buf;
17
14
  char *buf;
18
-
15
+
19
16
  size *= 2;
20
17
  if (size <= len * 2 + pos) {
21
18
  size += len;
data/ext/oj/dump_object.c CHANGED
@@ -1,7 +1,4 @@
1
- /* dump_object.c
2
- * Copyright (c) 2012, 2017, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
5
2
 
6
3
  #include "dump.h"
7
4
  #include "odd.h"
@@ -56,7 +53,7 @@ dump_data(VALUE obj, int depth, Out out, bool as_ok) {
56
53
  }
57
54
  } else {
58
55
  long id = oj_check_circular(obj, out);
59
-
56
+
60
57
  if (0 <= id) {
61
58
  dump_obj_attrs(obj, clas, id, depth, out);
62
59
  }
@@ -72,7 +69,7 @@ dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
72
69
  volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
73
70
  const char *str = rb_string_value_ptr((VALUE*)&rstr);
74
71
  int len = (int)RSTRING_LEN(rstr);
75
-
72
+
76
73
  if (0 == strcasecmp("Infinity", str)) {
77
74
  str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
78
75
  oj_dump_raw(str, len, out);
@@ -224,7 +221,8 @@ dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
224
221
  }
225
222
 
226
223
  static int
227
- hash_cb(VALUE key, VALUE value, Out out) {
224
+ hash_cb(VALUE key, VALUE value, VALUE ov) {
225
+ Out out = (Out)ov;
228
226
  int depth = out->depth;
229
227
  long size = depth * out->indent + 1;
230
228
 
@@ -280,7 +278,7 @@ hash_cb(VALUE key, VALUE value, Out out) {
280
278
  }
281
279
  out->depth = depth;
282
280
  *out->cur++ = ',';
283
-
281
+
284
282
  return ST_CONTINUE;
285
283
  }
286
284
 
@@ -348,7 +346,8 @@ dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
348
346
 
349
347
  #ifdef HAVE_RB_IVAR_FOREACH
350
348
  static int
351
- dump_attr_cb(ID key, VALUE value, Out out) {
349
+ dump_attr_cb(ID key, VALUE value, VALUE ov) {
350
+ Out out = (Out)ov;
352
351
  int depth = out->depth;
353
352
  size_t size = depth * out->indent + 1;
354
353
  const char *attr = rb_id2name(key);
@@ -363,6 +362,8 @@ dump_attr_cb(ID key, VALUE value, Out out) {
363
362
  // the key name is NULL. Not an empty string but NULL.
364
363
  if (NULL == attr) {
365
364
  attr = "";
365
+ } else if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
366
+ return ST_CONTINUE;
366
367
  }
367
368
  if (0 == strcmp("bt", attr) || 0 == strcmp("mesg", attr)) {
368
369
  return ST_CONTINUE;
@@ -384,7 +385,7 @@ dump_attr_cb(ID key, VALUE value, Out out) {
384
385
  oj_dump_obj_val(value, depth, out);
385
386
  out->depth = depth;
386
387
  *out->cur++ = ',';
387
-
388
+
388
389
  return ST_CONTINUE;
389
390
  }
390
391
  #endif
@@ -424,7 +425,7 @@ dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
424
425
  v = rb_funcall(obj, *odd->attrs, 0);
425
426
  if (Qundef == v || T_STRING != rb_type(v)) {
426
427
  rb_raise(rb_eEncodingError, "Invalid type for raw JSON.");
427
- } else {
428
+ } else {
428
429
  const char *s = rb_string_value_ptr((VALUE*)&v);
429
430
  int len = (int)RSTRING_LEN(v);
430
431
  const char *name = rb_id2name(*odd->attrs);
@@ -460,7 +461,7 @@ dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
460
461
  char *n;
461
462
  char *end;
462
463
  ID i;
463
-
464
+
464
465
  if (sizeof(nbuf) <= nlen) {
465
466
  if (NULL == (n2 = strdup(name))) {
466
467
  rb_raise(rb_eNoMemError, "for attribute name.");
@@ -610,9 +611,12 @@ dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) {
610
611
  size = d2 * out->indent + 1;
611
612
  for (i = cnt; 0 < i; i--, np++) {
612
613
  VALUE value;
613
-
614
+
614
615
  vid = rb_to_id(*np);
615
616
  attr = rb_id2name(vid);
617
+ if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
618
+ continue;
619
+ }
616
620
  value = rb_ivar_get(obj, vid);
617
621
 
618
622
  if (oj_dump_ignore(out->opts, value)) {
@@ -739,7 +743,7 @@ dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
739
743
  #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
740
744
  cnt = (int)RSTRUCT_LEN(obj);
741
745
  #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
742
-
746
+
743
747
  for (i = 0; i < cnt; i++) {
744
748
  v = RSTRUCT_GET(obj, i);
745
749
  if (oj_dump_ignore(out->opts, v)) {
@@ -812,7 +816,7 @@ static DumpFunc obj_funcs[] = {
812
816
  void
813
817
  oj_dump_obj_val(VALUE obj, int depth, Out out) {
814
818
  int type = rb_type(obj);
815
-
819
+
816
820
  if (Yes == out->opts->trace) {
817
821
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
818
822
  }