Values starting with "0" are treated as numbers

Issue #538 invalid
Michael Holtermann created an issue

Since release 1.30, snakeyaml treats every string starting with a “0” as integer.

Minimal example:

import org.yaml.snakeyaml.Yaml;

import java.io.StringWriter;

public class Main {

  public static void main(String[] args) throws Exception {
    Object data = new Yaml().load("VARIABLE: \"095\"");

    StringWriter w = new StringWriter();
    Yaml writeYaml = new Yaml();
    writeYaml.dump(data, w);

    System.out.println(w);
  }
}

With snakeyaml:1.29, the output will be

{VARIABLE: '095'}

With snakeyaml:1.30, the output will be

{VARIABLE: 095}

I guess this happens with #506.

I’d consider this as a major bug, since it interprets values as integers that were strings in the first place.

SnakeYaml is part of Jenkins in readYaml and writeYaml functions https://github.com/jenkinsci/pipeline-utility-steps-plugin/blob/d6481a9a669b90e667177d250d91749e4a6c1e4a/src/main/java/org/jenkinsci/plugins/pipeline/utility/steps/conf/ReadYamlStep.java and https://github.com/jenkinsci/pipeline-utility-steps-plugin/blob/d6481a9a669b90e667177d250d91749e4a6c1e4a/src/main/java/org/jenkinsci/plugins/pipeline/utility/steps/conf/WriteYamlStep.java.

Comments (15)

  1. Michael Holtermann reporter

    Hi @Andrey Somov , thanks for your response.

    To be honest, I’m not very firm with the YAML spec. But in my example, the value is quoted with ", so it should be treated as is, shouldn’t it? It doesn’t matter if I use single quotes BTW.

    The expected outcome is '095', but it gets converted to 095

    Our use case is to process some Kubernetes ConfigMap for a cluster running in AWS. The values in these ConfigMaps must be Strings. With snakeyaml:1.29, everything was fine.

    If "095" should be treated as octal, it would break configurations for e.g. AWS accounts. An AWS Account ID is a random sequence of digits and may start with a 0, but must be treated as-is, obviously.

  2. Michael Holtermann reporter

    Hm. That's surprising.

    I tried to debug the issue. AFAICS the parser ist okay. Then it's becoming less obvious - the Presenter seems to be okay, too.

    I think when it comes to writing, the quotes will disappear.

    If snakeyaml follows a spec here as you said, we wouldn't bei able to have String-like values in YAML that start with a 0.

    To my understanding, a quoted value should be kept as is.

    Would you please point me to the spec that says otherwise?

  3. Michael Holtermann reporter

    Ah, okay, now we are getting gcloser to the issue. 👍 I’m sorry for any misunderstandings.

    Let me try to rephrase the issue:

    “Given a Java String that starts with 0 and contains only digits, dumpwill not surround that value with quotes, but treat it as an integer.”

    My example above demonstrates this.

    I’m not sure if I could provide a unit test, but if it helps I would try to do so.

  4. Andrey Somov

    this is not entirely correct - “Given a Java String that starts with 0 and contains only digits, dump will not surround that value with quotes, but treat it as an integer.”

    095 - this is a string !!! it is not treated as an integer ! (abc is also string even without quotes)

    095' - this is also a string

  5. Michael Holtermann reporter

    I would like to ask you to apologize, your conclusion is correct. I needed some time to understand what you wrote above and to align it with the YAML spec.

    In addition, I overlooked that snakeyaml implements YAML 1.1, not 1.2. This wouldn’t solve my issue (yes, 095 is not octal, but a string), but in YAML 1.2 octals must start with 0o, which I found first.

    To solve my use case, I would have to file a bug against the tool that reads and misinterprets the YAML that was generated by snakeyaml.

    FTR, to my understanding:

    • snakeyaml 1.30 removes quotes from input that is unambiguously a string, like 095, '095', !!str 095 → all of them result in 095
    • with snakeyaml 1.29, the result was a quoted '095'; the update to 1.30 caused my problem.
    • octals in YAML 1.1 starts with a 0, so 012 results in number 10, while 0o12 results in string 0o12
    • octals in YAML 1.2 starts with 0o, so 012 results in string 012, while 0o12 results in number 10.

    I’d name the change in the treatment of octals between YAML 1.1 and 1.2 a breaking change, which I would not expect within a minor version bump. But to repeat myself: I’m not the expert, but instead the person that must deal with such incompatibilities between various tools.

    May I ask a final question:

    The input !!str 122 will be dumped to a quoted '122', while !!str 095 will be an unquoted 095. Is it possible to force snakeyaml to quote it to '095' as before with snakeyaml 1.29?

    Thanks again!

  6. Andrey Somov
    1. YAML 1.2 is not strict here, the formats 0o and 0x are defined in the Core Schema (which is optional and it is not supported by the SnakeYAML Engine)
    2. Yes, it is possible to dump ‘095’ - you need to set your custom Resolver. You can find examples in the tests. The regular expression can be found in the previous version of SnakeYAML

  7. vijaya kumar

    I have exactly same problem .. AWS account id (string with quotes) ‘0123456789’ is dumped as ( considered integer without quotes ) 0123456789 into yaml file . A tool further read AWS account id as 123456789 omitting 0 and fails .

    please advise custom resolver example that worked @Michael Holtermann for you @Andrey Somov

  8. Michael Michael

    We removed the step that involves snakeyaml from our deployment pipeline, and stood with kustomize/kubeval.

  9. vijaya kumar

    Thanks @Michael Michael . Same here. Avoid using snakeyaml or develop own work around.

    There is NO valid example provided to overcome .. This is BWC for snakeyaml adopter not even mentioned in doc/release . Strange this issue is being closed as invalid.

    This issue should be open and fixed. @Andrey Somov .

    Before fix, it should be mentioned in “BWC” section and steps to overcome with an example using “custom Resolver.” , i could not get a valid example browsing all docs.

  10. Andrey Somov

    it is invalid because SnakeYAML works according to the spec.

    The examples with custom resolver you can find in tests (clone the project and search in the tests)

  11. Log in to comment