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

Allow colons in plain scalars inside flow collections #104

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/scanner.c
Original file line number Diff line number Diff line change
Expand Up @@ -3430,11 +3430,22 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)

while (!IS_BLANKZ(parser->buffer))
{
/* Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". */
/* Check for "x:" + one of ',?[]{}' in the flow context. TODO: Fix the test "spec-08-13".
* This is not completely according to the spec
* See http://yaml.org/spec/1.1/#id907281 9.1.3. Plain
*/

if (parser->flow_level
&& CHECK(parser->buffer, ':')
&& !IS_BLANKZ_AT(parser->buffer, 1)) {
&& (
CHECK_AT(parser->buffer, ',', 1)
|| CHECK_AT(parser->buffer, '?', 1)
|| CHECK_AT(parser->buffer, '[', 1)
|| CHECK_AT(parser->buffer, ']', 1)
|| CHECK_AT(parser->buffer, '{', 1)
|| CHECK_AT(parser->buffer, '}', 1)
)
) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is undesirable. Regardless of how strange it is, [foo:]] is valid YAML 1.1 meaning [ "foo:]" ]. Moreover, ? certainly is not a flow indicator, so I am unsure how it found its way in here.

I think the correct fix would be to remove this if statement altogether (frankly, I have no idea why it is there in the first place; x:x is completely valid in a plain scalar inside flow content). : with succeeding space is handled later on. Note the comment about example 8.13 in the spec. That example is wrong! It shows this YAML:

{
  ? foo :°,
  ?° : bar,
}

° meaning empty scalar. This is not valid according to the productions, because there must be space after the : before the ,.

However, if I understand the rest of the code correctly, removing the if statement would cause [foo:] be parsed as [ "foo:" ] because the code is not designed to eat the character after the : as it should according to the spec. My proposed solution would be having a local ate_colon and then instead of the if:

ate_colon = CHECK(parser->buffer, ':');

and then at the end of the loop:

/* Copy the character. */

if (!READ(parser, string)) goto error;
if (ate_colon) if (!READ(parser, string)) goto error; /* <<< add this line */

end_mark = parser->mark;

if (!CACHE(parser, 2)) goto error;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moreover, ? certainly is not a flow indicator, so I am unsure how it found its way in here.

I added this for consistency, because it's also in the next if-statement. Maybe I should take it out in both statements. Then [foo:?bar] would be allowed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is undesirable. Regardless of how strange it is, [foo:]] is valid YAML 1.1

The point is that this currently is not allowed in libyaml, and I just keep it like that with this change. The only thing which changes is to allow [foo:bar].
ns-plain-char - ,[]{} characters after the colon. So I don't know why this change would be undesirable.

Could you clarify what you mean?

The goal of this PR is to accept things that make sense and are valid, but leaving the other cases alone for now, as I wrote above.

yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
start_mark, "found unexpected ':'");
goto error;
Expand All @@ -3444,7 +3455,7 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)

if ((CHECK(parser->buffer, ':') && IS_BLANKZ_AT(parser->buffer, 1))
|| (parser->flow_level &&
(CHECK(parser->buffer, ',') || CHECK(parser->buffer, ':')
(CHECK(parser->buffer, ',')
|| CHECK(parser->buffer, '?') || CHECK(parser->buffer, '[')
|| CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
|| CHECK(parser->buffer, '}'))))
Expand Down