Skip to content
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

Error when generating/serializing keys with multilines and colon #306

Closed
eginez opened this issue Jan 26, 2022 · 11 comments
Closed

Error when generating/serializing keys with multilines and colon #306

eginez opened this issue Jan 26, 2022 · 11 comments
Labels
yaml Issue related to YAML format backend

Comments

@eginez
Copy link

eginez commented Jan 26, 2022

Hello there

I wanted to report that a key containing a colon : followed by new line chars \n does not seem to be parsing correctly. For example the following test case reproduces the error

    @Test(expected = JsonParseException.class)
    public void testYamlMultiLineNotCanonical() throws Exception {
        String key = "SomeKey:\n\nOtherLine";
        ObjectMapper jsonMapper = new ObjectMapper();
        ObjectNode jsonRoot = jsonMapper.createObjectNode();
        jsonRoot.put(key, 302);

        YAMLFactory yamlFactory = new YAMLFactory();
        ObjectMapper yamlObjectMapper = new ObjectMapper(yamlFactory);
        yamlObjectMapper.configure(JsonParser.Feature.STRICT_DUPLICATE_DETECTION, true);
        StringWriter swriter = new StringWriter();

        yamlObjectMapper.writeValue(swriter, jsonRoot);

        ObjectMapper readMapper =  new ObjectMapper(yamlFactory);
        ObjectNode readJsonRoot = (ObjectNode) readMapper.readTree(swriter.toString());
        Assert.assertEquals(readJsonRoot.get(key).asInt(),302 );
    }

I would have expected the parser to quote the key as \n and : are supported yaml content.

There is work around for this: Force canonical output.

        yamlFactory.configure(YAMLGenerator.Feature.CANONICAL_OUTPUT, true);

That however could have other side effects. Maybe I am missing some other configuration that would do the same?

Thoughts, comments are welcomed.

@eginez eginez changed the title Error when parsing a keys with multilines and colon Error when parsing keys with multilines and colon Jan 26, 2022
@cowtowncoder cowtowncoder added yaml Issue related to YAML format backend 2.13 labels Jan 27, 2022
@cowtowncoder
Copy link
Member

Sounds reasonable that such characters (if and when allowed by YAML) should be properly escaped so that round-trip handling would work. So sounds like a bug.
I don't remember if there are relevant settings, off the top of my head, but I guess there aren't (you probably checked :) ).

@eginez
Copy link
Author

eginez commented Jan 27, 2022

Thanks for confirming @cowtowncoder. As far as I can tell this bug is in SnakeYAML? Would that be a fair assessment?

@cowtowncoder
Copy link
Member

@eginez It does sound like it would be, but I have not had a chance to check this yet. If you can write a simple reproduction against SnakeYAML, that'd allow filing a bug against it.

@asomov would be a good contact here, I think.

@asomov
Copy link
Contributor

asomov commented Jan 31, 2022

@eginez what is swriter.toString() ?

@asomov
Copy link
Contributor

asomov commented Jan 31, 2022

@eginez @cowtowncoder I made a test and it is green:

  public void testKey() {
    String key = "SomeKey:\n\nOtherLine";
    Map<String, Integer> map = new HashMap<>();
    map.put(key, 302);
    Yaml yaml = new Yaml();
    String obj = yaml.dump(map);
    assertEquals("? |-\n"
        + "  SomeKey:\n"
        + "\n"
        + "  OtherLine\n"
        + ": 302\n", obj);
    Map<String, String> parsed = yaml.load(obj);
    assertEquals(302, parsed.get(key));
  }

@eginez
Copy link
Author

eginez commented Jan 31, 2022

@asomov interesting so the bug could indeed somewhere in the jackson library. We should expect this to work right??? (currently fails)

@Test
    public void testYaml2() throws Exception {
        String key = "SomeKey:\n\nOtherLine";
        Map<String, Integer> map = new HashMap<>();
        map.put(key, 302);

        Yaml yaml = new Yaml();
        String dump = yaml.dump(map);

        YAMLFactory yamlFactory = new YAMLFactory();
        ObjectMapper yamlObjectMapper = new ObjectMapper(yamlFactory);
        StringWriter swriter = new StringWriter();
        yamlObjectMapper.writeValue(swriter, map);

        Assert.assertEquals(dump, swriter.toString());
    }

The only difference is the absence of |-

@asomov swriter.toString() pushes the contents of the string buffer to a string object

@cowtowncoder
Copy link
Member

It does sound like potential Jackson bug. I can probably use/repurpose the original sample; the goal is not so much to replicate what specific SnakeYAML settings produce but to ensure that what is written is read back reliably.

I suspect that Jackson's logic that tries to prevent coercion of "NO" into false is leading it to specify some output mode that disables SnakeYAML's escaping or checks.

@cowtowncoder cowtowncoder changed the title Error when parsing keys with multilines and colon Error when generating/serializing keys with multilines and colon Feb 1, 2022
@cowtowncoder
Copy link
Member

I added a simple failing test like so:

    public void testComplexName() throws Exception
    {
        final String key = "SomeKey:\nOtherLine";
        Map<?,?> input = Collections.singletonMap(key, 302);
        final String doc = MAPPER.writeValueAsString(input);
        Map<?,?> actual = MAPPER.readValue(doc, Map.class);
        assertEquals(input, actual);
    }

and will try to see if I can figure out how to resolve this, since SnakeYAML should be able to handle it properly.

@eginez
Copy link
Author

eginez commented Feb 1, 2022

this is great thanks all!!

@asomov
Copy link
Contributor

asomov commented Feb 1, 2022

@cowtowncoder feel free to ping me if you need any help

@cowtowncoder
Copy link
Member

@asomov Will do if need be, thanks!

Fix is in, for 2.13.2 release. Covers linefeed case but I suspect there may be other things that require quoting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
yaml Issue related to YAML format backend
Projects
None yet
Development

No branches or pull requests

3 participants