Skip to content

Commit

Permalink
Fix URI validation for tag shorthands (#403)
Browse files Browse the repository at this point in the history
  • Loading branch information
fktn-k authored Sep 29, 2024
1 parent 2ac58a8 commit b14f79e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 17 deletions.
24 changes: 16 additions & 8 deletions include/fkYAML/detail/input/lexical_analyzer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,16 +629,24 @@ class lexical_analyzer {
// See the "Tag Shorthands" section in https://yaml.org/spec/1.2.2/#691-node-tags.
emit_error("named handle has no suffix.");
}
}

// get the position of the beginning of a suffix. (!handle!suffix)
std::size_t last_tag_prefix_pos = token.str.find_last_of('!');
FK_YAML_ASSERT(last_tag_prefix_pos != str_view::npos);
// get the position of last tag prefix character (!) to extract body of tag shorthands.
// tag shorthand is either primary(!tag), secondary(!!tag) or named(!handle!tag).
std::size_t last_tag_prefix_pos = token.str.find_last_of('!');
FK_YAML_ASSERT(last_tag_prefix_pos != str_view::npos);

str_view tag_uri = token.str.substr(last_tag_prefix_pos + 1);
bool is_valid_uri = uri_encoding::validate(tag_uri.begin(), tag_uri.end());
if FK_YAML_UNLIKELY (!is_valid_uri) {
emit_error("Invalid URI character is found in a named tag handle.");
}
str_view tag_uri = token.str.substr(last_tag_prefix_pos + 1);
bool is_valid_uri = uri_encoding::validate(tag_uri.begin(), tag_uri.end());
if FK_YAML_UNLIKELY (!is_valid_uri) {
emit_error("Invalid URI character is found in a named tag handle.");
}

// Tag shorthands cannot contain flow indicators({}[],).
// See the "Tag Shorthands" section in https://yaml.org/spec/1.2.2/#691-node-tags.
std::size_t invalid_char_pos = tag_uri.find_first_of("{}[],");
if (invalid_char_pos != str_view::npos) {
emit_error("Tag shorthand cannot contain flow indicators({}[],).");
}
}

Expand Down
24 changes: 16 additions & 8 deletions single_include/fkYAML/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4645,16 +4645,24 @@ class lexical_analyzer {
// See the "Tag Shorthands" section in https://yaml.org/spec/1.2.2/#691-node-tags.
emit_error("named handle has no suffix.");
}
}

// get the position of the beginning of a suffix. (!handle!suffix)
std::size_t last_tag_prefix_pos = token.str.find_last_of('!');
FK_YAML_ASSERT(last_tag_prefix_pos != str_view::npos);
// get the position of last tag prefix character (!) to extract body of tag shorthands.
// tag shorthand is either primary(!tag), secondary(!!tag) or named(!handle!tag).
std::size_t last_tag_prefix_pos = token.str.find_last_of('!');
FK_YAML_ASSERT(last_tag_prefix_pos != str_view::npos);

str_view tag_uri = token.str.substr(last_tag_prefix_pos + 1);
bool is_valid_uri = uri_encoding::validate(tag_uri.begin(), tag_uri.end());
if FK_YAML_UNLIKELY (!is_valid_uri) {
emit_error("Invalid URI character is found in a named tag handle.");
}
str_view tag_uri = token.str.substr(last_tag_prefix_pos + 1);
bool is_valid_uri = uri_encoding::validate(tag_uri.begin(), tag_uri.end());
if FK_YAML_UNLIKELY (!is_valid_uri) {
emit_error("Invalid URI character is found in a named tag handle.");
}

// Tag shorthands cannot contain flow indicators({}[],).
// See the "Tag Shorthands" section in https://yaml.org/spec/1.2.2/#691-node-tags.
std::size_t invalid_char_pos = tag_uri.find_first_of("{}[],");
if (invalid_char_pos != str_view::npos) {
emit_error("Tag shorthand cannot contain flow indicators({}[],).");
}
}

Expand Down
17 changes: 16 additions & 1 deletion test/unit_test/test_lexical_analyzer_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1105,7 +1105,22 @@ TEST_CASE("LexicalAnalyzer_Tag") {
fkyaml::detail::str_view("!<%f:oo> tag"),
fkyaml::detail::str_view("!<!%f:oo> tag"),
fkyaml::detail::str_view("!foo! tag"),
fkyaml::detail::str_view("!foo!%f:oo tag"));
fkyaml::detail::str_view("!foo!%f:oo tag"),
fkyaml::detail::str_view("!foo{ tag"),
fkyaml::detail::str_view("!foo} tag"),
fkyaml::detail::str_view("!foo[ tag"),
fkyaml::detail::str_view("!foo] tag"),
fkyaml::detail::str_view("!foo, tag"),
fkyaml::detail::str_view("!!foo{ tag"),
fkyaml::detail::str_view("!!foo} tag"),
fkyaml::detail::str_view("!!foo[ tag"),
fkyaml::detail::str_view("!!foo] tag"),
fkyaml::detail::str_view("!!foo, tag"),
fkyaml::detail::str_view("!foo!bar{ tag"),
fkyaml::detail::str_view("!foo!bar} tag"),
fkyaml::detail::str_view("!foo!bar[ tag"),
fkyaml::detail::str_view("!foo!bar] tag"),
fkyaml::detail::str_view("!foo!bar, tag"));

fkyaml::detail::lexical_analyzer lexer(input);
REQUIRE_THROWS_AS(token = lexer.get_next_token(), fkyaml::parse_error);
Expand Down

0 comments on commit b14f79e

Please sign in to comment.