Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Corruption in Syck-Psych round trips when the document contains "base 60" strings #25

Closed
rsutphin opened this Issue Aug 17, 2011 · 3 comments

Comments

2 participants
Contributor

rsutphin commented Aug 17, 2011

If you have a YAML file that is being updated from both Syck and Psych, string values matching /(\d\d:)+\d\d/ can be corrupted. There is a sample script in this gist. Such a value might be a bare time or a duration in the form HH:MM:SS.

Syck interprets bare values with this pattern as "base 60" numbers according to the YAML 1.1 definition of a float. Psych (or libyaml) does not interpret values this way (as seems correct according to YAML 1.2 and my own personal preferences).

Syck will quote strings that match this pattern; Psych does not. This means that a value matching this pattern in a YAML file that is updated by both Syck and Psych will eventually be corrupted into an integer. You can see that in the gist — the file is created using Syck, then updated using Psych, then updated again using Syck. At the third load-dump cycle, the first two duration values have turned into integers.

This is really an unfortunate behavior on the part of Syck, but it would be nice if Psych would quote the strings to avoid it.

Owner

tenderlove commented Aug 17, 2011

Does this happen with the Psych gem? When I use psych to dump that hash, the values are quoted:

irb(main):002:0> require 'yaml'
=> true
irb(main):003:0> YAML.load '--- 11:22:33'
=> 40953
irb(main):004:0> YAML::ENGINE.yamler
=> "psych"
irb(main):005:0> YAML.dump '11:22:33'
=> "--- '11:22:33'\n"
irb(main):006:0> YAML.dump 'a' => '11:22:33'
=> "---\na: '11:22:33'\n"
irb(main):007:0> YAML.load YAML.dump '11:22:33'
=> "11:22:33"
irb(main):008:0>
Contributor

rsutphin commented Aug 18, 2011

Hmmm. I think that /(\d\d:)+\d\d/ may have been an over-broad assumption on my part.

ruby-1.9.2-p290 :001 > require 'psych'
 => true 
ruby-1.9.2-p290 :002 > Psych.dump('11:22:33')
 => "--- '11:22:33'\n" 
ruby-1.9.2-p290 :003 > Psych.dump('01:03:05')
 => "--- 01:03:05\n...\n" 
ruby-1.9.2-p290 :004 > Psych.dump('a' => '01:03:05')
 => "---\na: 01:03:05\n"

11:22:33 is quoted, but 01:03:05 is not.

Does this happen with the Psych gem?

Apologies, I'm not sure how to test this. I installed the Psych gem but, according to $LOADED_FEATURES, the version being used is still the one under lib/ruby.

Contributor

rsutphin commented Aug 18, 2011

Apologies, I'm not sure how to test this.

Figured it out two seconds later.

ruby-1.9.2-p290 :001 > $LOADED_FEATURES.grep /psych/
 => [] 
ruby-1.9.2-p290 :002 > gem 'psych'
 => true 
ruby-1.9.2-p290 :003 > require 'psych'
 => true 
ruby-1.9.2-p290 :004 > $LOADED_FEATURES.grep /psych/
# indicates that the gem version is being used
ruby-1.9.2-p290 :005 > Psych.dump('a' => '01:03:05')
 => "---\na: 01:03:05\n" 

So, version 1.2.0 of the gem has the same issue.

@tenderlove tenderlove closed this in 8dd7448 Nov 7, 2011

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment