oj 3.9.2 → 3.10.18

Sign up to get free protection for your applications and to get access to all the features.
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
  }