Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions Source/WTF/wtf/URLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3887,24 +3887,35 @@ auto URLParser::parseHostAndPort(CodePointIterator<CharacterType> iterator) -> H

std::optional<String> 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<Latin1Character>(utf8->span()));
// fromUTF8ReplacingInvalidSequences sizes a Vector<char16_t> by the byte count unless the bytes are all ASCII.
if (!isValidCapacityForVector<char16_t>(percentDecoded.size()) && !charactersAreAllASCII(percentDecoded.span()))
return std::nullopt;
auto percentDecoded = percentDecode(byteCast<Latin1Character>(utf8.span()));
return String::fromUTF8ReplacingInvalidSequences(percentDecoded.span());
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

// 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>
{
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<KeyValuePair<String, String>> URLParser::parseQueryNameAndValue(StringView bytes)
{
auto equalIndex = bytes.find('=');
Expand Down
3 changes: 3 additions & 0 deletions Source/WTF/wtf/URLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#pragma once

#include <limits>
#include <unicode/uidna.h>
#include <wtf/Expected.h>
#include <wtf/Forward.h>
Expand Down Expand Up @@ -56,6 +57,8 @@ class URLParser {

using URLEncodedForm = Vector<KeyValuePair<String, String>>;
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<URLEncodedForm> tryParseURLEncodedForm(StringView, size_t maxPairs = std::numeric_limits<size_t>::max());
WTF_EXPORT_PRIVATE static std::optional<KeyValuePair<String, String>> parseQueryNameAndValue(StringView);
WTF_EXPORT_PRIVATE static String serialize(const URLEncodedForm&);

Expand Down
Loading