activesupport 3.0.19 → 3.0.20

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: 6cb3ad3c0372d8514caee7e2d5217d2be827a88f
4
- data.tar.gz: 50718fbe4e4d817a3cb79708e32e08a8e465a2d9
5
- !binary "U0hBNTEy":
6
- metadata.gz: acd964ef057809cb947c30db00cc34d4a8eadb32ef3e80f33199fe76287bda8fbb53dddf004718d41eea99ac6bde63fe730561f98e401b0c8ec11b2e20be37c1
7
- data.tar.gz: 02b7c6804a3844706f83e66dc0325098cf2e4576fa485e64468eaaba60b7f559d33f61bccf0a2f371ad6b14a3515a5b2689904e9b9864cb21d5c169e83e6adba
2
+ SHA1:
3
+ metadata.gz: 5b10c504f7e89e31840146dc035f18db58ec6781
4
+ data.tar.gz: 174429c89cdc72aca932d18d7d89c64abc1f5ee8
5
+ SHA512:
6
+ metadata.gz: 6a1c10cce67fafe77efc20d56aa8039c873d457a63958b6c27a946dbe7414b6e7d745f2f4813a70d5b720454b5fb7ffc40658337a501a18a352813a7604fec38
7
+ data.tar.gz: a3b25fac82589dfb772fc9efd3ac4b8f4ec906c25e24145c1cf261208761d1b30e38e8763d66583be1ec4e6398e9aabce4e0d609a1fe995515f715488a5b7095
data/CHANGELOG CHANGED
@@ -1,13 +1,17 @@
1
- ## Rails 3.0.19 (Jan 8, 2012) ##
1
+ ## Rails 3.0.20 (unreleased)
2
2
 
3
- * Hash.from_xml raises when it encounters type="symbol" or type="yaml".
4
- Use Hash.from_trusted_xml to parse this XML.
3
+ ## Rails 3.0.19 (Jan 8, 2013)
5
4
 
6
- CVE-2013-0156
5
+ * Hash.from_xml raises when it encounters type="symbol" or type="yaml".
6
+ Use Hash.from_trusted_xml to parse this XML.
7
7
 
8
- *Jeremy Kemper*
8
+ CVE-2013-0156
9
9
 
10
- ## Rails 3.0.18
10
+ *Jeremy Kemper*
11
+
12
+ ## Rails 3.0.18 (Jan 2, 2013)
13
+
14
+ * No changes.
11
15
 
12
16
  ## Rails 3.0.17 (Aug 9, 2012)
13
17
 
@@ -15,11 +19,11 @@
15
19
 
16
20
  ## Rails 3.0.16 (Jul 26, 2012)
17
21
 
18
- * No changes.
22
+ * No changes.
19
23
 
20
24
  ## Rails 3.0.14 (Jun 12, 2012)
21
25
 
22
- * No changes.
26
+ * No changes.
23
27
 
24
28
  * Rails 3.0.13 (May 31, 2012)
25
29
 
@@ -7,9 +7,9 @@ module ActiveSupport
7
7
  module Gzip
8
8
  class Stream < StringIO
9
9
  def initialize(*)
10
- super
11
- set_encoding "BINARY" if "".encoding_aware?
12
- end
10
+ super
11
+ set_encoding "BINARY" if "".encoding_aware?
12
+ end
13
13
  def close; rewind; end
14
14
  end
15
15
 
@@ -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
@@ -8,102 +8,10 @@ module ActiveSupport
8
8
  extend self
9
9
 
10
10
  EXCEPTIONS = [::ArgumentError] # :nodoc:
11
- begin
12
- require 'psych'
13
- EXCEPTIONS << Psych::SyntaxError
14
- rescue LoadError
15
- end
16
11
 
17
- # Parses a JSON string or IO and converts it into an object
18
12
  def decode(json)
19
- if json.respond_to?(:read)
20
- json = json.read
21
- end
22
- YAML.load(convert_json_to_yaml(json))
23
- rescue *EXCEPTIONS => e
24
- raise ParseError, "Invalid JSON string: '%s'" % json
13
+ raise "Warning: The Yaml backend has been deprecated due to security risks, you should set ActiveSupport::JSON.backend = 'OkJson'"
25
14
  end
