-
Notifications
You must be signed in to change notification settings - Fork 294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
encoding/yaml: unable to parse number value in YAML with leading zero #2578
Comments
This appears to be a bug in upstream go-yaml; see go-yaml/yaml#157. See @rogpeppe's replies in that thread, in particular - each YAML implementation seems to solve this ambiguity a different way, since It seems to me like the YAML v1.2 spec is unambiguous in that
Either way, this needs to be fixed upstream - then we can pick up the fix. |
Thanks @mvdan. I was able to use go-yaml to decode the value as a string, while CUE will not. Here's a reproducer that I'd love your feedback on. Thanks!
Output:
|
Thank you @jesselang, indeed it seems like the error comes from CUE and not go-yaml, and we can tweak our YAML decoding logic to not produce an invalid/illegal CUE literal. I'll send a fix shortly. |
YAML 1.1 has octal numbers with the "0" prefix, whereas YAML 1.2 has octal numbers with the "0o" prefix. Both are used in the wild, so we must be able to handle both. Right now, a non-octal number beginning with "0" results in an error, whereas most YAML decoders, including go-yaml's Unmarshal, fall back to decoding the value as a string. We will implement a fix like that in a follow-up commit; this commit simply adds test cases to show the current behavior. For #2578. Signed-off-by: Daniel Martí <mvdan@mvdan.cc> Change-Id: I46f54f43d7f47c83ec907e421a37b049ad9d3137
That is, the input not_octal_yaml11: 0123456789 used to give the error cannot decode "0123456789" as !!float: illegal integer number "0123456789" given that YAML would hint that the value was float rather than int (given that it is not made up of octal digits), and we would try to decode as the CUE decimal literal 0123456789, which is invalid since a decimal can only start with "0" when it is the zero number: decimal_lit = "0" | ( "1" … "9" ) { [ "_" ] decimal_digit } . Much like other YAML decoders when they interpret this edge case, including go-yaml itself, we now decode the input value as a CUE string: not_octal_yaml11: "0123456789" Note that an alternative would be decoding as the valid CUE integer not_octal_yaml11: 123456789 and, while this may be OK for some programs using YAML 1.2 only that meant the value to be a decimal integer, some other programs may be depending on the string semantics where the leading 0 is kept. Fixes #2578. Signed-off-by: Daniel Martí <mvdan@mvdan.cc> Change-Id: If21bd469a2f75e07b76020451633627887868338
YAML 1.1 has octal numbers with the "0" prefix, whereas YAML 1.2 has octal numbers with the "0o" prefix. Both are used in the wild, so we must be able to handle both. Right now, a non-octal number beginning with "0" results in an error, whereas most YAML decoders, including go-yaml's Unmarshal, fall back to decoding the value as a string. We will implement a fix like that in a follow-up commit; this commit simply adds test cases to show the current behavior. Also add cases where YAML 1.1 and 1.2 octal integer literals are prefixed with an explicit !!float tag, where the user definitely does not mean the input to be an octal integer. We don't want any change in our handling of octal integers to change these cases, even if one of the cases is broken per the added TODO. For #2578. Signed-off-by: Daniel Martí <mvdan@mvdan.cc> Change-Id: I46f54f43d7f47c83ec907e421a37b049ad9d3137
That is, the input not_octal_yaml11: 0123456789 used to give the error cannot decode "0123456789" as !!float: illegal integer number "0123456789" given that YAML would hint that the value was float rather than int (given that it is not made up of octal digits), and we would try to decode as the CUE decimal literal 0123456789, which is invalid since a decimal can only start with "0" when it is the zero number: decimal_lit = "0" | ( "1" … "9" ) { [ "_" ] decimal_digit } . Much like other YAML decoders when they interpret this edge case, including go-yaml itself, we now decode the input value as a CUE string: not_octal_yaml11: "0123456789" Note that an alternative would be decoding as the valid CUE integer not_octal_yaml11: 123456789 and, while this may be OK for some programs using YAML 1.2 only that meant the value to be a decimal integer, some other programs may be depending on the string semantics where the leading 0 is kept. Fixes #2578. Signed-off-by: Daniel Martí <mvdan@mvdan.cc> Change-Id: If21bd469a2f75e07b76020451633627887868338
YAML 1.1 has octal numbers with the "0" prefix, whereas YAML 1.2 has octal numbers with the "0o" prefix. Both are used in the wild, so we must be able to handle both. Right now, a non-octal number beginning with "0" results in an error, whereas most YAML decoders, including go-yaml's Unmarshal, fall back to decoding the value as a string. We will implement a fix like that in a follow-up commit; this commit simply adds test cases to show the current behavior. Also add cases where YAML 1.1 and 1.2 octal integer literals are prefixed with an explicit !!float tag, where the user definitely does not mean the input to be an octal integer. We don't want any change in our handling of octal integers to change these cases, even if one of the cases is broken per the added TODO. For #2578. Signed-off-by: Daniel Martí <mvdan@mvdan.cc> Change-Id: I46f54f43d7f47c83ec907e421a37b049ad9d3137 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1195046 TryBot-Result: CUEcueckoo <cueckoo@cuelang.org> Reviewed-by: Roger Peppe <rogpeppe@gmail.com> Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
What version of CUE are you using (
cue version
)?Does this issue reproduce with the latest stable release?
Yes. v0.6.0 appears to be the latest release.
What did you do?
I'm trying to parse a YAML value that contains a number with a leading zero.
What did you expect to see?
The number is parsed. Perhaps this is challenging because some parsers parse the value as base 8, others might strip the leading zero, etc.
What did you see instead?
The text was updated successfully, but these errors were encountered: