LibWeb: Move url_{encode, decode} to URL/URLSearchParams.{h, cpp}

The new URL built-in that will reside in URL.{h, cpp} will have an
URLSearchParams member, which means it has to include its header, and
as such URLSearchParams.h can't include URL's header, which it needs as
it uses the url_{encode, decode} functions.
This commit is contained in:
Idan Horowitz 2021-09-13 21:50:05 +03:00 committed by Andreas Kling
parent 23997005cf
commit af5b62d8cd
Notes: sideshowbarker 2024-07-18 03:59:46 +09:00
4 changed files with 64 additions and 69 deletions

View file

@ -5,63 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/StringBuilder.h>
#include <LibWeb/URL/URL.h>
namespace Web::URL {
String url_encode(const Vector<QueryParam>& pairs, AK::URL::PercentEncodeSet percent_encode_set)
{
StringBuilder builder;
for (size_t i = 0; i < pairs.size(); ++i) {
builder.append(AK::URL::percent_encode(pairs[i].name, percent_encode_set));
builder.append('=');
builder.append(AK::URL::percent_encode(pairs[i].value, percent_encode_set));
if (i != pairs.size() - 1)
builder.append('&');
}
return builder.to_string();
}
Vector<QueryParam> url_decode(StringView const& input)
{
// 1. Let sequences be the result of splitting input on 0x26 (&).
auto sequences = input.split_view('&');
// 2. Let output be an initially empty list of name-value tuples where both name and value hold a string.
Vector<QueryParam> output;
// 3. For each byte sequence bytes in sequences:
for (auto bytes : sequences) {
// 1. If bytes is the empty byte sequence, then continue.
if (bytes.is_empty())
continue;
StringView name;
StringView value;
// 2. If bytes contains a 0x3D (=), then let name be the bytes from the start of bytes up to but excluding its first 0x3D (=), and let value be the bytes, if any, after the first 0x3D (=) up to the end of bytes. If 0x3D (=) is the first byte, then name will be the empty byte sequence. If it is the last, then value will be the empty byte sequence.
if (auto index = bytes.find('='); index.has_value()) {
name = bytes.substring_view(0, *index);
value = bytes.substring_view(*index + 1);
}
// 3. Otherwise, let name have the value of bytes and let value be the empty byte sequence.
else {
name = bytes;
value = ""sv;
}
// 4. Replace any 0x2B (+) in name and value with 0x20 (SP).
auto space_decoded_name = name.replace("+"sv, " "sv, true);
// 5. Let nameString and valueString be the result of running UTF-8 decode without BOM on the percent-decoding of name and value, respectively.
auto name_string = AK::URL::percent_decode(space_decoded_name);
auto value_string = AK::URL::percent_decode(value);
output.empend(move(name_string), move(value_string));
}
return output;
}
}

View file

@ -7,17 +7,5 @@
#pragma once
#include <AK/String.h>
#include <AK/URL.h>
#include <AK/Vector.h>
namespace Web::URL {
struct QueryParam {
String name;
String value;
};
String url_encode(const Vector<QueryParam>&, AK::URL::PercentEncodeSet);
Vector<QueryParam> url_decode(StringView const&);
}

View file

@ -5,11 +5,66 @@
*/
#include <AK/QuickSort.h>
#include <AK/StringBuilder.h>
#include <AK/Utf8View.h>
#include <LibWeb/URL/URLSearchParams.h>
namespace Web::URL {
String url_encode(const Vector<QueryParam>& pairs, AK::URL::PercentEncodeSet percent_encode_set)
{
StringBuilder builder;
for (size_t i = 0; i < pairs.size(); ++i) {
builder.append(AK::URL::percent_encode(pairs[i].name, percent_encode_set));
builder.append('=');
builder.append(AK::URL::percent_encode(pairs[i].value, percent_encode_set));
if (i != pairs.size() - 1)
builder.append('&');
}
return builder.to_string();
}
Vector<QueryParam> url_decode(StringView const& input)
{
// 1. Let sequences be the result of splitting input on 0x26 (&).
auto sequences = input.split_view('&');
// 2. Let output be an initially empty list of name-value tuples where both name and value hold a string.
Vector<QueryParam> output;
// 3. For each byte sequence bytes in sequences:
for (auto bytes : sequences) {
// 1. If bytes is the empty byte sequence, then continue.
if (bytes.is_empty())
continue;
StringView name;
StringView value;
// 2. If bytes contains a 0x3D (=), then let name be the bytes from the start of bytes up to but excluding its first 0x3D (=), and let value be the bytes, if any, after the first 0x3D (=) up to the end of bytes. If 0x3D (=) is the first byte, then name will be the empty byte sequence. If it is the last, then value will be the empty byte sequence.
if (auto index = bytes.find('='); index.has_value()) {
name = bytes.substring_view(0, *index);
value = bytes.substring_view(*index + 1);
}
// 3. Otherwise, let name have the value of bytes and let value be the empty byte sequence.
else {
name = bytes;
value = ""sv;
}
// 4. Replace any 0x2B (+) in name and value with 0x20 (SP).
auto space_decoded_name = name.replace("+"sv, " "sv, true);
// 5. Let nameString and valueString be the result of running UTF-8 decode without BOM on the percent-decoding of name and value, respectively.
auto name_string = AK::URL::percent_decode(space_decoded_name);
auto value_string = AK::URL::percent_decode(value);
output.empend(move(name_string), move(value_string));
}
return output;
}
DOM::ExceptionOr<NonnullRefPtr<URLSearchParams>> URLSearchParams::create_with_global_object(Bindings::WindowObject&, String const& init)
{
// 1. If init is a string and starts with U+003F (?), then remove the first code point from init.

View file

@ -6,12 +6,20 @@
#pragma once
#include <AK/URL.h>
#include <AK/Vector.h>
#include <LibWeb/Bindings/Wrappable.h>
#include <LibWeb/DOM/ExceptionOr.h>
#include <LibWeb/URL/URL.h>
namespace Web::URL {
struct QueryParam {
String name;
String value;
};
String url_encode(const Vector<QueryParam>&, AK::URL::PercentEncodeSet);
Vector<QueryParam> url_decode(StringView const&);
class URLSearchParams : public Bindings::Wrappable
, public RefCounted<URLSearchParams> {
public: