LoadSettings.setBufferSize truncates error messages

Issue #1087 resolved
Róbert Papp (TWiStErRob) created an issue

.setBufferSize(yaml.length) causes the parse error messages to be truncated by exactly one character, best shown with a JUnit Jupiter parameterized test in Kotlin:

    @ValueSource(
        strings = [
            "'aaa' == 'bbb'",
            "'aaaaaaa' == 'bbbbbbbb'",
            "\"aaa\" == \"bbb\"",
            "'aaa' == github.context.variable",
            "\"aaa\" == github.context.variable",
        ]
    )
    @ParameterizedTest
    fun `test`(condition: String) {
        // W1 Strangely adding a character (\n, space) after the last character of the condition also makes it work.
        val yaml = " - foo: bar\n   if: ${condition}"
        val ex = shouldThrow<ParserException> {
            val settings = LoadSettings.builder()
                // W2 Removing this also makes it work. But a bigger buffer shouldn't be necessary, right?
                .setBufferSize(yaml.length)
                .build()
            Composer(settings, ParserImpl(settings, StreamReader(settings, yaml))).singleNode
        }
        // Note: this removeSuffix shouldn't be necessary:
        val conditionInMessage = condition// W3 .removeSuffix(condition.last().toString())
        ex shouldHaveMessage """(?s)^.*\Q$conditionInMessage\E.*$""".toRegex()
    }

The 3 Wn comments show possible workarounds, but I think it should “just work”.

Example failure:

Throwable should match regex: (?s)^.*\Q'aaa' == 'bbb'\E.*$
Actual was:
"while parsing a block mapping
 in reader, line 1, column 4:
     - foo: bar
       ^
expected <block end>, but found '<scalar>'
 in reader, line 2, column 14:
       if: 'aaa' == 'bbb
                 ^"

in this case the YAML is:

 - foo: bar
   if: 'aaa' == 'bbb'

(no new line at end of file)

Comments (13)

  1. Róbert Papp (TWiStErRob) reporter

    Oh, sorry, artifact name is correct above, also forgot:

    import org.snakeyaml.engine.v2.api.LoadSettings
    import org.snakeyaml.engine.v2.composer.Composer
    import org.snakeyaml.engine.v2.nodes.Node
    import org.snakeyaml.engine.v2.parser.ParserImpl
    import org.snakeyaml.engine.v2.scanner.StreamReader
    

    Can you move, or should I reopen there?

  2. Andrey Somov

    can you please provide a failing test ?

    you can use as the template

    @Test
    void setBufferSizeCutsError() {
      String yaml = " - foo: bar\n   if: 'aaa' == 'bbb'";
      // W2 Removing this also makes it work. But a bigger buffer shouldn't be necessary, right?
      LoadSettings settings = LoadSettings.builder().setBufferSize(yaml.length()).build();
      ParserException exception = assertThrows(ParserException.class,
          () -> new Composer(settings, new ParserImpl(settings, new StreamReader(settings, yaml)))
              .getSingleNode());
      assertTrue(exception.getMessage().contains("foo: bar"));
    }
    

  3. Log in to comment