Bug #12451
closedruby yaml strangely parses string as fixnum
Description
Hi, I have stumbled upon a weird behavior of the yaml parser in ruby - older versions (1.8.7, 2.1.5), even latest 2.3.1.
The value 1,2 should be a string even if unquoted as the quotes are optional for strings. However in ruby this is not the case (see below), so if you load yaml file and native ruby data structures and then serialize it into yaml again, you get something else.
$ cat /tmp/x.yaml¶
x: 1,2
$ irb
irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> thing = YAML.load_file('x.yaml')
=> {"x"=>12}
irb(main):004:0> thing["x"]
=> 12
irb(main):006:0> thing["x"].class
=> Fixnum
irb(main):008:0> File.open('/tmp/y.yml', 'w') {|f| f.write thing.to_yaml }
=> 10
$ cat /tmp/y.yml¶
x: 12
In Python, this works as expected:
with open("/tmp/x.yaml", 'r') as stream:
... print(yaml.load(stream))
...
{'x': '1,2'}
Updated by tenderlovemaking (Aaron Patterson) over 8 years ago
On Wed, Jun 01, 2016 at 04:58:44PM +0000, david@watzke.cz wrote:
Issue #12451 has been reported by David Watzke.
Bug #12451: ruby yaml strangely parses string as fixnum
https://bugs.ruby-lang.org/issues/12451
- Author: David Watzke
- Status: Open
- Priority: Normal
- Assignee:
- ruby -v: ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
- Backport: 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN
Hi, I have stumbled upon a weird behavior of the yaml parser in ruby - older versions (1.8.7, 2.1.5), even latest 2.3.1.
The value 1,2 should be a string even if unquoted as the quotes are optional for strings. However in ruby this is not the case (see below), so if you load yaml file and native ruby data structures and then serialize it into yaml again, you get something else.
$ cat /tmp/x.yaml¶
x: 1,2
$ irb
irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> thing = YAML.load_file('x.yaml')
=> {"x"=>12}
irb(main):004:0> thing["x"]
=> 12
irb(main):006:0> thing["x"].class
=> Fixnum
irb(main):008:0> File.open('/tmp/y.yml', 'w') {|f| f.write thing.to_yaml }
=> 10$ cat /tmp/y.yml¶
x: 12
In Python, this works as expected:
with open("/tmp/x.yaml", 'r') as stream:
... print(yaml.load(stream))
...
{'x': '1,2'}
Yes. This is a "known bug" for backwards compatibility. The original
Ruby YAML implementation supported commas as a separator for numbers (so
you could write something like "1,000"), though if I remember correctly
the YAML spec says you can only use underscores.
I'm not sure how to fix this bug because it will break people with
existing YAML that expect it to be cast to a number.
As a work-around, you can wrap it with double quotes:
irb(main):004:0> Psych.load 'x: "1,2"'
=> {"x"=>"1,2"}
irb(main):005:0>
If you have suggestions for how to fix this without breaking backwards
compatibility, I'd appreciate it!
--
Aaron Patterson
http://tenderlovemaking.com/
Updated by hsbt (Hiroshi SHIBATA) over 8 years ago
- Status changed from Open to Rejected
- Assignee set to tenderlovemaking (Aaron Patterson)