Skip to content
Merged
Show file tree
Hide file tree
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
12 changes: 11 additions & 1 deletion src/core/yaml/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,17 @@ class Parser {
switch (current_token.type) {
case TokenType::Scalar: {
auto next{this->next_token()};
if (next.has_value() && next->type == TokenType::BlockMappingValue) {
// YAML 1.2.2 Section 7.4.2: the value of an entry of a flow collection
// is a single node, and a pair carrying no brackets of its own is a
// node only where a flow sequence takes its entries. Leaving the
// indicator unread in that position hands the scalar back on its own,
// which is what lets the caller report the separator the entry is
// really missing
const auto pair_without_brackets_allowed{
this->lexer_->flow_level() == 0 ||
context != JSON::ParseContext::Property};
if (next.has_value() && next->type == TokenType::BlockMappingValue &&
pair_without_brackets_allowed) {
if (current_token.multiline) [[unlikely]] {
throw YAMLParseError{current_token.line, current_token.column,
"Multi-line implicit mapping key"};
Expand Down
32 changes: 32 additions & 0 deletions test/yaml/yaml_parse_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2769,3 +2769,35 @@ TEST(implicit_key_anchor_on_a_plain_scalar_stays_a_string) {
sourcemeta::core::parse_json(R"JSON({ "foo": 1, "b": "foo" })JSON")};
EXPECT_EQ(result, expected);
}

// YAML 1.2.2 Section 7.4.2: the entries of a flow mapping are separated by a
// comma, and the value of an entry is a single node, so a second pair cannot
// stand in the place of the first entry's value
TEST(flow_mapping_entries_without_a_comma) {
const std::string input{"{a: 1 b: 2}"};
try {
sourcemeta::core::parse_yaml(input);
FAIL();
} catch (const sourcemeta::core::YAMLParseError &error) {
EXPECT_STREQ(error.what(), "Missing comma between flow mapping entries");
}
}

TEST(flow_sequence_single_pair_entry_still_parses) {
const std::string input{"[a: 1]"};
const auto result{sourcemeta::core::parse_yaml(input)};
EXPECT_TRUE(result.is_array());
EXPECT_EQ(result.size(), 1);
EXPECT_TRUE(result.at(0).is_object());
EXPECT_EQ(result.at(0).at("a"), sourcemeta::core::JSON{1});
}

TEST(flow_sequence_single_pair_value_cannot_be_another_pair) {
const std::string input{"[a: b: c]"};
try {
sourcemeta::core::parse_yaml(input);
FAIL();
} catch (const sourcemeta::core::YAMLParseError &error) {
EXPECT_STREQ(error.what(), "Missing comma in flow sequence");
}
}
Loading