26
-
27
- protected
28
- # Ensure that ":" and "," are always followed by a space
29
- def convert_json_to_yaml(json) #:nodoc:
30
- require 'strscan' unless defined? ::StringScanner
31
- scanner, quoting, marks, pos, times = ::StringScanner.new(json), false, [], nil, []
32
- while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
33
- case char = scanner[1]
34
- when '"', "'"
35
- if !quoting
36
- quoting = char
37
- pos = scanner.pos
38
- elsif quoting == char
39
- if valid_date?(json[pos..scanner.pos-2])
40
- # found a date, track the exact positions of the quotes so we can
41
- # overwrite them with spaces later.
42
- times << pos
43
- end
44
- quoting = false
45
- end
46
- when ":",","
47
- marks << scanner.pos - 1 unless quoting
48
- when "\\"
49
- scanner.skip(/\\/)
50
- end
51
- end
52
-
53
- if marks.empty?
54
- json.gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
55
- ustr = $1
56
- if ustr.start_with?('u')
57
- char = [ustr[1..-1].to_i(16)].pack("U")
58
- # "\n" needs extra escaping due to yaml formatting
59
- char == "\n" ? "\\n" : char
60
- elsif ustr == '\\'
61
- '\\\\'
62
- else
63
- ustr
64
- end
65
- end
66
- else
67
- left_pos = [-1].push(*marks)
68
- right_pos = marks << scanner.pos + scanner.rest_size
69
- output = []
70
- left_pos.each_with_index do |left, i|
71
- scanner.pos = left.succ
72
- chunk = scanner.peek(right_pos[i] - scanner.pos + 1)
73
- # overwrite the quotes found around the dates with spaces
74
- while times.size > 0 && times[0] <= right_pos[i]
75
- chunk.insert(times.shift - scanner.pos - 1, '! ')
76
- end
77
- chunk.gsub!(/\\([\\\/]|u[[:xdigit:]]{4})/) do
78
- ustr = $1
79
- if ustr.start_with?('u')
80
- char = [ustr[1..-1].to_i(16)].pack("U")
81
- # "\n" needs extra escaping due to yaml formatting
82
- char == "\n" ? "\\n" : char
83
- elsif ustr == '\\'
84
- '\\\\'
85
- else
86
- ustr
87
- end
88
- end
89
- output << chunk
90
- end
91
- output = output * " "
92
-
93
- output.gsub!(/\\\//, '/')
94
- output
95
- end
96
- end
97
-
98
- private
99
- def valid_date?(date_string)
100
- begin
101
- date_string =~ DATE_REGEX && DateTime.parse(date_string)
102
- rescue ArgumentError
103
- false
104
- end
105
- end
106
-
107
15
  end
108
16
  end
109
17
  end
@@ -7,7 +7,7 @@ module ActiveSupport
7
7
 
8
8
  module JSON
9
9
  # Listed in order of preference.
10
- DECODERS = %w(Yajl Yaml)
10
+ DECODERS = %w(Yajl OkJson)
11
11
 
12
12
  class << self
13
13
  attr_reader :parse_error
@@ -437,7 +437,7 @@ module ActiveSupport #:nodoc:
437
437
 
438
438
  begin
439
439
  @wrapped_string[0...byte_offset].unpack('U*').length
440
- rescue ArgumentError => e
440
+ rescue ArgumentError
441
441
  byte_offset -= 1
442
442
  retry
443
443
  end
@@ -8,7 +8,7 @@ require 'active_support/testing/isolation'
8
8
  require 'active_support/core_ext/kernel/reporting'
9
9
 
10
10
  begin
11
- silence_warnings { require 'mocha' }
11
+ silence_warnings { require 'mocha/setup' }
12
12
  rescue LoadError
13
13
  # Fake Mocha::ExpectationError so we can rescue it in #run. Bleh.
14
14
  Object.const_set :Mocha, Module.new
@@ -56,7 +56,7 @@ module ActiveSupport
56
56
  def run(result)
57
57
  return if @method_name.to_s == "default_test"
58
58
 
59
- mocha_counter = retrieve_mocha_counter(result)
59
+ mocha_counter = retrieve_mocha_counter(self, result)
60
60
  yield(Test::Unit::TestCase::STARTED, name)
61
61
  @_result = result
62
62
 
@@ -78,6 +78,8 @@ module ActiveSupport
78
78
  begin
79
79
  teardown
80
80
  _run_teardown_callbacks
81
+ rescue Mocha::ExpectationError => e
82
+ add_failure(e.message, e.backtrace)
81
83
  rescue Test::Unit::AssertionFailedError => e
82
84
  add_failure(e.message, e.backtrace)
83
85
  rescue Exception => e
@@ -95,17 +97,18 @@ module ActiveSupport
95
97
 
96
98
  protected
97
99
 
98
- def retrieve_mocha_counter(result) #:nodoc:
100
+ def retrieve_mocha_counter(test_case, result) #:nodoc:
99
101
  if respond_to?(:mocha_verify) # using mocha
100
102
  if defined?(Mocha::TestCaseAdapter::AssertionCounter)
101
103
  Mocha::TestCaseAdapter::AssertionCounter.new(result)
102
- else
104
+ elsif defined?(Mocha::Integration::TestUnit::AssertionCounter)
103
105
  Mocha::Integration::TestUnit::AssertionCounter.new(result)
106
+ else
107
+ Mocha::Integration::AssertionCounter.new(test_case)
104
108
  end
105
109
  end
106
110
  end
107
111
  end
108
-
109
112
  end
110
113
  end
111
114
  end
@@ -2,7 +2,7 @@ module ActiveSupport
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 3
4
4
  MINOR = 0
5
- TINY = 19
5
+ TINY = 20
6
6
  PRE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activesupport
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.19
4
+ version: 3.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-01-08 00:00:00.000000000 Z
11
+ date: 2013-01-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A toolkit of support libraries and Ruby core extensions extracted from
14
14
  the Rails framework. Rich support for multibyte strings, internationalization, time
@@ -174,6 +174,7 @@ files:
174
174
  - lib/active_support/inflector/transliterate.rb
175
175
  - lib/active_support/inflector.rb
176
176
  - lib/active_support/json/backends/jsongem.rb
177
+ - lib/active_support/json/backends/okjson.rb
177
178
  - lib/active_support/json/backends/yajl.rb
178
179
  - lib/active_support/json/backends/yaml.rb
179
180
  - lib/active_support/json/decoding.rb
@@ -246,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
246
247
  version: '0'
247
248
  requirements: []
248
249
  rubyforge_project: activesupport
249
- rubygems_version: 2.0.0.preview3
250
+ rubygems_version: 2.0.0.preview3.1
250
251
  signing_key:
251
252
  specification_version: 4
252
253
  summary: A toolkit of support libraries and Ruby core extensions extracted from the