1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 10:41:16 +02:00

url: make percentEncode stricter, expose and unit test it

This commit is contained in:
Yorick van Pelt 2023-02-07 16:44:37 +01:00
parent 92611e6e4c
commit 0844856c84
No known key found for this signature in database
GPG key ID: A36E70F9DC014A15
3 changed files with 45 additions and 6 deletions

View file

@ -88,17 +88,22 @@ std::map<std::string, std::string> decodeQuery(const std::string & query)
return result;
}
std::string percentEncode(std::string_view s)
const static std::string allowedInQuery = ":@/?";
const static std::string allowedInPath = ":@/";
std::string percentEncode(std::string_view s, std::string_view keep)
{
std::string res;
for (auto & c : s)
// unreserved + keep
if ((c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z')
|| (c >= '0' && c <= '9')
|| strchr("-._~!$&'()*+,;=:@", c))
|| strchr("-._~", c)
|| keep.find(c) != std::string::npos)
res += c;
else
res += fmt("%%%02x", (unsigned int) c);
res += fmt("%%%02X", (unsigned int) c);
return res;
}
@ -109,9 +114,9 @@ std::string encodeQuery(const std::map<std::string, std::string> & ss)
for (auto & [name, value] : ss) {
if (!first) res += '&';
first = false;
res += percentEncode(name);
res += percentEncode(name, allowedInQuery);
res += '=';
res += percentEncode(value);
res += percentEncode(value, allowedInQuery);
}
return res;
}
@ -122,7 +127,7 @@ std::string ParsedURL::to_string() const
scheme
+ ":"
+ (authority ? "//" + *authority : "")
+ path
+ percentEncode(path, allowedInPath)
+ (query.empty() ? "" : "?" + encodeQuery(query))
+ (fragment.empty() ? "" : "#" + percentEncode(fragment));
}