psych icon indicating copy to clipboard operation
psych copied to clipboard

Strings that could be interpreted as sexagesimal should always be emitted quoted

Open alexjfisher opened this issue 6 years ago • 3 comments

Not doing so causes parsers that follow the yaml 1.1 spec (crazy though it might be), to load certain unquoted mac addresses as integers.

IMO https://github.com/ruby/psych/issues/265 wasn't actually a bug. It was following the 1.1 spec. (To make things more complicated, sexagesimal was dropped from yaml in the 1.2 spec)

Ruby 2.5 and 2.6 emit mac addresses, (but not shorter strings it thinks are more likely to be sexagesimal), unquoted.

2.6.0 :002 > '52:54:00:44:49:56'.to_yaml
 => "--- 52:54:00:44:49:56\n...\n" 
2.6.0 :003 > '44:49:56'.to_yaml
 => "--- '44:49:56'\n"

ruby < 2.5 then parse them as integers.

2.4.5 :006 >   YAML.load('macaddress: 52:54:00:44:49:56')
 => {"macaddress"=>12465480}

Here is an actual example of where the change in handling of sexagesimal has been a problem.

alexjfisher avatar Feb 21 '19 10:02 alexjfisher

Another example. https://community.theforeman.org/t/custom-facts-in-foreman/20036/3

The scsi-id string is not being quoted when output. Older versions of ruby are thinking it's an int.

alexjfisher avatar Aug 13 '20 09:08 alexjfisher

@tenderlove Any chance this could be looked at? It's causing real problems for users consuming yaml with other implementations.

https://github.com/ruby/psych/commit/4ae7a3efbc5a423ee288bd734545f834b3cd426b has broken conformance to yaml 1.1

alexjfisher avatar Aug 13 '20 12:08 alexjfisher

FWIW, the implementation before the change was broken too (but possibly not noticed by anyone as it's a daft feature of the spec)

eg in ruby 2.1, two different values being loaded as the same int

2.1.9 :001 > require 'yaml'
 => true 
2.1.9 :002 > YAML.load("---\na: 1:0:0:0")
 => {"a"=>3600} 
2.1.9 :003 > YAML.load("---\na: 1:0:0")
 => {"a"=>3600}

Compare to python

Python 2.7.17 (default, Jul 20 2020, 15:37:01) 
[GCC 7.5.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import yaml
>>> yaml.safe_load("---\na: 1:0:0:0")
{'a': 216000}
Python 3.6.9 (default, Jul 17 2020, 12:50:27) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import yaml
>>> yaml.safe_load("---\na: 1:0:0:0")
{'a': 216000}

alexjfisher avatar Aug 13 '20 14:08 alexjfisher