activesupport 2.3.15 → 2.3.16

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

Potentially problematic release.


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

@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 35c91c93ca5afc2bf63abffbc68b17b58c02f5b1
4
+ data.tar.gz: 302dded5230559b2fccd62e0f9a8a2e77bc884e6
5
+ SHA512:
6
+ metadata.gz: c7baffba66eeb3f966981ffda3545a69a2084fccf9b08606d6df7de150c54965a6a410cace6396c1d31ee027322061bd9843dd607cfae1ce46ca74260da85135
7
+ data.tar.gz: 39f392723fa015bfec08e2f7e8277470ac41da7efffc0edf6c6285971f2e1302ff82d8158943dc77ec817c00f75133d2c0cd26f4f4e1bda9838f0c2bd71a631b
@@ -18,6 +18,7 @@ class MissingSourceFile < LoadError #:nodoc:
18
18
  end
19
19
 
20
20
  REGEXPS = [
21
+ [/^cannot load such file -- (.+)$/i, 1],
21
22
  [/^no such file to load -- (.+)$/i, 1],
22
23
  [/^Missing \w+ (file\s*)?([^\s]+.rb)$/i, 2],
23
24
  [/^Missing API definition file in (.+)$/i, 1]
@@ -2,13 +2,13 @@ require 'erb'
2
2
 
3
3
  class ERB
4
4
  module Util
5
- HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;' }
5
+ HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#x27;' }
6
6
  JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
7
7
 
8
8
  # A utility method for escaping HTML tag characters.
9
9
  # This method is also aliased as <tt>h</tt>.
10
10
  #
11
- # In your ERb templates, use this method to escape any unsafe content. For example:
11
+ # In your ERB templates, use this method to escape any unsafe content. For example:
12
12
  # <%=h @person.name %>
13
13
  #
14
14
  # ==== Example:
@@ -19,7 +19,7 @@ class ERB
19
19
  if s.html_safe?
20
20
  s
21
21
  else
22
- s.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;").html_safe
22
+ s.gsub(/[&"'><]/n) { |special| HTML_ESCAPE[special] }.html_safe
23
23
  end
24
24
  end
25
25
 
@@ -0,0 +1,644 @@
1
+ module ActiveSupport
2
+ # Include OkJson as a replacement for the Yaml backend
3
+ # encoding: UTF-8
4
+ #
5
+ # Copyright 2011, 2012 Keith Rarick
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
25
+ # See https://github.com/kr/okjson for updates.
26
+
27
+ require 'stringio'
28
+
29
+ # Some parts adapted from
30
+ # http://golang.org/src/pkg/json/decode.go and
31
+ # http://golang.org/src/pkg/utf8/utf8.go
32
+ module OkJson
33
+ Upstream = 'LTD7LBKLZWFF7OZK'
34
+ extend self
35
+
36
+
37
+ # Decodes a json document in string s and
38
+ # returns the corresponding ruby value.
39
+ # String s must be valid UTF-8. If you have
40
+ # a string in some other encoding, convert
41
+ # it first.
42
+ #
43
+ # String values in the resulting structure
44
+ # will be UTF-8.
45
+ def decode(s)
46
+ ts = lex(s)
47
+ v, ts = textparse(ts)
48
+ if ts.length > 0
49
+ raise Error, 'trailing garbage'
50
+ end
51
+ v
52
+ end
53
+
54
+
55
+ # Parses a "json text" in the sense of RFC 4627.
56
+ # Returns the parsed value and any trailing tokens.
57
+ # Note: this is almost the same as valparse,
58
+ # except that it does not accept atomic values.
59
+ def textparse(ts)
60
+ if ts.length < 0
61
+ raise Error, 'empty'
62
+ end
63
+
64
+ typ, _, val = ts[0]
65
+ case typ
66
+ when '{' then objparse(ts)
67
+ when '[' then arrparse(ts)
68
+ else
69
+ raise Error, "unexpected #{val.inspect}"
70
+ end
71
+ end
72
+
73
+
74
+ # Parses a "value" in the sense of RFC 4627.
75
+ # Returns the parsed value and any trailing tokens.
76
+ def valparse(ts)
77
+ if ts.length < 0
78
+ raise Error, 'empty'
79
+ end
80
+
81
+ typ, _, val = ts[0]
82
+ case typ
83
+ when '{' then objparse(ts)
84
+ when '[' then arrparse(ts)
85
+ when :val,:str then [val, ts[1..-1]]
86
+ else
87
+ raise Error, "unexpected #{val.inspect}"
88
+ end
89
+ end
90
+
91
+
92
+ # Parses an "object" in the sense of RFC 4627.
93
+ # Returns the parsed value and any trailing tokens.
94
+ def objparse(ts)
95
+ ts = eat('{', ts)
96
+ obj = {}
97
+
98
+ if ts[0][0] == '}'
99
+ return obj, ts[1..-1]
100
+ end
101
+
102
+ k, v, ts = pairparse(ts)
103
+ obj[k] = v
104
+
105
+ if ts[0][0] == '}'
106
+ return obj, ts[1..-1]
107
+ end
108
+
109
+ loop do
110
+ ts = eat(',', ts)
111
+
112
+ k, v, ts = pairparse(ts)
113
+ obj[k] = v
114
+
115
+ if ts[0][0] == '}'
116
+ return obj, ts[1..-1]
117
+ end
118
+ end
119
+ end
120
+
121
+
122
+ # Parses a "member" in the sense of RFC 4627.
123
+ # Returns the parsed values and any trailing tokens.
124
+ def pairparse(ts)
125
+ (typ, _, k), ts = ts[0], ts[1..-1]
126
+ if typ != :str
127
+ raise Error, "unexpected #{k.inspect}"
128
+ end
129
+ ts = eat(':', ts)
130
+ v, ts = valparse(ts)
131
+ [k, v, ts]
132
+ end
133
+
134
+
135
+ # Parses an "array" in the sense of RFC 4627.
136
+ # Returns the parsed value and any trailing tokens.
137
+ def arrparse(ts)
138
+ ts = eat('[', ts)
139
+ arr = []
140
+
141
+ if ts[0][0] == ']'
142
+ return arr, ts[1..-1]
143
+ end
144
+
145
+ v, ts = valparse(ts)
146
+ arr << v
147
+
148
+ if ts[0][0] == ']'
149
+ return arr, ts[1..-1]
150
+ end
151
+
152
+ loop do
153
+ ts = eat(',', ts)
154
+
155
+ v, ts = valparse(ts)
156
+ arr << v
157
+
158
+ if ts[0][0] == ']'
159
+ return arr, ts[1..-1]
160
+ end
161
+ end
162
+ end
163
+
164
+
165
+ def eat(typ, ts)
166
+ if ts[0][0] != typ
167
+ raise Error, "expected #{typ} (got #{ts[0].inspect})"
168
+ end
169
+ ts[1..-1]
170
+ end
171
+
172
+
173
+ # Scans s and returns a list of json tokens,
174
+ # excluding white space (as defined in RFC 4627).
175
+ def lex(s)
176
+ ts = []
177
+ while s.length > 0
178
+ typ, lexeme, val = tok(s)
179
+ if typ == nil
180
+ raise Error, "invalid character at #{s[0,10].inspect}"
181
+ end
182
+ if typ != :space
183
+ ts << [typ, lexeme, val]
184
+ end
185
+ s = s[lexeme.length..-1]
186
+ end
187
+ ts
188
+ end
189
+
190
+
191
+ # Scans the first token in s and
192
+ # returns a 3-element list, or nil
193
+ # if s does not begin with a valid token.
194
+ #
195
+ # The first list element is one of
196
+ # '{', '}', ':', ',', '[', ']',
197
+ # :val, :str, and :space.
198
+ #
199
+ # The second element is the lexeme.
200
+ #
201
+ # The third element is the value of the
202
+ # token for :val and :str, otherwise
203
+ # it is the lexeme.
204
+ def tok(s)
205
+ case s[0]
206
+ when ?{ then ['{', s[0,1], s[0,1]]
207
+ when ?} then ['}', s[0,1], s[0,1]]
208
+ when ?: then [':', s[0,1], s[0,1]]
209
+ when ?, then [',', s[0,1], s[0,1]]
210
+ when ?[ then ['[', s[0,1], s[0,1]]
211
+ when ?] then [']', s[0,1], s[0,1]]
212
+ when ?n then nulltok(s)
213
+ when ?t then truetok(s)
214
+ when ?f then falsetok(s)
215
+ when ?" then strtok(s)
216
+ when Spc then [:space, s[0,1], s[0,1]]
217
+ when ?\t then [:space, s[0,1], s[0,1]]
218
+ when ?\n then [:space, s[0,1], s[0,1]]
219
+ when ?\r then [:space, s[0,1], s[0,1]]
220
+ else numtok(s)
221
+ end
222
+ end
223
+
224
+
225
+ def nulltok(s); s[0,4] == 'null' ? [:val, 'null', nil] : [] end
226
+ def truetok(s); s[0,4] == 'true' ? [:val, 'true', true] : [] end
227
+ def falsetok(s); s[0,5] == 'false' ? [:val, 'false', false] : [] end
228
+
229
+
230
+ def numtok(s)
231
+ m = /-?([1-9][0-9]+|[0-9])([.][0-9]+)?([eE][+-]?[0-9]+)?/.match(s)
232
+ if m && m.begin(0) == 0
233
+ if m[3] && !m[2]
234
+ [:val, m[0], Integer(m[1])*(10**Integer(m[3][1..-1]))]
235
+ elsif m[2]
236
+ [:val, m[0], Float(m[0])]
237
+ else
238
+ [:val, m[0], Integer(m[0])]
239
+ end
240
+ else
241
+ []
242
+ end
243
+ end
244
+
245
+
246
+ def strtok(s)
247
+ m = /"([^"\\]|\\["\/\\bfnrt]|\\u[0-9a-fA-F]{4})*"/.match(s)
248
+ if ! m
249
+ raise Error, "invalid string literal at #{abbrev(s)}"
250
+ end
251
+ [:str, m[0], unquote(m[0])]
252
+ end
253
+
254
+
255
+ def abbrev(s)
256
+ t = s[0,10]
257
+ p = t['`']
258
+ t = t[0,p] if p
259
+ t = t + '...' if t.length < s.length
260
+ '`' + t + '`'
261
+ end
262
+
263
+
264
+ # Converts a quoted json string literal q into a UTF-8-encoded string.
265
+ # The rules are different than for Ruby, so we cannot use eval.
266
+ # Unquote will raise an error if q contains control characters.
267
+ def unquote(q)
268
+ q = q[1...-1]
269
+ a = q.dup # allocate a big enough string
270
+ rubydoesenc = false
271
+ # In ruby >= 1.9, a[w] is a codepoint, not a byte.
272
+ if a.class.method_defined?(:force_encoding)
273
+ a.force_encoding('UTF-8')
274
+ rubydoesenc = true
275
+ end
276
+ r, w = 0, 0
277
+ while r < q.length
278
+ c = q[r]
279
+ case true
280
+ when c == ?\\
281
+ r += 1
282
+ if r >= q.length
283
+ raise Error, "string literal ends with a \"\\\": \"#{q}\""
284
+ end
285
+
286
+ case q[r]
287
+ when ?",?\\,?/,?'
288
+ a[w] = q[r]
289
+ r += 1
290
+ w += 1
291
+ when ?b,?f,?n,?r,?t
292
+ a[w] = Unesc[q[r]]
293
+ r += 1
294
+ w += 1
295
+ when ?u
296
+ r += 1
297
+ uchar = begin
298
+ hexdec4(q[r,4])
299
+ rescue RuntimeError => e
300
+ raise Error, "invalid escape sequence \\u#{q[r,4]}: #{e}"
301
+ end
302
+ r += 4
303
+ if surrogate? uchar
304
+ if q.length >= r+6
305
+ uchar1 = hexdec4(q[r+2,4])
306
+ uchar = subst(uchar, uchar1)
307
+ if uchar != Ucharerr
308
+ # A valid pair; consume.
309
+ r += 6
310
+ end
311
+ end
312
+ end
313
+ if rubydoesenc
314
+ a[w] = '' << uchar
315
+ w += 1
316
+ else
317
+ w += ucharenc(a, w, uchar)
318
+ end
319
+ else
320
+ raise Error, "invalid escape char #{q[r]} in \"#{q}\""
321
+ end
322
+ when c == ?", c < Spc
323
+ raise Error, "invalid character in string literal \"#{q}\""
324
+ else
325
+ # Copy anything else byte-for-byte.
326
+ # Valid UTF-8 will remain valid UTF-8.
327
+ # Invalid UTF-8 will remain invalid UTF-8.
328
+ # In ruby >= 1.9, c is a codepoint, not a byte,
329
+ # in which case this is still what we want.
330
+ a[w] = c
331
+ r += 1
332
+ w += 1
333
+ end
334
+ end
335
+ a[0,w]
336
+ end
337
+
338
+
339
+ # Encodes unicode character u as UTF-8
340
+ # bytes in string a at position i.
341
+ # Returns the number of bytes written.
342
+ def ucharenc(a, i, u)
343
+ case true
344
+ when u <= Uchar1max
345
+ a[i] = (u & 0xff).chr
346
+ 1
347
+ when u <= Uchar2max
348
+ a[i+0] = (Utag2 | ((u>>6)&0xff)).chr
349
+ a[i+1] = (Utagx | (u&Umaskx)).chr
350
+ 2
351
+ when u <= Uchar3max
352
+ a[i+0] = (Utag3 | ((u>>12)&0xff)).chr
353
+ a[i+1] = (Utagx | ((u>>6)&Umaskx)).chr
354
+ a[i+2] = (Utagx | (u&Umaskx)).chr
355
+ 3
356
+ else
357
+ a[i+0] = (Utag4 | ((u>>18)&0xff)).chr
358
+ a[i+1] = (Utagx | ((u>>12)&Umaskx)).chr
359
+ a[i+2] = (Utagx | ((u>>6)&Umaskx)).chr
360
+ a[i+3] = (Utagx | (u&Umaskx)).chr
361
+ 4
362
+ end
363
+ end
364
+
365
+
366
+ def hexdec4(s)
367
+ if s.length != 4
368
+ raise Error, 'short'
369
+ end
370
+ (nibble(s[0])<<12) | (nibble(s[1])<<8) | (nibble(s[2])<<4) | nibble(s[3])
371
+ end
372
+
373
+
374
+ def subst(u1, u2)
375
+ if Usurr1 <= u1 && u1 < Usurr2 && Usurr2 <= u2 && u2 < Usurr3
376
+ return ((u1-Usurr1)<<10) | (u2-Usurr2) + Usurrself
377
+ end
378
+ return Ucharerr
379
+ end
380
+
381
+
382
+ def surrogate?(u)
383
+ Usurr1 <= u && u < Usurr3
384
+ end
385
+
386
+
387
+ def nibble(c)
388
+ case true
389
+ when ?0 <= c && c <= ?9 then c.ord - ?0.ord
390
+ when ?a <= c && c <= ?z then c.ord - ?a.ord + 10
391
+ when ?A <= c && c <= ?Z then c.ord - ?A.ord + 10
392
+ else
393
+ raise Error, "invalid hex code #{c}"
394
+ end
395
+ end
396
+
397
+
398
+ # Encodes x into a json text. It may contain only
399
+ # Array, Hash, String, Numeric, true, false, nil.
400
+ # (Note, this list excludes Symbol.)
401
+ # X itself must be an Array or a Hash.
402
+ # No other value can be encoded, and an error will
403
+ # be raised if x contains any other value, such as
404
+ # Nan, Infinity, Symbol, and Proc, or if a Hash key
405
+ # is not a String.
406
+ # Strings contained in x must be valid UTF-8.
407
+ def encode(x)
408
+ case x
409
+ when Hash then objenc(x)
410
+ when Array then arrenc(x)
411
+ else
412
+ raise Error, 'root value must be an Array or a Hash'
413
+ end
414
+ end
415
+
416
+
417
+ def valenc(x)
418
+ case x
419
+ when Hash then objenc(x)
420
+ when Array then arrenc(x)
421
+ when String then strenc(x)
422
+ when Numeric then numenc(x)
423
+ when true then "true"
424
+ when false then "false"
425
+ when nil then "null"
426
+ else
427
+ raise Error, "cannot encode #{x.class}: #{x.inspect}"
428
+ end
429
+ end
430
+
431
+
432
+ def objenc(x)
433
+ '{' + x.map{|k,v| keyenc(k) + ':' + valenc(v)}.join(',') + '}'
434
+ end
435
+
436
+
437
+ def arrenc(a)
438
+ '[' + a.map{|x| valenc(x)}.join(',') + ']'
439
+ end
440
+
441
+
442
+ def keyenc(k)
443
+ case k
444
+ when String then strenc(k)
445
+ else
446
+ raise Error, "Hash key is not a string: #{k.inspect}"
447
+ end
448
+ end
449
+
450
+
451
+ def strenc(s)
452
+ t = StringIO.new
453
+ t.putc(?")
454
+ r = 0
455
+
456
+ # In ruby >= 1.9, s[r] is a codepoint, not a byte.
457
+ rubydoesenc = s.class.method_defined?(:encoding)
458
+
459
+ while r < s.length
460
+ case s[r]
461
+ when ?" then t.print('\\"')
462
+ when ?\\ then t.print('\\\\')
463
+ when ?\b then t.print('\\b')
464
+ when ?\f then t.print('\\f')
465
+ when ?\n then t.print('\\n')
466
+ when ?\r then t.print('\\r')
467
+ when ?\t then t.print('\\t')
468
+ else
469
+ c = s[r]
470
+ case true
471
+ when rubydoesenc
472
+ begin
473
+ c.ord # will raise an error if c is invalid UTF-8
474
+ t.write(c)
475
+ rescue
476
+ t.write(Ustrerr)
477
+ end
478
+ when Spc <= c && c <= ?~
479
+ t.putc(c)
480
+ else
481
+ n = ucharcopy(t, s, r) # ensure valid UTF-8 output
482
+ r += n - 1 # r is incremented below
483
+ end
484
+ end
485
+ r += 1
486
+ end
487
+ t.putc(?")
488
+ t.string
489
+ end
490
+
491
+
492
+ def numenc(x)
493
+ if ((x.nan? || x.infinite?) rescue false)
494
+ raise Error, "Numeric cannot be represented: #{x}"
495
+ end
496
+ "#{x}"
497
+ end
498
+
499
+
500
+ # Copies the valid UTF-8 bytes of a single character
501
+ # from string s at position i to I/O object t, and
502
+ # returns the number of bytes copied.
503
+ # If no valid UTF-8 char exists at position i,
504
+ # ucharcopy writes Ustrerr and returns 1.
505
+ def ucharcopy(t, s, i)
506
+ n = s.length - i
507
+ raise Utf8Error if n < 1
508
+
509
+ c0 = s[i].ord
510
+
511
+ # 1-byte, 7-bit sequence?
512
+ if c0 < Utagx
513
+ t.putc(c0)
514
+ return 1
515
+ end
516
+
517
+ raise Utf8Error if c0 < Utag2 # unexpected continuation byte?
518
+
519
+ raise Utf8Error if n < 2 # need continuation byte
520
+ c1 = s[i+1].ord
521
+ raise Utf8Error if c1 < Utagx || Utag2 <= c1
522
+
523
+ # 2-byte, 11-bit sequence?
524
+ if c0 < Utag3
525
+ raise Utf8Error if ((c0&Umask2)<<6 | (c1&Umaskx)) <= Uchar1max
526
+ t.putc(c0)
527
+ t.putc(c1)
528
+ return 2
529
+ end
530
+
531
+ # need second continuation byte
532
+ raise Utf8Error if n < 3
533
+
534
+ c2 = s[i+2].ord
535
+ raise Utf8Error if c2 < Utagx || Utag2 <= c2
536
+
537
+ # 3-byte, 16-bit sequence?
538
+ if c0 < Utag4
539
+ u = (c0&Umask3)<<12 | (c1&Umaskx)<<6 | (c2&Umaskx)
540
+ raise Utf8Error if u <= Uchar2max
541
+ t.putc(c0)
542
+ t.putc(c1)
543
+ t.putc(c2)
544
+ return 3
545
+ end
546
+
547
+ # need third continuation byte
548
+ raise Utf8Error if n < 4
549
+ c3 = s[i+3].ord
550
+ raise Utf8Error if c3 < Utagx || Utag2 <= c3
551
+
552
+ # 4-byte, 21-bit sequence?
553
+ if c0 < Utag5
554
+ u = (c0&Umask4)<<18 | (c1&Umaskx)<<12 | (c2&Umaskx)<<6 | (c3&Umaskx)
555
+ raise Utf8Error if u <= Uchar3max
556
+ t.putc(c0)
557
+ t.putc(c1)
558
+ t.putc(c2)
559
+ t.putc(c3)
560
+ return 4
561
+ end
562
+
563
+ raise Utf8Error
564
+ rescue Utf8Error
565
+ t.write(Ustrerr)
566
+ return 1
567
+ end
568
+
569
+
570
+ class Utf8Error < ::StandardError
571
+ end
572
+
573
+
574
+ class Error < ::StandardError
575
+ end
576
+
577
+
578
+ Utagx = 0x80 # 1000 0000
579
+ Utag2 = 0xc0 # 1100 0000
580
+ Utag3 = 0xe0 # 1110 0000
581
+ Utag4 = 0xf0 # 1111 0000
582
+ Utag5 = 0xF8 # 1111 1000
583
+ Umaskx = 0x3f # 0011 1111
584
+ Umask2 = 0x1f # 0001 1111
585
+ Umask3 = 0x0f # 0000 1111
586
+ Umask4 = 0x07 # 0000 0111
587
+ Uchar1max = (1<<7) - 1
588
+ Uchar2max = (1<<11) - 1
589
+ Uchar3max = (1<<16) - 1
590
+ Ucharerr = 0xFFFD # unicode "replacement char"
591
+ Ustrerr = "\xef\xbf\xbd" # unicode "replacement char"
592
+ Usurrself = 0x10000
593
+ Usurr1 = 0xd800
594
+ Usurr2 = 0xdc00
595
+ Usurr3 = 0xe000
596
+
597
+ Spc = ' '[0]
598
+ Unesc = {?b=>?\b, ?f=>?\f, ?n=>?\n, ?r=>?\r, ?t=>?\t}
599
+ end
600
+
601
+ module JSON
602
+ module Backends
603
+ module OkJson
604
+ ParseError = ::ActiveSupport::OkJson::Error
605
+ extend self
606
+
607
+ # Parses a JSON string or IO and convert it into an object
608
+ def decode(json)
609
+ if json.respond_to?(:read)
610
+ json = json.read
611
+ end
612
+ data = ActiveSupport::OkJson.decode(json)
613
+ if ActiveSupport.parse_json_times
614
+ convert_dates_from(data)
615
+ else
616
+ data
617
+ end
618
+ end
619
+
620
+ private
621
+ def convert_dates_from(data)
622
+ case data
623
+ when nil
624
+ nil
625
+ when DATE_REGEX
626
+ begin
627
+ DateTime.parse(data)
628
+ rescue ArgumentError
629
+ data
630
+ end
631
+ when Array
632
+ data.map! { |d| convert_dates_from(d) }
633
+ when Hash
634
+ data.each do |key, value|
635
+ data[key] = convert_dates_from(value)
636
+ end
637
+ else
638
+ data
639
+ end
640
+ end
641
+ end
642
+ end
643
+ end
644
+ end
@@ -7,79 +7,12 @@ module ActiveSupport
7
7
  ParseError = ::StandardError
8
8
  extend self
9
9
 
10
- # Converts a JSON string into a Ruby object.
11
10
  def decode(json)
12
- YAML.load(convert_json_to_yaml(json))
13
- rescue ArgumentError => e
14
- raise ParseError, "Invalid JSON string"
11
+ raise "The Yaml backend has been deprecated due to security risks, you should set ActiveSupport::JSON.backend = 'OkJson'"
15
12
  end
16
13
 
17
14
  protected
18
- # Ensure that ":" and "," are always followed by a space
19
- def convert_json_to_yaml(json) #:nodoc:
20
- require 'strscan' unless defined? ::StringScanner
21
- scanner, quoting, marks, pos, times = ::StringScanner.new(json), false, [], nil, []
22
- while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
23
- case char = scanner[1]
24
- when '"', "'"
25
- if !quoting
26
- quoting = char
27
- pos = scanner.pos
28
- elsif quoting == char
29
- if json[pos..scanner.pos-2] =~ DATE_REGEX
30
- # found a date, track the exact positions of the quotes so we can
31
- # overwrite them with spaces later.
32
- times << pos << scanner.pos
33
- end
34
- quoting = false
35
- end
36
- when ":",","
37
- marks << scanner.pos - 1 unless quoting
38
- when "\\"
39
- scanner.skip(/\\/)
40
- end
41
- end
42
-
43
- if marks.empty?
44
- json.gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
45
- ustr = $1
46
- if ustr.start_with?('u')
47
- [ustr[1..-1].to_i(16)].pack("U")
48
- elsif ustr == '\\'
49
- '\\\\'
50
- else
51
- ustr
52
- end
53
- end
54
- else
55
- left_pos = [-1].push(*marks)
56
- right_pos = marks << scanner.pos + scanner.rest_size
57
- output = []
58
- left_pos.each_with_index do |left, i|
59
- scanner.pos = left.succ
60
- chunk = scanner.peek(right_pos[i] - scanner.pos + 1)
61
- # overwrite the quotes found around the dates with spaces
62
- while times.size > 0 && times[0] <= right_pos[i]
63
- chunk[times.shift - scanner.pos - 1] = ' '
64
- end
65
- chunk.gsub!(/\\([\\\/]|u[[:xdigit:]]{4})/) do
66
- ustr = $1
67
- if ustr.start_with?('u')
68
- [ustr[1..-1].to_i(16)].pack("U")
69
- elsif ustr == '\\'
70
- '\\\\'
71
- else
72
- ustr
73
- end
74
- end
75
- output << chunk
76
- end
77
- output = output * " "
78
-
79
- output.gsub!(/\\\//, '/')
80
- output
81
- end
82
- end
15
+
83
16
  end
84
17
  end
85
18
  end
@@ -6,7 +6,7 @@ module ActiveSupport
6
6
 
7
7
  module JSON
8
8
  # Listed in order of preference.
9
- DECODERS = %w(Yajl Yaml)
9
+ DECODERS = %w(Yajl OkJson)
10
10
 
11
11
  class << self
12
12
  attr_reader :parse_error
@@ -2,7 +2,7 @@ module ActiveSupport
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 2
4
4
  MINOR = 3
5
- TINY = 15
5
+ TINY = 16
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
metadata CHANGED
@@ -1,32 +1,22 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: activesupport
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 2
7
- - 3
8
- - 15
9
- version: 2.3.15
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.3.16
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - David Heinemeier Hansson
13
8
  autorequire:
14
9
  bindir: bin
15
10
  cert_chain: []
16
-
17
- date: 2013-01-08 00:00:00 -08:00
18
- default_executable:
11
+ date: 2013-01-28 00:00:00.000000000 Z
19
12
  dependencies: []
20
-
21
- description: Utility library which carries commonly used classes and goodies from the Rails framework
13
+ description: Utility library which carries commonly used classes and goodies from
14
+ the Rails framework
22
15
  email: david@loudthinking.com
23
16
  executables: []
24
-
25
17
  extensions: []
26
-
27
18
  extra_rdoc_files: []
28
-
29
- files:
19
+ files:
30
20
  - CHANGELOG
31
21
  - README
32
22
  - lib/active_support/all.rb
@@ -165,6 +155,7 @@ files:
165
155
  - lib/active_support/inflections.rb
166
156
  - lib/active_support/inflector.rb
167
157
  - lib/active_support/json/backends/jsongem.rb
158
+ - lib/active_support/json/backends/okjson.rb
168
159
  - lib/active_support/json/backends/yajl.rb
169
160
  - lib/active_support/json/backends/yaml.rb
170
161
  - lib/active_support/json/decoding.rb
@@ -403,35 +394,27 @@ files:
403
394
  - lib/active_support/xml_mini.rb
404
395
  - lib/active_support.rb
405
396
  - lib/activesupport.rb
406
- has_rdoc: true
407
397
  homepage: http://www.rubyonrails.org
408
398
  licenses: []
409
-
399
+ metadata: {}
410
400
  post_install_message:
411
401
  rdoc_options: []
412
-
413
- require_paths:
402
+ require_paths:
414
403
  - lib
415
- required_ruby_version: !ruby/object:Gem::Requirement
416
- requirements:
404
+ required_ruby_version: !ruby/object:Gem::Requirement
405
+ requirements:
417
406
  - - ">="
418
- - !ruby/object:Gem::Version
419
- segments:
420
- - 0
421
- version: "0"
422
- required_rubygems_version: !ruby/object:Gem::Requirement
423
- requirements:
407
+ - !ruby/object:Gem::Version
408
+ version: '0'
409
+ required_rubygems_version: !ruby/object:Gem::Requirement
410
+ requirements:
424
411
  - - ">="
425
- - !ruby/object:Gem::Version
426
- segments:
427
- - 0
428
- version: "0"
412
+ - !ruby/object:Gem::Version
413
+ version: '0'
429
414
  requirements: []
430
-
431
415
  rubyforge_project: activesupport
432
- rubygems_version: 1.3.6
416
+ rubygems_version: 2.0.0.preview3.1
433
417
  signing_key:
434
- specification_version: 3
418
+ specification_version: 4
435
419
  summary: Support and utility classes used by the Rails framework.
436
420
  test_files: []
437
-