diff options
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/json/decoding.rb | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/activesupport/lib/active_support/json/decoding.rb b/activesupport/lib/active_support/json/decoding.rb index 08446d3a83..b6370ddb0e 100644 --- a/activesupport/lib/active_support/json/decoding.rb +++ b/activesupport/lib/active_support/json/decoding.rb @@ -15,17 +15,26 @@ module ActiveSupport end protected - + # matches YAML-formatted dates + DATE_REGEX = /^\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?$/ + # Ensure that ":" and "," are always followed by a space def convert_json_to_yaml(json) #:nodoc: - scanner, quoting, marks = StringScanner.new(json), false, [] - + scanner, quoting, marks, pos, times = StringScanner.new(json), false, [], nil, [] while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/) case char = scanner[1] when '"', "'" if !quoting quoting = char + pos = scanner.pos elsif quoting == char + if json[pos..scanner.pos-2] =~ DATE_REGEX + # found a date, track the exact positions of the quotes so we can remove them later. + # oh, and increment them for each current mark, each one is an extra padded space that bumps + # the position in the final yaml output + total_marks = marks.size + times << pos+total_marks << scanner.pos+total_marks + end quoting = false end when ":","," @@ -37,9 +46,13 @@ module ActiveSupport json else ranges = ([0] + marks.map(&:succ)).zip(marks + [json.length]) - ranges.map { |(left, right)| json[left..right] }.join(" ") + output = ranges.collect! { |(left, right)| json[left..right] }.join(" ") + times.each do |pos| + output[pos-1] = ' ' + end + output end - end + end end end end |