From 6cc1d2edb0783e4616d79c2c8e91fa3da8c580eb Mon Sep 17 00:00:00 2001 From: AJ Heller Date: Tue, 8 Dec 2020 18:18:59 -0800 Subject: [PATCH] Fix overpermissive percent-decoding of URIs ('%eth1' case) Invalid `%nn` 3-character strings were being incorrectly decoded. For example, in `%eth1`, the `%e` was being translated to ASCII 14, while the correct behavior is to leave `%eth1` unchanged since the string `%et` is an invalid 3-character percent encoding. --- src/core/lib/uri/uri_parser.cc | 4 +++- test/core/uri/uri_parser_test.cc | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/lib/uri/uri_parser.cc b/src/core/lib/uri/uri_parser.cc index e47daeb5a4b..ea1033069e0 100644 --- a/src/core/lib/uri/uri_parser.cc +++ b/src/core/lib/uri/uri_parser.cc @@ -46,13 +46,15 @@ std::string PercentDecode(absl::string_view str) { std::string unescaped; out.reserve(str.size()); for (size_t i = 0; i < str.length(); i++) { + unescaped = ""; if (str[i] != '%') { out += str[i]; continue; } if (i + 3 >= str.length() || !absl::CUnescape(absl::StrCat("\\x", str.substr(i + 1, 2)), - &unescaped)) { + &unescaped) || + unescaped.length() > 1) { out += str[i]; } else { out += unescaped[0]; diff --git a/test/core/uri/uri_parser_test.cc b/test/core/uri/uri_parser_test.cc index 70f44ffe48d..4db01f3e210 100644 --- a/test/core/uri/uri_parser_test.cc +++ b/test/core/uri/uri_parser_test.cc @@ -146,6 +146,8 @@ int main(int argc, char** argv) { {{"bar", ""}}, "lol?/"); test_succeeds("ipv6:[2001:db8::1%252]:12345", "ipv6", "", "[2001:db8::1%2]:12345", {}, {}, ""); + test_succeeds("ipv6:[fe80::90%eth1.sky1]:6010", "ipv6", "", + "[fe80::90%eth1.sky1]:6010", {}, {}, ""); test_succeeds("https://www.google.com/?a=1%26b%3D2&c=3", "https", "www.google.com", "/", {{"c", "3"}, {"a", "1&b=2"}}, {{"a", "1&b=2"}, {"c", "3"}}, "");