oj 2.0.3 → 2.0.4

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

Potentially problematic release.


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

data/README.md CHANGED
@@ -32,9 +32,15 @@ A fast JSON parser and Object marshaller as a Ruby gem.
32
32
 
33
33
  ## <a name="release">Release Notes</a>
34
34
 
35
- ### Release 2.0.3
35
+ ### Release 2.0.4
36
36
 
37
- - Fixed round off error in time format when rounding up to the next second.
37
+ - Fixed bug related to long class names.
38
+
39
+ - Change the default for the auto_define option.
40
+
41
+ - Added Oj.strict_load() method that sets the options to public safe options. This should be safe for loading JSON
42
+ documents from a public unverified source. It does not eleviate to need for reasonable programming practices of
43
+ course. See the section on the <a href="#proper_use">proper use of Oj</a> in a public exposure.
38
44
 
39
45
  ## <a name="description">Description</a>
40
46
 
@@ -80,6 +86,21 @@ each element. The Oj::Saj API is useful when only portions of the JSON are of in
80
86
  faster than conventional JSON are possible. The API is simple to use but does require a different approach than the
81
87
  conventional parse followed by access approach used by conventional JSON parsing.
82
88
 
89
+ ## <a name="proper_use">Proper Use</a>
90
+
91
+ Two settings in Oj are useful for parsing but do expose a vunerability if used from an untrusted source. Symbolizing
92
+ keys can be used to cause memory to be filled up since Ruby does not garbage collect Symbols. The same is true for auto
93
+ defining classes. Memory can be exhausted if too many classes are automatically defined. Auto defining is a useful
94
+ feature during development and from trusted sources but it does allow too many classes to be created in the object load
95
+ mode and auto defined is used with an untrusted source. The Oj.strict_load() method sets uses the most strict and safest
96
+ options. It should be used by developers who find it difficult to understand the options available in Oj.
97
+
98
+ The options in Oj are designed to provide flexibility to the developer. This flexibility allows Objects to be serialized
99
+ and deserialized. No methods are ever called on these created Objects but that does not stop the developer from calling
100
+ methods on the Objects created. As in any system, check your inputs before working with them. Taking an arbitrary String
101
+ from a user and evaluating it is never a good idea from an unsecure source. The same is true for Object attributes as
102
+ they are not more than Strings. Always check inputs from untrusted sources.
103
+
83
104
  ## <a name="compare">Comparisons</a>
84
105
 
85
106
  ### Fast Oj::Doc parser comparisons
@@ -268,6 +268,7 @@ dump_unicode(const char *str, const char *end, Out out) {
268
268
  cnt = 5;
269
269
  code = b & 0x00000001;
270
270
  } else {
271
+ cnt = 0;
271
272
  rb_raise(rb_eEncodingError, "Invalid Unicode\n");
272
273
  }
273
274
  str++;
