snakeyaml parse String as number by mistake

Issue #449 resolved
dumbdonkey created an issue

What steps will reproduce the problem

you can use following code to reproduce the problem。

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.yaml.snakeyaml.Yaml;

/**
 *
 * @author zcauniverse@163.com
 * @version 1.0
 * @since 2019-06-19 14:16
 **/
public class YamlTest {


    private Map<String, List<String>> maps = new HashMap<>();
    private Map<String, String[]> strs = new HashMap<>();

    public static void main(String[] args) {

        String yamlStr = "---\n"
            + "maps:\n"
            + "  test:\n"
            + "  - 0123456789\n"
            + "  - 232323\n"
            + "  - 231132131\n"
            + "strs:\n"
            + "  str:\n"
            + "  - 0123456789\n"
            + "  - 232323\n"
            + "  - 231132131\n";

        Yaml yaml = new Yaml();
        YamlTest parsed = yaml.loadAs(yamlStr, YamlTest.class);
        System.out.println(parsed.getMaps().get("test")); //variable maps got values of wrong type
        System.out.println(Arrays.toString(parsed.getStrs().get("str")));
    }

    public Map<String, List<String>> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, List<String>> maps) {
        this.maps = maps;
    }

    public Map<String, String[]> getStrs() {
        return strs;
    }

    public void setStrs(Map<String, String[]> strs) {
        this.strs = strs;
    }
}

What is the expected output? What do you see instead?

the expected output is [0123456789, 232323, 231132131], well [1.23456789E8, 232323, 231132131] instead

What version of SnakeYAML are you using? What is the Java version?

snakeyaml:1.2.1

java: 1.8

Please provide any additional information below. (Often a failing test is the best way to describe the problem.)

after make some debugging. I found maybe following code cause this problem.

GenericProperty.java

thanks

Comments (5)

  1. Andrey Somov

    Unfortunately the YAML 1.1 specification defines that if a number starts with 0 it should be parsed as octal. SnakeYAML has to follow it.

    I added a test to clarify the problem: https://bitbucket.org/asomov/snakeyaml/src/default/src/test/java/org/yaml/snakeyaml/issues/issue449/LeadingZeroDoubleTest.java

    You can see that your number cannot be parsed as integer because it is defined as octal but it contains 8 and 9.

    If a number cannot be parsed as integer SnakeYAML tries to parse it as double.

    In order to fix the problem you can define your own Resolver which ignores the octals (you can find examples in tests)

  2. Michael Ziwisky

    i know this is digging up some history, but the decision here strikes me as is an odd one. i do not interpret https://yaml.org/type/int.html to mean that any series of digits that starts with a “0” should be octal, regardless of the digits – there’s a regex explicitly showing that octals only contain 0-7. and even if it did mean that, it makes no sense to me that when digits exceeding “7” exist, then it the value should be interpreted as a float, which itself has its own spec at http://yaml.org/type/float.html, which says nothing about octal.

    i bring it up because i’m working on a PR that breaks the specs associated with this issue, so i’m trying to justify removal or modification of those specs.

  3. Log in to comment