diff --git a/Source/WTF/wtf/URLParser.cpp b/Source/WTF/wtf/URLParser.cpp index 70476811098b..7c1fea25d7a7 100644 --- a/Source/WTF/wtf/URLParser.cpp +++ b/Source/WTF/wtf/URLParser.cpp @@ -3887,24 +3887,35 @@ auto URLParser::parseHostAndPort(CodePointIterator iterator) -> H std::optional URLParser::formURLDecode(StringView input) { - auto utf8 = input.utf8(StrictConversion); - if (utf8.isNull()) + auto utf8 = input.tryGetUTF8(StrictConversion); + if (!utf8) + return std::nullopt; + auto percentDecoded = percentDecode(byteCast(utf8->span())); + // fromUTF8ReplacingInvalidSequences sizes a Vector by the byte count unless the bytes are all ASCII. + if (!isValidCapacityForVector(percentDecoded.size()) && !charactersAreAllASCII(percentDecoded.span())) return std::nullopt; - auto percentDecoded = percentDecode(byteCast(utf8.span())); return String::fromUTF8ReplacingInvalidSequences(percentDecoded.span()); } // https://url.spec.whatwg.org/#concept-urlencoded-parser -auto URLParser::parseURLEncodedForm(StringView input) -> URLEncodedForm +auto URLParser::tryParseURLEncodedForm(StringView input, size_t maxPairs) -> std::optional { URLEncodedForm output; for (StringView bytes : input.split('&')) { - if (auto nameAndValue = parseQueryNameAndValue(bytes)) - output.append(WTF::move(*nameAndValue)); + auto nameAndValue = parseQueryNameAndValue(bytes); + if (!nameAndValue) + continue; + if (output.size() >= maxPairs || !output.tryAppend(WTF::move(*nameAndValue))) + return std::nullopt; } return output; } +auto URLParser::parseURLEncodedForm(StringView input) -> URLEncodedForm +{ + return tryParseURLEncodedForm(input).value_or(URLEncodedForm { }); +} + std::optional> URLParser::parseQueryNameAndValue(StringView bytes) { auto equalIndex = bytes.find('='); diff --git a/Source/WTF/wtf/URLParser.h b/Source/WTF/wtf/URLParser.h index 95c3361e6822..86a5215a84ad 100644 --- a/Source/WTF/wtf/URLParser.h +++ b/Source/WTF/wtf/URLParser.h @@ -25,6 +25,7 @@ #pragma once +#include #include #include #include @@ -56,6 +57,8 @@ class URLParser { using URLEncodedForm = Vector>; WTF_EXPORT_PRIVATE static URLEncodedForm parseURLEncodedForm(StringView); + // Returns nullopt when the form has more than maxPairs pairs, or more than the Vector can grow to hold. + WTF_EXPORT_PRIVATE static std::optional tryParseURLEncodedForm(StringView, size_t maxPairs = std::numeric_limits::max()); WTF_EXPORT_PRIVATE static std::optional> parseQueryNameAndValue(StringView); WTF_EXPORT_PRIVATE static String serialize(const URLEncodedForm&);