json 2.2.0 → 2.3.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d5aa01bc44bdf00e8465d5acbde009357987e98ac653672feba63b81f98dfc8
4
- data.tar.gz: 5845322c2daa41d815c4b845c6561d2addf86b459a5c093590317210d6d85901
3
+ metadata.gz: 80444509bc162d6df8e9cc3e7af2fc28507c06aef49cbfc1dd9e5990af42b14f
4
+ data.tar.gz: 8541be9708b44604eeeecac22f89c47933d32c90606f23c1d37e70c8b2d3e9db
5
5
  SHA512:
6
- metadata.gz: f553341d9b8c4d20788255a35a48816a59cacb408f183e8a6009ab9326b66d80078961d4cc9da8e62155e4bb00f31dedddb449cf30afdb386ab6b49e248299dd
7
- data.tar.gz: e74601af87a7ec32952fd596b4981b0d26c4f96ddb88979a26b2fb06604dff204d38ba7c120cd0389756edb83cbd81b6fc569d16f5f7740b8b2915d63cdc8f22
6
+ metadata.gz: 1df7b5ee2bf58103f0b5776c4a581aa3b013ad4b3a85a442d37bb72dc62aaf04dc42ed1080fb307fec1d1e9128c9f21e43827c7f15494cb0f9f310f7189bdc5e
7
+ data.tar.gz: 15ba56ce5d0e04c5326feb9e9faf2627628a715fa4bbeaec5c4aadeab5f27a65135f4f24f142b361f62ca37bbf36380f671d7ae35d46991737e4fc62423a6f9b
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ Gemfile.lock
15
15
  */**/Makefile
16
16
  */**/*.o
17
17
  .byebug_history
18
+ *.log
@@ -4,7 +4,6 @@ language: ruby
4
4
 
5
5
  # Specify which ruby versions you wish to run your tests on, each version will be used
6
6
  rvm:
7
- - 1.9.3
8
7
  - 2.0.0
9
8
  - 2.1
10
9
  - 2.2
@@ -12,12 +11,16 @@ rvm:
12
11
  - 2.4
13
12
  - 2.5
14
13
  - 2.6
14
+ - 2.7.0-preview3
15
15
  - ruby-head
16
16
  - jruby
17
+ - jruby-9.2.7.0
18
+ - truffleruby
17
19
  matrix:
18
20
  allow_failures:
19
- - rvm: 1.9.3
20
21
  - rvm: ruby-head
21
22
  - rvm: jruby
23
+ - rvm: jruby-9.2.7.0
24
+ - rvm: truffleruby
22
25
  script: "bundle exec rake"
23
26
  sudo: false
data/CHANGES.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changes
2
2
 
3
+ ## 2020-06-30 (2.3.1)
4
+
5
+ * Spelling and grammar fixes for comments. Pull request #191 by Josh
6
+ Kline.
7
+ * Enhance generic JSON and #generate docs. Pull request #347 by Victor
8
+ Shepelev.
9
+ * Add :nodoc: for GeneratorMethods. Pull request #349 by Victor Shepelev.
10
+ * Baseline changes to help (JRuby) development. Pull request #371 by Karol
11
+ Bucek.
12
+ * Add metadata for rubygems.org. Pull request #379 by Alexandre ZANNI.
13
+ * Remove invalid JSON.generate description from JSON module rdoc. Pull
14
+ request #384 by Jeremy Evans.
15
+ * Test with TruffleRuby in CI. Pull request #402 by Benoit Daloze.
16
+ * Rdoc enhancements. Pull request #413 by Burdette Lamar.
17
+ * Fixtures/ are not being tested... Pull request #416 by Marc-André
18
+ Lafortune.
19
+ * Use frozen string for hash key. Pull request #420 by Marc-André
20
+ Lafortune.
21
+ * Added :call-seq: to RDoc for some methods. Pull request #422 by Burdette
22
+ Lamar.
23
+ * Small typo fix. Pull request #423 by Marc-André Lafortune.
24
+
25
+ ## 2019-12-11 (2.3.0)
26
+ * Fix default of `create_additions` to always be `false` for `JSON(user_input)`
27
+ and `JSON.parse(user_input, nil)`.
28
+ Note that `JSON.load` remains with default `true` and is meant for internal
29
+ serialization of trusted data. [CVE-2020-10663]
30
+ * Fix passing args all #to_json in json/add/*.
31
+ * Fix encoding issues
32
+ * Fix issues of keyword vs positional parameter
33
+ * Fix JSON::Parser against bigdecimal updates
34
+ * Bug fixes to JRuby port
35
+
3
36
  ## 2019-02-21 (2.2.0)
