Project

General

Profile

Actions

Bug #12451

closed

ruby yaml strangely parses string as fixnum

Added by dwatzke (David Watzke) almost 8 years ago. Updated almost 8 years ago.

Status:
Rejected
Target version:
-
ruby -v:
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
[ruby-core:75824]

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) almost 8 years ago

On Wed, Jun 01, 2016 at 04:58:44PM +0000, 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) almost 8 years ago

  • Status changed from Open to Rejected
  • Assignee set to tenderlovemaking (Aaron Patterson)
Actions

Also available in: Atom PDF

Like0
Like0Like0