From de19dcf81aad60d4f86e31d1e9ff46b071b93903 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Mon, 13 Sep 2021 00:59:12 +0300 Subject: [PATCH] LibWeb: Add URL::url_decode for decoding form url encoded parameters --- Userland/Libraries/LibWeb/URL/URL.cpp | 42 ++++++++++++++++++++++++++- Userland/Libraries/LibWeb/URL/URL.h | 2 ++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibWeb/URL/URL.cpp b/Userland/Libraries/LibWeb/URL/URL.cpp index 4bb41d92f1..f201b8f979 100644 --- a/Userland/Libraries/LibWeb/URL/URL.cpp +++ b/Userland/Libraries/LibWeb/URL/URL.cpp @@ -6,7 +6,6 @@ */ #include -#include #include namespace Web::URL { @@ -24,4 +23,45 @@ String url_encode(const Vector& pairs, AK::URL::PercentEncodeSet per return builder.to_string(); } +Vector 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 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; +} + } diff --git a/Userland/Libraries/LibWeb/URL/URL.h b/Userland/Libraries/LibWeb/URL/URL.h index a8c65aa5c2..2ea27fe772 100644 --- a/Userland/Libraries/LibWeb/URL/URL.h +++ b/Userland/Libraries/LibWeb/URL/URL.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include namespace Web::URL { @@ -17,5 +18,6 @@ struct QueryParam { String value; }; String url_encode(const Vector&, AK::URL::PercentEncodeSet); +Vector url_decode(StringView const&); }