4
37
  * Adds support for 2.6 BigDecimal and ruby standard library Set datetype.
5
38
 
data/README.md CHANGED
@@ -390,6 +390,22 @@ Here are the median comparisons for completeness' sake:
390
390
  secs/call
391
391
  ```
392
392
 
393
+ ## Development
394
+
395
+ ### Release
396
+
397
+ Update the json.gemspec and json-java.gemspec.
398
+
399
+ ```
400
+ rbenv shell 2.6.5
401
+ rake build
402
+ gem push pkg/json-2.3.0.gem
403
+
404
+ rbenv shell jruby-9.2.9.0
405
+ rake build
406
+ gem push pkg/json-2.3.0-java.gem
407
+ ```
408
+
393
409
  ## Author
394
410
 
395
411
  Florian Frank <mailto:flori@ping.de>
@@ -406,4 +422,4 @@ The latest version of this library can be downloaded at
406
422
 
407
423
  Online Documentation should be located at
408
424
 
409
- * http://json.rubyforge.org
425
+ * https://www.rubydoc.info/gems/json
data/Rakefile CHANGED
@@ -23,8 +23,13 @@ class UndocumentedTestTask < Rake::TestTask
23
23
  def desc(*) end
24
24
  end
25
25
 
26
- MAKE = ENV['MAKE'] || %w[gmake make].find { |c| system(c, '-v') }
27
- BUNDLE = ENV['BUNDLE'] || %w[bundle].find { |c| system(c, '-v') }
26
+ which = lambda { |c|
27
+ w = `which #{c}`
28
+ break w.chomp unless w.empty?
29
+ }
30
+
31
+ MAKE = ENV['MAKE'] || %w[gmake make].find(&which)
32
+ BUNDLE = ENV['BUNDLE'] || %w[bundle].find(&which)
28
33
  PKG_NAME = 'json'
29
34
  PKG_TITLE = 'JSON Implementation for Ruby'
30
35
  PKG_VERSION = File.read('VERSION').chomp
@@ -47,8 +52,8 @@ JAVA_CLASSES = []
47
52
  JRUBY_PARSER_JAR = File.expand_path("lib/json/ext/parser.jar")
48
53
  JRUBY_GENERATOR_JAR = File.expand_path("lib/json/ext/generator.jar")
49
54
 
50
- RAGEL_CODEGEN = %w[rlcodegen rlgen-cd ragel].find { |c| system(c, '-v') }
51
- RAGEL_DOTGEN = %w[rlgen-dot rlgen-cd ragel].find { |c| system(c, '-v') }
55
+ RAGEL_CODEGEN = %w[rlcodegen rlgen-cd ragel].find(&which)
56
+ RAGEL_DOTGEN = %w[rlgen-dot rlgen-cd ragel].find(&which)
52
57
 
53
58
  desc "Installing library (pure)"
54
59
  task :install_pure => :version do
@@ -73,86 +78,6 @@ task :install_ext => [ :compile, :install_pure, :install_ext_really ]
73
78
  desc "Installing library (extension)"
74
79
  task :install => :install_ext
75
80
 
