yakaz / yamerl

YAML 1.2 and JSON parser in pure Erlang

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Hex strings are incorrectly parsed as exponentials

jbodah opened this issue · comments

OTP 20
yamerl 0.6.0

We have a Ruby app that is serializing some RGBA hex strings with the Ruby YAML library. We get the following:

irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> {rgba: "660000e0"}.to_yaml
=> "---\n:rgba: 660000e0\n"

And when we go over to yamerl it gets parsed as an exponential:

iex(1)> :application.start(:yamerl)
:ok
iex(2)> :yamerl_constr.string("---\n:rgba: 660000e0\n")
[[{':rgba', 6.6e5}]]

In the Ruby parser we would get a hex string back as expected:

irb(main):003:0> YAML.load("---\n:rgba: 660000e0\n")
=> {:rgba=>"660000e0"}

From what I can tell exponentials in YAML should take the form 1.23e+10 and the Ruby library conforms to that behavior:

irb(main):007:0> YAML.load("---\n:rgba: 6.6e+34\n")
=> {:rgba=>6.6e+34}
irb(main):008:0> {rgba: "6.6e+34"}.to_yaml
=> "---\n:rgba: '6.6e+34'\n"

Sorry if this isn't a yamerl bug - it's unclear to me in the spec how these are supposed to be handled

Here's an example with :fast_yaml which is also a libyaml wrapper:

iex(2)> :fast_yaml.decode("---\n:rgba: 660000e0\n")
{:ok, [[{":rgba", "660000e0"}]]}

Hi!

I'm sorry, I didn't notice the issue you reported....

As I read the paragraph in the YAML 1.2 specification about how float should be read when using the "core" (default) schema, e can be followed directly with an integer. In fact, I copy-pasted their regex in yamerl.

The "json" schema in YAML 1.2, however, requires e to be followed by + or - for floats. Likewise for floats in YAML 1.1, which is probably the version implemented by the parsers you tried.

It looks like yamerl doesn't load the YAML-1.1-specific modules, even though the document indicates it's YAML 1.1, so I need to fix that. In your case, the generated YAML document doesn't specify the version anyway. So what you could do is request the yaml11 schema in yamerl:

1> application:start(yamerl).
ok
2> yamerl:decode("---\n:rgba: 660000e0\n", [{schema, yaml11}]).       
[[{":rgba","660000e0"}]]

Oh interesting, I didn't realize that - thanks for the reference links!