diff --git a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp
index c3a619af44..7440c781ef 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp
@@ -233,14 +233,14 @@ WebIDL::ExceptionOr HTMLFormElement::submit_form(JS::NonnullGCPtr plain_text_encode(Vector const& pairs)
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-mutate-action
-ErrorOr HTMLFormElement::mutate_action_url(AK::URL parsed_action, Vector entry_list, JS::NonnullGCPtr target_navigable, HistoryHandlingBehavior history_handling)
+ErrorOr HTMLFormElement::mutate_action_url(AK::URL parsed_action, Vector entry_list, String encoding, JS::NonnullGCPtr target_navigable, HistoryHandlingBehavior history_handling)
{
// 1. Let pairs be the result of converting to a list of name-value pairs with entry list.
auto pairs = TRY(convert_to_list_of_name_value_pairs(entry_list));
// 2. Let query be the result of running the application/x-www-form-urlencoded serializer with pairs and encoding.
- // FIXME: Pass in encoding.
- auto query = TRY(url_encode(pairs, AK::URL::PercentEncodeSet::ApplicationXWWWFormUrlencoded));
+ auto query = TRY(url_encode(pairs, encoding));
// 3. Set parsed action's query component to query.
parsed_action.set_query(query.to_deprecated_string());
@@ -642,8 +641,7 @@ ErrorOr HTMLFormElement::submit_as_entity_body(AK::URL parsed_action, Vect
auto pairs = TRY(convert_to_list_of_name_value_pairs(entry_list));
// 2. Let body be the result of running the application/x-www-form-urlencoded serializer with pairs and encoding.
- // FIXME: Pass in encoding.
- body = TRY(ByteBuffer::copy(TRY(url_encode(pairs, AK::URL::PercentEncodeSet::ApplicationXWWWFormUrlencoded)).bytes()));
+ body = TRY(ByteBuffer::copy(TRY(url_encode(pairs, encoding)).bytes()));
// 3. Set body to the result of encoding body.
// NOTE: `encoding` refers to `UTF-8 encode`, which body already is encoded as because it uses AK::String.
@@ -713,8 +711,7 @@ ErrorOr HTMLFormElement::mail_with_headers(AK::URL parsed_action, Vector HTMLFormElement::mail_as_body(AK::URL parsed_action, Vector Otherwise
// Let body be the result of running the application/x-www-form-urlencoded serializer with pairs and encoding.
- // FIXME: Pass in encoding.
- body = TRY(url_encode(pairs, AK::URL::PercentEncodeSet::ApplicationXWWWFormUrlencoded));
+ body = TRY(url_encode(pairs, encoding));
break;
}
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.h b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.h
index 9ac43a4608..86e75ef00f 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.h
@@ -96,7 +96,7 @@ private:
ErrorOr pick_an_encoding() const;
- ErrorOr mutate_action_url(AK::URL parsed_action, Vector entry_list, JS::NonnullGCPtr target_navigable, HistoryHandlingBehavior history_handling);
+ ErrorOr mutate_action_url(AK::URL parsed_action, Vector entry_list, String encoding, JS::NonnullGCPtr target_navigable, HistoryHandlingBehavior history_handling);
ErrorOr submit_as_entity_body(AK::URL parsed_action, Vector entry_list, EncodingTypeAttributeState encoding_type, String encoding, JS::NonnullGCPtr target_navigable, HistoryHandlingBehavior history_handling);
void get_action_url(AK::URL parsed_action, JS::NonnullGCPtr target_navigable, HistoryHandlingBehavior history_handling);
ErrorOr mail_with_headers(AK::URL parsed_action, Vector entry_list, String encoding, JS::NonnullGCPtr target_navigable, HistoryHandlingBehavior history_handling);
diff --git a/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp b/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp
index 851d6863ce..3b80540dc0 100644
--- a/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp
+++ b/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp
@@ -1,12 +1,15 @@
/*
* Copyright (c) 2021, Idan Horowitz
+ * Copyright (c) 2023, Shannon Booth
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include
#include
+#include
#include
+#include
#include
#include
#include
@@ -36,17 +39,40 @@ void URLSearchParams::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_url);
}
-ErrorOr url_encode(Vector const& pairs, AK::URL::PercentEncodeSet percent_encode_set)
+// https://url.spec.whatwg.org/#concept-urlencoded-serializer
+// The application/x-www-form-urlencoded serializer takes a list of name-value tuples tuples, with an optional encoding encoding (default UTF-8), and then runs these steps. They return an ASCII string.
+ErrorOr url_encode(Vector const& tuples, StringView encoding)
{
- StringBuilder builder;
- for (size_t i = 0; i < pairs.size(); ++i) {
- TRY(builder.try_append(AK::URL::percent_encode(pairs[i].name, percent_encode_set, AK::URL::SpaceAsPlus::Yes)));
- TRY(builder.try_append('='));
- TRY(builder.try_append(AK::URL::percent_encode(pairs[i].value, percent_encode_set, AK::URL::SpaceAsPlus::Yes)));
- if (i != pairs.size() - 1)
- TRY(builder.try_append('&'));
+ // 1. Set encoding to the result of getting an output encoding from encoding.
+ encoding = TextCodec::get_output_encoding(encoding);
+
+ // 2. Let output be the empty string.
+ StringBuilder output;
+
+ // 3. For each tuple of tuples:
+ for (auto const& tuple : tuples) {
+ // 1. Assert: tuple’s name and tuple’s value are scalar value strings.
+
+ // 2. Let name be the result of running percent-encode after encoding with encoding, tuple’s name, the application/x-www-form-urlencoded percent-encode set, and true.
+ // FIXME: URLParser does not currently implement encoding.
+ auto name = AK::URLParser::percent_encode_after_encoding(tuple.name, AK::URL::PercentEncodeSet::ApplicationXWWWFormUrlencoded, true);
+
+ // 3. Let value be the result of running percent-encode after encoding with encoding, tuple’s value, the application/x-www-form-urlencoded percent-encode set, and true.
+ // FIXME: URLParser does not currently implement encoding.
+ auto value = AK::URLParser::percent_encode_after_encoding(tuple.value, AK::URL::PercentEncodeSet::ApplicationXWWWFormUrlencoded, true);
+
+ // 4. If output is not the empty string, then append U+0026 (&) to output.
+ if (!output.is_empty())
+ TRY(output.try_append('&'));
+
+ // 5. Append name, followed by U+003D (=), followed by value, to output.
+ TRY(output.try_append(name));
+ TRY(output.try_append('='));
+ TRY(output.try_append(value));
}
- return builder.to_string();
+
+ // 4. Return output.
+ return output.to_string();
}
// https://url.spec.whatwg.org/#concept-urlencoded-parser
@@ -292,7 +318,7 @@ WebIDL::ExceptionOr URLSearchParams::to_string() const
auto& vm = realm().vm();
// return the serialization of this’s list.
- return TRY_OR_THROW_OOM(vm, url_encode(m_list, AK::URL::PercentEncodeSet::ApplicationXWWWFormUrlencoded));
+ return TRY_OR_THROW_OOM(vm, url_encode(m_list));
}
JS::ThrowCompletionOr URLSearchParams::for_each(ForEachCallback callback)
diff --git a/Userland/Libraries/LibWeb/URL/URLSearchParams.h b/Userland/Libraries/LibWeb/URL/URLSearchParams.h
index 5d0d45c402..f251cd7472 100644
--- a/Userland/Libraries/LibWeb/URL/URLSearchParams.h
+++ b/Userland/Libraries/LibWeb/URL/URLSearchParams.h
@@ -16,7 +16,7 @@ struct QueryParam {
String name;
String value;
};
-ErrorOr url_encode(Vector const&, AK::URL::PercentEncodeSet);
+ErrorOr url_encode(Vector const&, StringView encoding = "UTF-8"sv);
ErrorOr> url_decode(StringView);
class URLSearchParams : public Bindings::PlatformObject {