76
- if defined?(Gem) and defined?(Gem::PackageTask)
77
- spec_pure = Gem::Specification.new do |s|
78
- s.name = 'json_pure'
79
- s.version = PKG_VERSION
80
- s.summary = PKG_TITLE
81
- s.description = "This is a JSON implementation in pure Ruby."
82
-
83
- s.files = PKG_FILES
84
-
85
- s.require_path = 'lib'
86
- s.add_development_dependency 'rake'
87
- s.add_development_dependency 'test-unit', '~> 2.0'
88
-
89
- s.extra_rdoc_files << 'README.md'
90
- s.rdoc_options <<
91
- '--title' << 'JSON implemention for ruby' << '--main' << 'README.md'
92
- s.test_files.concat Dir['./tests/test_*.rb']
93
-
94
- s.author = "Florian Frank"
95
- s.email = "flori@ping.de"
96
- s.homepage = "http://flori.github.com/#{PKG_NAME}"
97
- s.license = 'Ruby'
98
- s.required_ruby_version = '>= 1.9'
99
- end
100
-
101
- desc 'Creates a json_pure.gemspec file'
102
- task :gemspec_pure => :version do
103
- File.open('json_pure.gemspec', 'w') do |gemspec|
104
- gemspec.write spec_pure.to_ruby
105
- end
106
- end
107
-
108
- Gem::PackageTask.new(spec_pure) do |pkg|
109
- pkg.need_tar = true
110
- pkg.package_files = PKG_FILES
111
- end
112
-
113
- spec_ext = Gem::Specification.new do |s|
114
- s.name = 'json'
115
- s.version = PKG_VERSION
116
- s.summary = PKG_TITLE
117
- s.description = "This is a JSON implementation as a Ruby extension in C."
118
-
119
- s.files = PKG_FILES
120
-
121
- s.extensions = FileList['ext/**/extconf.rb']
122
-
123
- s.require_path = 'lib'
124
- s.add_development_dependency 'rake'
125
- s.add_development_dependency 'test-unit', '~> 2.0'
126
-
127
- s.extra_rdoc_files << 'README.md'
128
- s.rdoc_options <<
129
- '--title' << 'JSON implemention for Ruby' << '--main' << 'README.md'
130
- s.test_files.concat Dir['./tests/test_*.rb']
131
-
132
- s.author = "Florian Frank"
133
- s.email = "flori@ping.de"
134
- s.homepage = "http://flori.github.com/#{PKG_NAME}"
135
- s.license = 'Ruby'
136
- s.required_ruby_version = '>= 1.9'
137
- end
138
-
139
- desc 'Creates a json.gemspec file'
140
- task :gemspec_ext => :version do
141
- File.open('json.gemspec', 'w') do |gemspec|
142
- gemspec.write spec_ext.to_ruby
143
- end
144
- end
145
-
146
- Gem::PackageTask.new(spec_ext) do |pkg|
147
- pkg.need_tar = true
148
- pkg.package_files = PKG_FILES
149
- end
150
-
151
-
152
- desc 'Create all gemspec files'
153
- task :gemspec => [ :gemspec_pure, :gemspec_ext ]
154
- end
155
-
156
81
  desc m = "Writing version information for #{PKG_VERSION}"
157
82
  task :version do
158
83
  puts m
@@ -176,7 +101,8 @@ task :check_env do
176
101
  end
177
102
 
178
103
  desc "Testing library (pure ruby)"
179
- task :test_pure => [ :clean, :check_env, :do_test_pure ]
104
+ task :test_pure => [ :set_env_pure, :check_env, :do_test_pure ]
105
+ task(:set_env_pure) { ENV['JSON'] = 'pure' }
180
106
 
181
107
  UndocumentedTestTask.new do |t|
182
108
  t.name = 'do_test_pure'
@@ -187,10 +113,7 @@ UndocumentedTestTask.new do |t|
187
113
  end
188
114
 
189
115
  desc "Testing library (pure ruby and extension)"
190
- task :test do
191
- sh "env JSON=pure #{BUNDLE} exec rake test_pure" or exit 1
192
- sh "env JSON=ext #{BUNDLE} exec rake test_ext" or exit 1
193
- end
116
+ task :test => [ :test_pure, :test_ext ]
194
117
 
195
118
  namespace :gems do
196
119
  desc 'Install all development gems'
@@ -257,7 +180,8 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
257
180
  end
258
181
 
259
182
  desc "Testing library (jruby)"
260
- task :test_ext => [ :check_env, :create_jar, :do_test_ext ]
183
+ task :test_ext => [ :set_env_ext, :create_jar, :check_env, :do_test_ext ]
184
+ task(:set_env_ext) { ENV['JSON'] = 'ext' }
261
185
 
262
186
  UndocumentedTestTask.new do |t|
263
187
  t.name = 'do_test_ext'
@@ -363,6 +287,8 @@ else
363
287
  end
364
288
  src = File.read("parser.c").gsub(/[ \t]+$/, '')
365
289
  src.gsub!(/^static const int (JSON_.*=.*);$/, 'enum {\1};')
