json 1.5.3 → 1.5.4

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.

@@ -47,14 +47,14 @@ module JSON
47
47
  # Opens an error dialog on top of _window_ showing the error message
48
48
  # _text_.
49
49
  def Editor.error_dialog(window, text)
50
- dialog = MessageDialog.new(window, Dialog::MODAL,
51
- MessageDialog::ERROR,
50
+ dialog = MessageDialog.new(window, Dialog::MODAL,
51
+ MessageDialog::ERROR,
52
52
  MessageDialog::BUTTONS_CLOSE, text)
53
53
  dialog.show_all
54
54
  dialog.run
55
55
  rescue TypeError
56
- dialog = MessageDialog.new(Editor.window, Dialog::MODAL,
57
- MessageDialog::ERROR,
56
+ dialog = MessageDialog.new(Editor.window, Dialog::MODAL,
57
+ MessageDialog::ERROR,
58
58
  MessageDialog::BUTTONS_CLOSE, text)
59
59
  dialog.show_all
60
60
  dialog.run
@@ -66,8 +66,8 @@ module JSON
66
66
  # message _text_. If yes was answered _true_ is returned, otherwise
67
67
  # _false_.
68
68
  def Editor.question_dialog(window, text)
69
- dialog = MessageDialog.new(window, Dialog::MODAL,
70
- MessageDialog::QUESTION,
69
+ dialog = MessageDialog.new(window, Dialog::MODAL,
70
+ MessageDialog::QUESTION,
71
71
  MessageDialog::BUTTONS_YES_NO, text)
72
72
  dialog.show_all
73
73
  dialog.run do |response|
@@ -464,7 +464,7 @@ module JSON
464
464
  add_separator
465
465
  add_item("Append new node", ?a, &method(:append_new_node))
466
466
  add_item("Insert new node before", ?i, &method(:insert_new_node))
467
- add_separator
467
+ add_separator
468
468
  add_item("Collapse/Expand node (recursively)", ?e,
469
469
  &method(:collapse_expand))
470
470
 
@@ -503,7 +503,7 @@ module JSON
503
503
  # Revert the current JSON document in the editor to the saved version.
504
504
  def revert(item)
505
505
  window.instance_eval do
506
- @filename and file_open(@filename)
506
+ @filename and file_open(@filename)
507
507
  end
508
508
  end
509
509
 
@@ -665,7 +665,7 @@ module JSON
665
665
  collapse_all
666
666
  else
667
667
  self.expanded = true
668
- expand_all
668
+ expand_all
669
669
  end
670
670
  end
671
671
 
@@ -884,7 +884,7 @@ module JSON
884
884
  dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
885
885
  dialog.show_all
886
886
  self.focus = dialog
887
- dialog.run do |response|
887
+ dialog.run do |response|
888
888
  if response == Dialog::RESPONSE_ACCEPT
889
889
  @key = key_input.text
890
890
  type = ALL_TYPES[@type = type_input.active]
@@ -936,7 +936,7 @@ module JSON
936
936
  dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
937
937
  dialog.show_all
938
938
  self.focus = dialog
939
- dialog.run do |response|
939
+ dialog.run do |response|
940
940
  if response == Dialog::RESPONSE_ACCEPT
941
941
  type = types[type_input.active]
942
942
  @content = case type
@@ -981,7 +981,7 @@ module JSON
981
981
  dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
982
982
  dialog.show_all
983
983
  self.focus = dialog
984
- dialog.run do |response|
984
+ dialog.run do |response|
985
985
  if response == Dialog::RESPONSE_ACCEPT
986
986
  return @order = order_input.text, reverse_checkbox.active?
987
987
  end
@@ -1016,7 +1016,7 @@ module JSON
1016
1016
  dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
1017
1017
  dialog.show_all
1018
1018
  self.focus = dialog
1019
- dialog.run do |response|
1019
+ dialog.run do |response|
1020
1020
  if response == Dialog::RESPONSE_ACCEPT
1021
1021
  begin
1022
1022
  return Regexp.new(regex_input.text, icase_checkbox.active? ? Regexp::IGNORECASE : 0)
@@ -1215,7 +1215,7 @@ module JSON
1215
1215
  end
1216
1216
  end
1217
1217
 
1218
- # Save the current file as the filename
1218
+ # Save the current file as the filename
1219
1219
  def file_save_as
1220
1220
  filename = select_file('Save as a JSON file')
1221
1221
  store_file(filename)
@@ -1241,7 +1241,7 @@ module JSON
1241
1241
  rescue SystemCallError => e
1242
1242
  Editor.error_dialog(self, "Failed to store JSON file: #{e}!")
1243
1243
  end
1244
-
1244
+
1245
1245
  # Load the file named _filename_ into the editor as a JSON document.
1246
1246
  def load_file(filename)
1247
1247
  if filename
@@ -1333,7 +1333,7 @@ module JSON
1333
1333
 
1334
1334
  dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
1335
1335
  dialog.show_all
1336
- dialog.run do |response|
1336
+ dialog.run do |response|
1337
1337
  if response == Dialog::RESPONSE_ACCEPT
1338
1338
  return @location = location_input.text
1339
1339
  end
@@ -4,21 +4,8 @@ module JSON
4
4
  # This module holds all the modules/classes that implement JSON's
5
5
  # functionality as C extensions.
6
6
  module Ext
7
- begin
8
- if defined?(RUBY_ENGINE) == 'constant' and RUBY_ENGINE == 'ruby' and RUBY_VERSION =~ /\A1\.9\./
9
- require 'json/ext/1.9/parser'
10
- require 'json/ext/1.9/generator'
11
- elsif !defined?(RUBY_ENGINE) && RUBY_VERSION =~ /\A1\.8\./
12
- require 'json/ext/1.8/parser'
13
- require 'json/ext/1.8/generator'
14
- else
15
- require 'json/ext/parser'
16
- require 'json/ext/generator'
17
- end
18
- rescue LoadError
19
- require 'json/ext/parser'
20
- require 'json/ext/generator'
21
- end
7
+ require 'json/ext/parser'
8
+ require 'json/ext/generator'
22
9
  $DEBUG and warn "Using Ext extension for JSON."
23
10
  JSON.parser = Parser
24
11
  JSON.generator = Generator
@@ -125,7 +125,7 @@ module JSON
125
125
  # * *indent*: a string used to indent levels (default: ''),
126
126
  # * *space*: a string that is put after, a : or , delimiter (default: ''),
127
127
  # * *space_before*: a string that is put before a : pair delimiter (default: ''),
128
- # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
128
+ # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
129
129
  # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
130
130
  # * *check_circular*: is deprecated now, use the :max_nesting option instead,
131
131
  # * *max_nesting*: sets the maximum level of data structure nesting in
@@ -133,6 +133,8 @@ module JSON
133
133
  # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
134
134
  # generated, otherwise an exception is thrown, if these values are
135
135
  # encountered. This options defaults to false.
136
+ # * *quirks_mode*: Enables quirks_mode for parser, that is for example
137
+ # generating single JSON values instead of documents is possible.
136
138
  def initialize(opts = {})
137
139
  @indent = ''
138
140
  @space = ''
@@ -141,6 +143,7 @@ module JSON
141
143
  @array_nl = ''
142
144
  @allow_nan = false
143
145
  @ascii_only = false
146
+ @quirks_mode = false
144
147
  configure opts
145
148
  end
146
149
 
@@ -165,6 +168,10 @@ module JSON
165
168
  # the generated JSON, max_nesting = 0 if no maximum is checked.
166
169
  attr_accessor :max_nesting
167
170
 
171
+ # If this attribute is set to true, quirks mode is enabled, otherwise
172
+ # it's disabled.
173
+ attr_accessor :quirks_mode
174
+
168
175
  # This integer returns the current depth data structure nesting in the
169
176
  # generated JSON.
170
177
  attr_accessor :depth
@@ -188,10 +195,17 @@ module JSON
188
195
  @allow_nan
189
196
  end
190
197
 
198
+ # Returns true, if only ASCII characters should be generated. Otherwise
199
+ # returns false.
191
200
  def ascii_only?
192
201
  @ascii_only
193
202
  end
194
203
 
204
+ # Returns true, if quirks mode is enabled. Otherwise returns false.
205
+ def quirks_mode?
206
+ @quirks_mode
207
+ end
208
+
195
209
  # Configure this State instance with the Hash _opts_, and return
196
210
  # itself.
197
211
  def configure(opts)
@@ -203,6 +217,7 @@ module JSON
203
217
  @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
204
218
  @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
205
219
  @depth = opts[:depth] || 0
220
+ @quirks_mode = opts[:quirks_mode] if opts.key?(:quirks_mode)
206
221
  if !opts.key?(:max_nesting) # defaults to 19
207
222
  @max_nesting = 19
208
223
  elsif opts[:max_nesting]
@@ -218,7 +233,7 @@ module JSON
218
233
  # passed to the configure method.
219
234
  def to_h
220
235
  result = {}
221
- for iv in %w[indent space space_before object_nl array_nl allow_nan max_nesting ascii_only depth]
236
+ for iv in %w[indent space space_before object_nl array_nl allow_nan max_nesting ascii_only quirks_mode depth]
222
237
  result[iv.intern] = instance_variable_get("@#{iv}")
223
238
  end
224
239
  result
@@ -229,7 +244,7 @@ module JSON
229
244
  # GeneratorError exception.
230
245
  def generate(obj)
231
246
  result = obj.to_json(self)
232
- if result !~ /\A\s*(?:\[.*\]|\{.*\})\s*\Z/m
247
+ if !@quirks_mode && result !~ /\A\s*(?:\[.*\]|\{.*\})\s*\Z/m
233
248
  raise GeneratorError, "only generation of JSON objects or arrays allowed"
234
249
  end
235
250
  result
@@ -41,7 +41,7 @@ module JSON
41
41
  [^*/]| # normal chars
42
42
  /[^*]| # slashes that do not start a nested comment
43
43
  \*[^/]| # asterisks that do not end this comment
44
- /(?=\*/) # single slash before this comment's end
44
+ /(?=\*/) # single slash before this comment's end
45
45
  )*
46
46
  \*/ # the End of this comment
47
47
  |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr
@@ -68,42 +68,12 @@ module JSON
68
68
  # defaults to true.
69
69
  # * *object_class*: Defaults to Hash
70
70
  # * *array_class*: Defaults to Array
71
+ # * *quirks_mode*: Enables quirks_mode for parser, that is for example
72
+ # parsing single JSON values instead of documents is possible.
71
73
  def initialize(source, opts = {})
72
74
  opts ||= {}
73
- if defined?(::Encoding)
74
- if source.encoding == ::Encoding::ASCII_8BIT
75
- b = source[0, 4].bytes.to_a
76
- source = case
77
- when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
78
- source.dup.force_encoding(::Encoding::UTF_32BE).encode!(::Encoding::UTF_8)
79
- when b.size >= 4 && b[0] == 0 && b[2] == 0
80
- source.dup.force_encoding(::Encoding::UTF_16BE).encode!(::Encoding::UTF_8)
81
- when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
82
- source.dup.force_encoding(::Encoding::UTF_32LE).encode!(::Encoding::UTF_8)
83
-
84
- when b.size >= 4 && b[1] == 0 && b[3] == 0
85
- source.dup.force_encoding(::Encoding::UTF_16LE).encode!(::Encoding::UTF_8)
86
- else
87
- source.dup
88
- end
89
- else
90
- source = source.encode(::Encoding::UTF_8)
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
75
+ unless @quirks_mode = opts[:quirks_mode]
76
+ source = determine_encoding source
107
77
  end
108
78
  super source
109
79
  if !opts.key?(:max_nesting) # defaults to 19
@@ -113,44 +83,108 @@ module JSON
113
83
  else
114
84
  @max_nesting = 0
115
85
  end
116
- @allow_nan = !!opts[:allow_nan]
117
- @symbolize_names = !!opts[:symbolize_names]
118
- @create_additions = opts.key?(:create_additions) ? !!opts[:create_additions] : true
119
- @create_id = opts[:create_id] || JSON.create_id
120
- @object_class = opts[:object_class] || Hash
121
- @array_class = opts[:array_class] || Array
122
- @match_string = opts[:match_string]
86
+ @allow_nan = !!opts[:allow_nan]
87
+ @symbolize_names = !!opts[:symbolize_names]
88
+ if opts.key?(:create_additions)
89
+ @create_additions = !!opts[:create_additions]
90
+ else
91
+ @create_additions = true
92
+ end
93
+ @create_id = @create_additions ? JSON.create_id : nil
94
+ @object_class = opts[:object_class] || Hash
95
+ @array_class = opts[:array_class] || Array
96
+ @match_string = opts[:match_string]
123
97
  end
124
98
 
125
99
  alias source string
126
100
 
101
+ def quirks_mode?
102
+ !!@quirks_mode
103
+ end
104
+
105
+ def reset
106
+ super
107
+ @current_nesting = 0
108
+ end
109
+
127
110
  # Parses the current JSON string _source_ and returns the complete data
128
111
  # structure as a result.
129
112
  def parse
130
113
  reset
131
114
  obj = nil
132
- until eos?
133
- case
134
- when scan(OBJECT_OPEN)
135
- obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
136
- @current_nesting = 1
137
- obj = parse_object
138
- when scan(ARRAY_OPEN)
139
- obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
140
- @current_nesting = 1
141
- obj = parse_array
142
- when skip(IGNORE)
143
- ;
115
+ if @quirks_mode
116
+ while !eos? && skip(IGNORE)
117
+ end
118
+ if eos?
119
+ raise ParserError, "source did not contain any JSON!"
144
120
  else
145
- raise ParserError, "source '#{peek(20)}' not in JSON!"
121
+ obj = parse_value
122
+ obj == UNPARSED and raise ParserError, "source did not contain any JSON!"
146
123
  end
124
+ else
125
+ until eos?
126
+ case
127
+ when scan(OBJECT_OPEN)
128
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
129
+ @current_nesting = 1
130
+ obj = parse_object
131
+ when scan(ARRAY_OPEN)
132
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
133
+ @current_nesting = 1
134
+ obj = parse_array
135
+ when skip(IGNORE)
136
+ ;
137
+ else
138
+ raise ParserError, "source '#{peek(20)}' not in JSON!"
139
+ end
140
+ end
141
+ obj or raise ParserError, "source did not contain any JSON!"
147
142
  end
148
- obj or raise ParserError, "source did not contain any JSON!"
149
143
  obj
150
144
  end
151
145
 
152
146
  private
153
147
 
148
+ def determine_encoding(source)
149
+ if defined?(::Encoding)
150
+ if source.encoding == ::Encoding::ASCII_8BIT
151
+ b = source[0, 4].bytes.to_a
152
+ source =
153
+ case
154
+ when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
155
+ source.dup.force_encoding(::Encoding::UTF_32BE).encode!(::Encoding::UTF_8)
156
+ when b.size >= 4 && b[0] == 0 && b[2] == 0
157
+ source.dup.force_encoding(::Encoding::UTF_16BE).encode!(::Encoding::UTF_8)
158
+ when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
159
+ source.dup.force_encoding(::Encoding::UTF_32LE).encode!(::Encoding::UTF_8)
160
+ when b.size >= 4 && b[1] == 0 && b[3] == 0
161
+ source.dup.force_encoding(::Encoding::UTF_16LE).encode!(::Encoding::UTF_8)
162
+ else
163
+ source.dup
164
+ end
165
+ else
166
+ source = source.encode(::Encoding::UTF_8)
167
+ end
168
+ source.force_encoding(::Encoding::ASCII_8BIT)
169
+ else
170
+ b = source
171
+ source =
172
+ case
173
+ when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
174
+ JSON.iconv('utf-8', 'utf-32be', b)
175
+ when b.size >= 4 && b[0] == 0 && b[2] == 0
176
+ JSON.iconv('utf-8', 'utf-16be', b)
177
+ when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
178
+ JSON.iconv('utf-8', 'utf-32le', b)
179
+ when b.size >= 4 && b[1] == 0 && b[3] == 0
180
+ JSON.iconv('utf-8', 'utf-16le', b)
181
+ else
182
+ b
183
+ end
184
+ end
185
+ source
186
+ end
187
+
154
188
  # Unescape characters in strings.
155
189
  UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
156
190
  UNESCAPE_MAP.update({
@@ -162,12 +196,12 @@ module JSON
162
196
  ?n => "\n",
163
197
  ?r => "\r",
164
198
  ?t => "\t",
165
- ?u => nil,
199
+ ?u => nil,
166
200
  })
167
201
 
168
202
  EMPTY_8BIT_STRING = ''
169
203
  if ::String.method_defined?(:encode)
170
- EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT
204
+ EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT
171
205
  end
172
206
 
173
207
  def parse_string
@@ -1,6 +1,6 @@
1
1
  module JSON
2
2
  # JSON version
3
- VERSION = '1.5.3'
3
+ VERSION = '1.5.4'
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:
@@ -104,6 +104,42 @@ class TC_JSON < Test::Unit::TestCase
104
104
  assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
105
105
  end
106
106
 
107
+ def test_parse_json_primitive_values
108
+ assert_raise(JSON::ParserError) { JSON.parse('') }
109
+ assert_raise(JSON::ParserError) { JSON.parse('', :quirks_mode => true) }
110
+ assert_raise(JSON::ParserError) { JSON.parse(' /* foo */ ') }
111
+ assert_raise(JSON::ParserError) { JSON.parse(' /* foo */ ', :quirks_mode => true) }
112
+ parser = JSON::Parser.new('null')
113
+ assert_equal false, parser.quirks_mode?
114
+ assert_raise(JSON::ParserError) { parser.parse }
115
+ assert_raise(JSON::ParserError) { JSON.parse('null') }
116
+ assert_equal nil, JSON.parse('null', :quirks_mode => true)
117
+ parser = JSON::Parser.new('null', :quirks_mode => true)
118
+ assert_equal true, parser.quirks_mode?
119
+ assert_equal nil, parser.parse
120
+ assert_raise(JSON::ParserError) { JSON.parse('false') }
121
+ assert_equal false, JSON.parse('false', :quirks_mode => true)
122
+ assert_raise(JSON::ParserError) { JSON.parse('true') }
123
+ assert_equal true, JSON.parse('true', :quirks_mode => true)
124
+ assert_raise(JSON::ParserError) { JSON.parse('23') }
125
+ assert_equal 23, JSON.parse('23', :quirks_mode => true)
126
+ assert_raise(JSON::ParserError) { JSON.parse('1') }
127
+ assert_equal 1, JSON.parse('1', :quirks_mode => true)
128
+ assert_raise(JSON::ParserError) { JSON.parse('3.141') }
129
+ assert_in_delta 3.141, JSON.parse('3.141', :quirks_mode => true), 1E-3
130
+ assert_raise(JSON::ParserError) { JSON.parse('18446744073709551616') }
131
+ assert_equal 2 ** 64, JSON.parse('18446744073709551616', :quirks_mode => true)
132
+ assert_raise(JSON::ParserError) { JSON.parse('"foo"') }
133
+ assert_equal 'foo', JSON.parse('"foo"', :quirks_mode => true)
134
+ assert_raise(JSON::ParserError) { JSON.parse('NaN', :allow_nan => true) }
135
+ assert JSON.parse('NaN', :quirks_mode => true, :allow_nan => true).nan?
136
+ assert_raise(JSON::ParserError) { JSON.parse('Infinity', :allow_nan => true) }
137
+ assert JSON.parse('Infinity', :quirks_mode => true, :allow_nan => true).infinite?
138
+ assert_raise(JSON::ParserError) { JSON.parse('-Infinity', :allow_nan => true) }
139
+ assert JSON.parse('-Infinity', :quirks_mode => true, :allow_nan => true).infinite?
140
+ assert_raise(JSON::ParserError) { JSON.parse('[ 1, ]', :quirks_mode => true) }
141
+ end
142
+
107
143
  if Array.method_defined?(:permutation)
108
144
  def test_parse_more_complex_arrays
109
145
  a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
@@ -150,7 +186,7 @@ class TC_JSON < Test::Unit::TestCase
150
186
  assert_equal(@ary,
151
187
  parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]]'\
152
188
  ',[false],[true]]'))
153
- assert_equal(@ary, parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]
189
+ assert_equal(@ary, parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]\s
154
190
  , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] }))
155
191
  end
156
192
 
@@ -406,4 +442,19 @@ EOT
406
442
  json5 = JSON([orig = 1 << 64])
407
443
  assert_equal orig, JSON[json5][0]
408
444
  end
445
+
446
+ if defined?(JSON::Ext::Parser)
447
+ def test_allocate
448
+ parser = JSON::Ext::Parser.new("{}")
449
+ assert_raise(TypeError, '[ruby-core:35079]') {parser.__send__(:initialize, "{}")}
450
+ parser = JSON::Ext::Parser.allocate
451
+ assert_raise(TypeError, '[ruby-core:35079]') {parser.source}
452
+ end
453
+ end
454
+
455
+ def test_argument_encoding
456
+ source = "{}".force_encoding("ascii-8bit")
457
+ JSON::Parser.new(source)
458
+ assert_equal Encoding::ASCII_8BIT, source.encoding
459
+ end if defined?(Encoding::ASCII_8BIT)
409
460
  end