Skip to content

Commit

Permalink
detect missing the end of directives markers (---)
Browse files Browse the repository at this point in the history
  • Loading branch information
fktn-k committed Jun 15, 2024
1 parent 6ee80b0 commit 222f3c5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
14 changes: 13 additions & 1 deletion include/fkYAML/detail/input/deserializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ class basic_deserializer {
/// @param lexer The lexical analyzer to be used.
/// @param last_type The variable to store the last lexical token type.
void deserialize_directives(lexer_type& lexer, lexical_token_t& last_type) {
bool lacks_end_of_directives_marker = false;

for (;;) {
lexical_token_t type = lexer.get_next_token();

Expand All @@ -179,6 +181,7 @@ class basic_deserializer {

mp_meta->version = convert_yaml_version(lexer.get_yaml_version());
mp_meta->is_version_specified = true;
lacks_end_of_directives_marker = true;
break;
case lexical_token_t::TAG_DIRECTIVE: {
const std::string& tag_handle = lexer.get_tag_handle();
Expand All @@ -192,6 +195,7 @@ class basic_deserializer {
lexer.get_last_token_begin_pos());
}
mp_meta->primary_handle_prefix = lexer.get_tag_prefix();
lacks_end_of_directives_marker = true;
break;
}
case 2: {
Expand All @@ -203,6 +207,7 @@ class basic_deserializer {
lexer.get_last_token_begin_pos());
}
mp_meta->secondary_handle_prefix = lexer.get_tag_prefix();
lacks_end_of_directives_marker = true;
break;
}
default: {
Expand All @@ -214,6 +219,7 @@ class basic_deserializer {
lexer.get_lines_processed(),
lexer.get_last_token_begin_pos());
}
lacks_end_of_directives_marker = true;
break;
}
}
Expand All @@ -223,9 +229,15 @@ class basic_deserializer {
// TODO: should output a warning log. Currently just ignore this case.
break;
case lexical_token_t::END_OF_DIRECTIVES:
// Ignore this directives end marker so the caller will get the beginning token of the contents.
lacks_end_of_directives_marker = false;
break;
default:
if (lacks_end_of_directives_marker) {
throw parse_error(
"The end of directives marker (---) is missing after directives.",
lexer.get_lines_processed(),
lexer.get_last_token_begin_pos());
}
// end the parsing of directives if the other tokens are found.
last_type = type;
return;
Expand Down
14 changes: 13 additions & 1 deletion single_include/fkYAML/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4394,6 +4394,8 @@ class basic_deserializer {
/// @param lexer The lexical analyzer to be used.
/// @param last_type The variable to store the last lexical token type.
void deserialize_directives(lexer_type& lexer, lexical_token_t& last_type) {
bool lacks_end_of_directives_marker = false;

for (;;) {
lexical_token_t type = lexer.get_next_token();

Expand All @@ -4408,6 +4410,7 @@ class basic_deserializer {

mp_meta->version = convert_yaml_version(lexer.get_yaml_version());
mp_meta->is_version_specified = true;
lacks_end_of_directives_marker = true;
break;
case lexical_token_t::TAG_DIRECTIVE: {
const std::string& tag_handle = lexer.get_tag_handle();
Expand All @@ -4421,6 +4424,7 @@ class basic_deserializer {
lexer.get_last_token_begin_pos());
}
mp_meta->primary_handle_prefix = lexer.get_tag_prefix();
lacks_end_of_directives_marker = true;
break;
}
case 2: {
Expand All @@ -4432,6 +4436,7 @@ class basic_deserializer {
lexer.get_last_token_begin_pos());
}
mp_meta->secondary_handle_prefix = lexer.get_tag_prefix();
lacks_end_of_directives_marker = true;
break;
}
default: {
Expand All @@ -4443,6 +4448,7 @@ class basic_deserializer {
lexer.get_lines_processed(),
lexer.get_last_token_begin_pos());
}
lacks_end_of_directives_marker = true;
break;
}
}
Expand All @@ -4452,9 +4458,15 @@ class basic_deserializer {
// TODO: should output a warning log. Currently just ignore this case.
break;
case lexical_token_t::END_OF_DIRECTIVES:
// Ignore this directives end marker so the caller will get the beginning token of the contents.
lacks_end_of_directives_marker = false;
break;
default:
if (lacks_end_of_directives_marker) {
throw parse_error(
"The end of directives marker (---) is missing after directives.",
lexer.get_lines_processed(),
lexer.get_last_token_begin_pos());
}
// end the parsing of directives if the other tokens are found.
last_type = type;
return;
Expand Down
11 changes: 11 additions & 0 deletions test/unit_test/test_deserializer_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1921,6 +1921,11 @@ TEST_CASE("Deserializer_YAMLVerDirective") {
REQUIRE_THROWS_AS(
deserializer.deserialize(fkyaml::detail::input_adapter("%YAML 1.1\n%YAML 1.2\n")), fkyaml::parse_error);
}

SECTION("lacks the end of directives marker after YAML directive") {
REQUIRE_THROWS_AS(
deserializer.deserialize(fkyaml::detail::input_adapter("%YAML 1.2\nfoo: bar")), fkyaml::parse_error);
}
}

TEST_CASE("Deserializer_TagDirective") {
Expand Down Expand Up @@ -2010,6 +2015,12 @@ TEST_CASE("Deserializer_TagDirective") {
"foo: bar";
REQUIRE_THROWS_AS(deserializer.deserialize(fkyaml::detail::input_adapter(input)), fkyaml::parse_error);
}

SECTION("lacks the end of directives marker after TAG directive") {
std::string input = "%TAG ! tag:test.com,2000:\n"
"foo: bar";
REQUIRE_THROWS_AS(deserializer.deserialize(fkyaml::detail::input_adapter(input)), fkyaml::parse_error);
}
}

TEST_CASE("Deserializer_InvalidDirective") {
Expand Down

0 comments on commit 222f3c5

Please sign in to comment.