290
+ src.gsub!(/0 <= \(\*p\) && \(\*p\) <= 31/, "0 <= (signed char)(*p) && (*p) <= 31")
291
+ src[0, 0] = "/* This file is automatically generated from parser.rl by using ragel */"
366
292
  File.open("parser.c", "w") {|f| f.print src}
367
293
  end
368
294
  end
@@ -405,4 +331,4 @@ else
405
331
  end
406
332
 
407
333
  desc "Compile in the the source directory"
408
- task :default => [ :clean, :gemspec, :test ]
334
+ task :default => [ :clean, :test ]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.0
1
+ 2.3.1
@@ -15,7 +15,7 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
15
15
  #endif
16
16
  mFloat, mString, mString_Extend,
17
17
  mTrueClass, mFalseClass, mNilClass, eGeneratorError,
18
- eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE,
18
+ eNestingError,
19
19
  i_SAFE_STATE_PROTOTYPE;
20
20
 
21
21
  static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
@@ -237,6 +237,7 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
237
237
  int escape_len;
238
238
  unsigned char c;
239
239
  char buf[6] = { '\\', 'u' };
240
+ int ascii_only = rb_enc_str_asciionly_p(string);
240
241
 
241
242
  for (start = 0, end = 0; end < len;) {
242
243
  p = ptr + end;
@@ -281,14 +282,17 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
281
282
  break;
282
283
  default:
283
284
  {
284
- unsigned short clen = trailingBytesForUTF8[c] + 1;
285
- if (end + clen > len) {
286
- rb_raise(rb_path2class("JSON::GeneratorError"),
287
- "partial character in source, but hit end");
288
- }
289
- if (!isLegalUTF8((UTF8 *) p, clen)) {
290
- rb_raise(rb_path2class("JSON::GeneratorError"),
291
- "source sequence is illegal/malformed utf-8");
285
+ unsigned short clen = 1;
286
+ if (!ascii_only) {
287
+ clen += trailingBytesForUTF8[c];
288
+ if (end + clen > len) {
289
+ rb_raise(rb_path2class("JSON::GeneratorError"),
290
+ "partial character in source, but hit end");
291
+ }
292
+ if (!isLegalUTF8((UTF8 *) p, clen)) {
293
+ rb_raise(rb_path2class("JSON::GeneratorError"),
294
+ "source sequence is illegal/malformed utf-8");
295
+ }
292
296
  }
293
297
  end += clen;
294
298
  }
@@ -324,6 +328,76 @@ static char *fstrndup(const char *ptr, unsigned long len) {
324
328
  *
325
329
  */
326
330
 
331
+ /* Explanation of the following: that's the only way to not pollute
332
+ * standard library's docs with GeneratorMethods::<ClassName> which
333
+ * are uninformative and take a large place in a list of classes
334
+ */
335
+
336
+ /*
337
+ * Document-module: JSON::Ext::Generator::GeneratorMethods
338
+ * :nodoc:
339
+ */
340
+
341
+ /*
342
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Array
343
+ * :nodoc:
344
+ */
345
+
346
+ /*
347
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Bignum
348
+ * :nodoc:
349
+ */
350
+
351
+ /*
352
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::FalseClass
353
+ * :nodoc:
354
+ */
355
+
356
+ /*
357
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Fixnum
358
+ * :nodoc:
359
+ */
360
+
361
+ /*
362
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Float
363
+ * :nodoc:
364
+ */
365
+
366
+ /*
367
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Hash
368
+ * :nodoc:
369
+ */
370
+
371
+ /*
372
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Integer
373
+ * :nodoc:
374
+ */
375
+
376
+ /*
377
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::NilClass
378
+ * :nodoc:
379
+ */
380
+
381
+ /*
382
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Object
383
+ * :nodoc:
384
+ */
385
+
386
+ /*
387
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::String
388
+ * :nodoc:
389
+ */
390
+
391
+ /*
392
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::String::Extend
393
+ * :nodoc:
394
+ */
395
+
396
+ /*
397
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::TrueClass
398
+ * :nodoc:
399
+ */
400
+
327
401
  /*
328
402
  * call-seq: to_json(state = nil)
329
403
  *
@@ -692,7 +766,7 @@ static VALUE cState_aref(VALUE self, VALUE name)
692
766
  if (RTEST(rb_funcall(self, i_respond_to_p, 1, name))) {
693
767
  return rb_funcall(self, i_send, 1, name);
694
768
  } else {
695
- return rb_ivar_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)));
769
+ return rb_attr_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)));
696
770
  }
697
771
  }
698
772
 
@@ -715,43 +789,83 @@ static VALUE cState_aset(VALUE self, VALUE name, VALUE value)
715
789
  return Qnil;
716
790
  }
717
791
 
718
- static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
792
+ struct hash_foreach_arg {
793
+ FBuffer *buffer;
794
+ JSON_Generator_State *state;
795
+ VALUE Vstate;
796
+ int iter;
797
+ };
798
+
799
+ static int
800
+ json_object_i(VALUE key, VALUE val, VALUE _arg)
719
801
  {
802
+ struct hash_foreach_arg *arg = (struct hash_foreach_arg *)_arg;
803
+ FBuffer *buffer = arg->buffer;
804
+ JSON_Generator_State *state = arg->state;
805
+ VALUE Vstate = arg->Vstate;
806
+
720
807
  char *object_nl = state->object_nl;
721
808
  long object_nl_len = state->object_nl_len;
722
809
  char *indent = state->indent;
723
810
  long indent_len = state->indent_len;
724
- long max_nesting = state->max_nesting;
725
811
  char *delim = FBUFFER_PTR(state->object_delim);
726
812
  long delim_len = FBUFFER_LEN(state->object_delim);
727
813
  char *delim2 = FBUFFER_PTR(state->object_delim2);
728
814
  long delim2_len = FBUFFER_LEN(state->object_delim2);
815
+ long depth = state->depth;
816
+ int j;
817
+ VALUE klass, key_to_s;
818
+
819
+ if (arg->iter > 0) fbuffer_append(buffer, delim, delim_len);
820
+ if (object_nl) {
821
+ fbuffer_append(buffer, object_nl, object_nl_len);
822
+ }
823
+ if (indent) {
824
+ for (j = 0; j < depth; j++) {
825
+ fbuffer_append(buffer, indent, indent_len);
826
+ }
827
+ }
828
+
829
+ klass = CLASS_OF(key);
830
+ if (klass == rb_cString) {
831
+ key_to_s = key;
832
+ } else if (klass == rb_cSymbol) {
833
+ key_to_s = rb_id2str(SYM2ID(key));
834
+ } else {
835
+ key_to_s = rb_funcall(key, i_to_s, 0);
836
+ }
837
+ Check_Type(key_to_s, T_STRING);
838
+ generate_json(buffer, Vstate, state, key_to_s);
839
+ fbuffer_append(buffer, delim2, delim2_len);
840
+ generate_json(buffer, Vstate, state, val);
841
+
842
+ arg->iter++;
843
+ return ST_CONTINUE;
844
+ }
845
+
846
+ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
847
+ {
848
+ char *object_nl = state->object_nl;
849
+ long object_nl_len = state->object_nl_len;
850
+ char *indent = state->indent;
851
+ long indent_len = state->indent_len;
852
+ long max_nesting = state->max_nesting;
729
853
  long depth = ++state->depth;
730
- int i, j;
731
- VALUE key, key_to_s, keys;
854
+ int j;
855
+ struct hash_foreach_arg arg;
856
+
732
857
  if (max_nesting != 0 && depth > max_nesting) {
733
858
  fbuffer_free(buffer);
734
859
  rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
735
860
  }
736
861
  fbuffer_append_char(buffer, '{');
737
- keys = rb_funcall(obj, i_keys, 0);
738
- for(i = 0; i < RARRAY_LEN(keys); i++) {
739
- if (i > 0) fbuffer_append(buffer, delim, delim_len);
740
- if (object_nl) {
741
- fbuffer_append(buffer, object_nl, object_nl_len);
742
- }
743
- if (indent) {
744
- for (j = 0; j < depth; j++) {
745
- fbuffer_append(buffer, indent, indent_len);
746
- }
747
- }
748
- key = rb_ary_entry(keys, i);
749
- key_to_s = rb_funcall(key, i_to_s, 0);
750
- Check_Type(key_to_s, T_STRING);
751
- generate_json(buffer, Vstate, state, key_to_s);
752
- fbuffer_append(buffer, delim2, delim2_len);
753
- generate_json(buffer, Vstate, state, rb_hash_aref(obj, key));
754
- }
862
+
863
+ arg.buffer = buffer;
864
+ arg.state = state;
865
+ arg.Vstate = Vstate;
866
+ arg.iter = 0;
867
+ rb_hash_foreach(obj, json_object_i, (VALUE)&arg);
868
+
755
869
  depth = --state->depth;
756
870
  if (object_nl) {
757
871
  fbuffer_append(buffer, object_nl, object_nl_len);
@@ -802,11 +916,22 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
802
916
  fbuffer_append_char(buffer, ']');
803
917
  }
804
918
 
919
+ #ifdef HAVE_RUBY_ENCODING_H
920
+ static int enc_utf8_compatible_p(rb_encoding *enc)
921
+ {
922
+ if (enc == rb_usascii_encoding()) return 1;
923
+ if (enc == rb_utf8_encoding()) return 1;
924
+ return 0;
925
+ }
926
+ #endif
927
+
805
928
  static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
806
929
  {
807
930
  fbuffer_append_char(buffer, '"');
808
931
  #ifdef HAVE_RUBY_ENCODING_H
809
- obj = rb_funcall(obj, i_encode, 1, CEncoding_UTF_8);
932
+ if (!enc_utf8_compatible_p(rb_enc_get(obj))) {
933
+ obj = rb_str_encode(obj, CEncoding_UTF_8, 0, Qnil);
934
+ }
810
935
  #endif
811
936
  if (state->ascii_only) {
812
937
  convert_UTF8_to_JSON_ASCII(buffer, obj);
@@ -970,6 +1095,8 @@ static VALUE cState_generate(VALUE self, VALUE obj)
970
1095
  * * *allow_nan*: true if NaN, Infinity, and -Infinity should be
971
1096
  * generated, otherwise an exception is thrown, if these values are
972
1097
  * encountered. This options defaults to false.
1098
+ * * *ascii_only*: true if only ASCII characters should be generated. This
1099
+ * option defaults to false.
973
1100
  * * *buffer_initial_length*: sets the initial length of the generator's
974
1101
  * internal buffer.
975
1102
  */
@@ -1025,10 +1152,8 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts)
1025
1152
  } else if (rb_obj_is_kind_of(opts, rb_cHash)) {
1026
1153
  return rb_funcall(self, i_new, 1, opts);
1027
1154
  } else {
1028
- if (NIL_P(CJSON_SAFE_STATE_PROTOTYPE)) {
1029
- CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
1030
- }
1031
- return rb_funcall(CJSON_SAFE_STATE_PROTOTYPE, i_dup, 0);
1155
+ VALUE prototype = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
1156
+ return rb_funcall(prototype, i_dup, 0);
1032
1157
  }
1033
1158
  }
