json 2.7.5 → 2.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,331 +0,0 @@
1
- #frozen_string_literal: true
2
- require 'strscan'
3
-
4
- module JSON
5
- module Pure
6
- # This class implements the JSON parser that is used to parse a JSON string
7
- # into a Ruby data structure.
8
- class Parser < StringScanner
9
- STRING = /" ((?:[^\x0-\x1f"\\] |
10
- # escaped special characters:
11
- \\["\\\/bfnrt] |
12
- \\u[0-9a-fA-F]{4} |
13
- # match all but escaped special characters:
14
- \\[\x20-\x21\x23-\x2e\x30-\x5b\x5d-\x61\x63-\x65\x67-\x6d\x6f-\x71\x73\x75-\xff])*)
15
- "/nx
16
- INTEGER = /(-?0|-?[1-9]\d*)/
17
- FLOAT = /(-?
18
- (?:0|[1-9]\d*)
19
- (?:
20
- \.\d+(?i:e[+-]?\d+) |
21
- \.\d+ |
22
- (?i:e[+-]?\d+)
23
- )
24
- )/x
25
- NAN = /NaN/
26
- INFINITY = /Infinity/
27
- MINUS_INFINITY = /-Infinity/
28
- OBJECT_OPEN = /\{/
29
- OBJECT_CLOSE = /\}/
30
- ARRAY_OPEN = /\[/
31
- ARRAY_CLOSE = /\]/
32
- PAIR_DELIMITER = /:/
33
- COLLECTION_DELIMITER = /,/
34
- TRUE = /true/
35
- FALSE = /false/
36
- NULL = /null/
37
- IGNORE = %r(
38
- (?:
39
- //[^\n\r]*[\n\r]| # line comments
40
- /\* # c-style comments
41
- (?:
42
- [\s\S]*? # any char, repeated lazily
43
- )
44
- \*/ # the End of this comment
45
- |[ \t\r\n]+ # whitespaces: space, horizontal tab, lf, cr
46
- )+
47
- )mx
48
-
49
- UNPARSED = Object.new.freeze
50
-
51
- # Creates a new JSON::Pure::Parser instance for the string _source_.
52
- #
53
- # It will be configured by the _opts_ hash. _opts_ can have the following
54
- # keys:
55
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
56
- # structures. Disable depth checking with :max_nesting => false|nil|0,
57
- # it defaults to 100.
58
- # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
59
- # defiance of RFC 7159 to be parsed by the Parser. This option defaults
60
- # to false.
61
- # * *freeze*: If set to true, all parsed objects will be frozen. Parsed
62
- # string will be deduplicated if possible.
63
- # * *symbolize_names*: If set to true, returns symbols for the names
64
- # (keys) in a JSON object. Otherwise strings are returned, which is
65
- # also the default. It's not possible to use this option in
66
- # conjunction with the *create_additions* option.
67
- # * *create_additions*: If set to true, the Parser creates
68
- # additions when a matching class and create_id are found. This
69
- # option defaults to false.
70
- # * *object_class*: Defaults to Hash. If another type is provided, it will be used
71
- # instead of Hash to represent JSON objects. The type must respond to
72
- # +new+ without arguments, and return an object that respond to +[]=+.
73
- # * *array_class*: Defaults to Array If another type is provided, it will be used
74
- # instead of Hash to represent JSON arrays. The type must respond to
75
- # +new+ without arguments, and return an object that respond to +<<+.
76
- # * *decimal_class*: Specifies which class to use instead of the default
77
- # (Float) when parsing decimal numbers. This class must accept a single
78
- # string argument in its constructor.
79
- def initialize(source, opts = nil)
80
- opts ||= {}
81
- source = convert_encoding source
82
- super source
83
- if !opts.key?(:max_nesting) # defaults to 100
84
- @max_nesting = 100
85
- elsif opts[:max_nesting]
86
- @max_nesting = opts[:max_nesting]
87
- else
88
- @max_nesting = 0
89
- end
90
- @allow_nan = !!opts[:allow_nan]
91
- @symbolize_names = !!opts[:symbolize_names]
92
- @freeze = !!opts[:freeze]
93
- if opts.key?(:create_additions)
94
- @create_additions = !!opts[:create_additions]
95
- else
96
- @create_additions = false
97
- end
98
- @symbolize_names && @create_additions and raise ArgumentError,
99
- 'options :symbolize_names and :create_additions cannot be used '\
100
- 'in conjunction'
101
- @create_id = @create_additions ? JSON.create_id : nil
102
- @object_class = opts[:object_class] || Hash
103
- @array_class = opts[:array_class] || Array
104
- @decimal_class = opts[:decimal_class]
105
- @match_string = opts[:match_string]
106
- end
107
-
108
- alias source string
109
-
110
- def reset
111
- super
112
- @current_nesting = 0
113
- end
114
-
115
- # Parses the current JSON string _source_ and returns the
116
- # complete data structure as a result.
117
- def parse
118
- reset
119
- obj = nil
120
- while !eos? && skip(IGNORE) do end
121
- if eos?
122
- raise ParserError, "source is not valid JSON!"
123
- else
124
- obj = parse_value
125
- UNPARSED.equal?(obj) and raise ParserError,
126
- "source is not valid JSON!"
127
- obj.freeze if @freeze
128
- end
129
- while !eos? && skip(IGNORE) do end
130
- eos? or raise ParserError, "source is not valid JSON!"
131
- obj
132
- end
133
-
134
- private
135
-
136
- def convert_encoding(source)
137
- if source.respond_to?(:to_str)
138
- source = source.to_str
139
- else
140
- raise TypeError,
141
- "#{source.inspect} is not like a string"
142
- end
143
- if source.encoding != ::Encoding::ASCII_8BIT
144
- source = source.encode(::Encoding::UTF_8)
145
- source.force_encoding(::Encoding::ASCII_8BIT)
146
- end
147
- source
148
- end
149
-
150
- # Unescape characters in strings.
151
- UNESCAPE_MAP = {
152
- '"' => '"',
153
- '\\' => '\\',
154
- '/' => '/',
155
- 'b' => "\b",
156
- 'f' => "\f",
157
- 'n' => "\n",
158
- 'r' => "\r",
159
- 't' => "\t",
160
- 'u' => nil,
161
- }.freeze
162
-
163
- STR_UMINUS = ''.respond_to?(:-@)
164
- def parse_string
165
- if scan(STRING)
166
- return '' if self[1].empty?
167
- string = self[1].gsub(%r{(?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff])}n) do |c|
168
- k = $&[1]
169
- if u = UNESCAPE_MAP.fetch(k) { k.chr }
170
- u
171
- else # \uXXXX
172
- bytes = ''.b
173
- i = 0
174
- while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
175
- bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
176
- i += 1
177
- end
178
- bytes.encode(Encoding::UTF_8, Encoding::UTF_16BE).force_encoding(::Encoding::BINARY)
179
- end
180
- end
181
- string.force_encoding(::Encoding::UTF_8)
182
-
183
- if @freeze
184
- if STR_UMINUS
185
- string = -string
186
- else
187
- string.freeze
188
- end
189
- end
190
-
191
- if @create_additions and @match_string
192
- for (regexp, klass) in @match_string
193
- klass.json_creatable? or next
194
- string =~ regexp and return klass.json_create(string)
195
- end
196
- end
197
- string
198
- else
199
- UNPARSED
200
- end
201
- rescue => e
202
- raise ParserError, "Caught #{e.class} at '#{peek(20)}': #{e}"
203
- end
204
-
205
- def parse_value
206
- case
207
- when scan(FLOAT)
208
- if @decimal_class then
209
- if @decimal_class == BigDecimal then
210
- BigDecimal(self[1])
211
- else
212
- @decimal_class.new(self[1]) || Float(self[1])
213
- end
214
- else
215
- Float(self[1])
216
- end
217
- when scan(INTEGER)
218
- Integer(self[1])
219
- when scan(TRUE)
220
- true
221
- when scan(FALSE)
222
- false
223
- when scan(NULL)
224
- nil
225
- when !UNPARSED.equal?(string = parse_string)
226
- string
227
- when scan(ARRAY_OPEN)
228
- @current_nesting += 1
229
- ary = parse_array
230
- @current_nesting -= 1
231
- ary
232
- when scan(OBJECT_OPEN)
233
- @current_nesting += 1
234
- obj = parse_object
235
- @current_nesting -= 1
236
- obj
237
- when @allow_nan && scan(NAN)
238
- NaN
239
- when @allow_nan && scan(INFINITY)
240
- Infinity
241
- when @allow_nan && scan(MINUS_INFINITY)
242
- MinusInfinity
243
- else
244
- UNPARSED
245
- end
246
- end
247
-
248
- def parse_array
249
- raise NestingError, "nesting of #@current_nesting is too deep" if
250
- @max_nesting.nonzero? && @current_nesting > @max_nesting
251
- result = @array_class.new
252
- delim = false
253
- loop do
254
- case
255
- when eos?
256
- raise ParserError, "unexpected end of string while parsing array"
257
- when !UNPARSED.equal?(value = parse_value)
258
- delim = false
259
- result << value
260
- skip(IGNORE)
261
- if scan(COLLECTION_DELIMITER)
262
- delim = true
263
- elsif match?(ARRAY_CLOSE)
264
- ;
265
- else
266
- raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
267
- end
268
- when scan(ARRAY_CLOSE)
269
- if delim
270
- raise ParserError, "expected next element in array at '#{peek(20)}'!"
271
- end
272
- break
273
- when skip(IGNORE)
274
- ;
275
- else
276
- raise ParserError, "unexpected token in array at '#{peek(20)}'!"
277
- end
278
- end
279
- result
280
- end
281
-
282
- def parse_object
283
- raise NestingError, "nesting of #@current_nesting is too deep" if
284
- @max_nesting.nonzero? && @current_nesting > @max_nesting
285
- result = @object_class.new
286
- delim = false
287
- loop do
288
- case
289
- when eos?
290
- raise ParserError, "unexpected end of string while parsing object"
291
- when !UNPARSED.equal?(string = parse_string)
292
- skip(IGNORE)
293
- unless scan(PAIR_DELIMITER)
294
- raise ParserError, "expected ':' in object at '#{peek(20)}'!"
295
- end
296
- skip(IGNORE)
297
- unless UNPARSED.equal?(value = parse_value)
298
- result[@symbolize_names ? string.to_sym : string] = value
299
- delim = false
300
- skip(IGNORE)
301
- if scan(COLLECTION_DELIMITER)
302
- delim = true
303
- elsif match?(OBJECT_CLOSE)
304
- ;
305
- else
306
- raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
307
- end
308
- else
309
- raise ParserError, "expected value in object at '#{peek(20)}'!"
310
- end
311
- when scan(OBJECT_CLOSE)
312
- if delim
313
- raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
314
- end
315
- if @create_additions and klassname = result[@create_id]
316
- klass = JSON.deep_const_get klassname
317
- break unless klass and klass.json_creatable?
318
- result = klass.json_create(result)
319
- end
320
- break
321
- when skip(IGNORE)
322
- ;
323
- else
324
- raise ParserError, "unexpected token in object at '#{peek(20)}'!"
325
- end
326
- end
327
- result
328
- end
329
- end
330
- end
331
- end
data/lib/json/pure.rb DELETED
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'json/common'
3
-
4
- module JSON
5
- # This module holds all the modules/classes that implement JSON's
6
- # functionality in pure ruby.
7
- module Pure
8
- require 'json/pure/parser'
9
- require 'json/pure/generator'
10
- $DEBUG and warn "Using Pure library for JSON."
11
- JSON.parser = Parser
12
- JSON.generator = Generator
13
- end
14
-
15
- JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
16
- end