@@ -139,10 +139,12 @@ resolve_classname(VALUE mod, const char *class_name, int auto_define) {
139
139
  VALUE clas;
140
140
  ID ci = rb_intern(class_name);
141
141
 
142
- if (rb_const_defined_at(mod, ci) || !auto_define) {
142
+ if (rb_const_defined_at(mod, ci)) {
143
143
  clas = rb_const_get_at(mod, ci);
144
- } else {
144
+ } else if (auto_define) {
145
145
  clas = rb_define_class_under(mod, class_name, oj_bag_class);
146
+ } else {
147
+ clas = Qundef;
146
148
  }
147
149
  return clas;
148
150
  }
@@ -169,6 +171,7 @@ classname2class(const char *name, ParseInfo pi) {
169
171
  #endif
170
172
  if (Qundef == (clas = oj_cache_get(oj_class_cache, name, &slot))) {
171
173
  char class_name[1024];
174
+ char *end = class_name + sizeof(class_name) - 1;
172
175
  char *s;
173
176
  const char *n = name;
174
177
 
@@ -184,6 +187,8 @@ classname2class(const char *name, ParseInfo pi) {
184
187
  return Qundef;
185
188
  }
186
189
  s = class_name;
190
+ } else if (end <= s) {
191
+ raise_error("Invalid classname, limit is 1024 characters", pi->str, pi->s);
187
192
  } else {
188
193
  *s++ = *n;
189
194
  }
@@ -122,7 +122,7 @@ static const char json_class[] = "json_class";
122
122
  struct _Options oj_default_options = {
123
123
  0, // indent
124
124
  No, // circular
125
- Yes, // auto_define
125
+ No, // auto_define
126
126
  No, // sym_key
127
127
  No, // ascii_only
128
128
  ObjectMode, // mode
@@ -395,8 +395,8 @@ parse_options(VALUE ropts, Options copts) {
395
395
 
396
396
  static VALUE
397
397
  load_with_opts(VALUE input, Options copts) {
398
- char *json;
399
- size_t len;
398
+ char *json = 0;
399
+ size_t len = 0;
400
400
  VALUE obj;
401
401
 
402
402
  if (rb_type(input) == T_STRING) {
@@ -531,6 +531,24 @@ load_file(int argc, VALUE *argv, VALUE self) {
531
531
  return obj;
532
532
  }
533
533
 
534
+ /* call-seq: strict_load(doc)
535
+ *
536
+ * Loads a JSON document in strict mode with auto_define and symbol_keys turned off. This function should be safe to use
537
+ * with JSON received on an unprotected public interface.
538
+ * @param [String|IO] doc JSON String or IO to load
539
+ * @return [Hash|Array|String|Fixnum|Bignum|BigDecimal|nil|True|False]
540
+ */
541
+ static VALUE
542
+ strict_load(VALUE self, VALUE doc) {
543
+ struct _Options options = oj_default_options;
544
+
545
+ options.auto_define = No;
546
+ options.sym_key = No;
547
+ options.mode = StrictMode;
548
+
549
+ return load_with_opts(doc, &options);
550
+ }
551
+
534
552
  /* call-seq: dump(obj, options) => json-string
535
553
  *
536
554
  * Dumps an Object (obj) to a string.
@@ -591,8 +609,8 @@ to_file(int argc, VALUE *argv, VALUE self) {
591
609
  static VALUE
592
610
  saj_parse(int argc, VALUE *argv, VALUE self) {
593
611
  struct _Options copts = oj_default_options;
594
- char *json;
595
- size_t len;
612
+ char *json = 0;
613
+ size_t len = 0;
596
614
  VALUE input = argv[1];
597
615
 
598
616
  if (argc < 2) {
@@ -994,6 +1012,7 @@ void Init_oj() {
994
1012
  rb_define_module_function(Oj, "mimic_JSON", define_mimic_json, -1);
995
1013
  rb_define_module_function(Oj, "load", load, -1);
996
1014
  rb_define_module_function(Oj, "load_file", load_file, -1);
1015
+ rb_define_module_function(Oj, "strict_load", strict_load, 1);
997
1016
  rb_define_module_function(Oj, "dump", dump, -1);
998
1017
  rb_define_module_function(Oj, "to_file", to_file, -1);
999
1018
 
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '2.0.3'
4
+ VERSION = '2.0.4'
5
5
  end
@@ -1 +1,2 @@
1
- Oj.load('{":s": 1}', :symbol_keys => true)
1
+ Oj.load(%{{"json_class":"#{'x'*1300}"}})
2
+
@@ -112,7 +112,7 @@ class Juice < ::Test::Unit::TestCase
112
112
  assert_equal({ :indent=>0,
113
113
  :second_precision=>9,
114
114
  :circular=>false,
115
- :auto_define=>true,
115
+ :auto_define=>false,
116
116
  :symbol_keys=>false,
117
117
  :ascii_only=>false,
118
118
  :mode=>:object,
@@ -126,7 +126,7 @@ class Juice < ::Test::Unit::TestCase
126
126
  :indent=>0,
127
127
  :second_precision=>9,
128
128
  :circular=>false,
129
- :auto_define=>true,
129
+ :auto_define=>false,
130
130
  :symbol_keys=>false,
131
131
  :ascii_only=>false,
132
132
  :mode=>:object,
@@ -137,7 +137,7 @@ class Juice < ::Test::Unit::TestCase
137
137
  :indent=>4,
138
138
  :second_precision=>7,
139
139
  :circular=>true,
140
- :auto_define=>false,
140
+ :auto_define=>true,
141
141
  :symbol_keys=>true,
142
142
  :ascii_only=>true,
143
143
  :mode=>:compat,
@@ -818,7 +818,7 @@ class Juice < ::Test::Unit::TestCase
818
818
  "^o":"Jem",
819
819
  "x":true,
820
820
  "y":58 }}
821
- obj = Oj.load(json, :mode => :object)
821
+ obj = Oj.load(json, :mode => :object, :auto_define => true)
822
822
  assert_equal('Jem', obj.class.name)
823
823
  assert_equal(true, obj.x)
824
824
  assert_equal(58, obj.y)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-03 00:00:00.000000000 Z
12
+ date: 2013-02-11 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! 'The fastest JSON parser and object serializer. '
15
15
  email: peter@ohler.com
@@ -97,3 +97,4 @@ signing_key:
97
97
  specification_version: 3
98
98
  summary: A fast JSON parser and serializer.
99
99
  test_files: []
100
+ has_rdoc: true