1034
1159
 
@@ -1267,7 +1392,7 @@ static VALUE cState_allow_nan_p(VALUE self)
1267
1392
  /*
1268
1393
  * call-seq: ascii_only?
1269
1394
  *
1270
- * Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise
1395
+ * Returns true, if only ASCII characters should be generated. Otherwise
1271
1396
  * returns false.
1272
1397
  */
1273
1398
  static VALUE cState_ascii_only_p(VALUE self)
@@ -1344,6 +1469,8 @@ void Init_generator(void)
1344
1469
 
1345
1470
  eGeneratorError = rb_path2class("JSON::GeneratorError");
1346
1471
  eNestingError = rb_path2class("JSON::NestingError");
1472
+ rb_gc_register_mark_object(eGeneratorError);
1473
+ rb_gc_register_mark_object(eNestingError);
1347
1474
 
1348
1475
  cState = rb_define_class_under(mGenerator, "State", rb_cObject);
1349
1476
  rb_define_alloc_func(cState, cState_s_allocate);
@@ -1409,7 +1536,6 @@ void Init_generator(void)
1409
1536
  mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass");
1410
1537
  rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1);
1411
1538
 
1412
- CRegexp_MULTILINE = rb_const_get(rb_cRegexp, rb_intern("MULTILINE"));
1413
1539
  i_to_s = rb_intern("to_s");
1414
1540
  i_to_json = rb_intern("to_json");
1415
1541
  i_new = rb_intern("new");
@@ -1440,5 +1566,4 @@ void Init_generator(void)
1440
1566
  i_encode = rb_intern("encode");
1441
1567
  #endif
1442
1568
  i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE");
1443
- CJSON_SAFE_STATE_PROTOTYPE = Qnil;
1444
1569
  }