diff --git a/AK/Base64.cpp b/AK/Base64.cpp index b70425165e2..8c1806f9fc8 100644 --- a/AK/Base64.cpp +++ b/AK/Base64.cpp @@ -54,14 +54,22 @@ ErrorOr decode_base64url(StringView input) return decode_base64_impl(input, simdutf::base64_url); } -ErrorOr encode_base64(ReadonlyBytes input) +ErrorOr encode_base64(ReadonlyBytes input, OmitPadding omit_padding) { - return encode_base64_impl(input, simdutf::base64_default); + auto options = omit_padding == OmitPadding::Yes + ? simdutf::base64_default_no_padding + : simdutf::base64_default; + + return encode_base64_impl(input, options); } -ErrorOr encode_base64url(ReadonlyBytes input) +ErrorOr encode_base64url(ReadonlyBytes input, OmitPadding omit_padding) { - return encode_base64_impl(input, simdutf::base64_url_with_padding); + auto options = omit_padding == OmitPadding::Yes + ? simdutf::base64_url + : simdutf::base64_url_with_padding; + + return encode_base64_impl(input, options); } } diff --git a/AK/Base64.h b/AK/Base64.h index 73761cceaa2..51db98ab664 100644 --- a/AK/Base64.h +++ b/AK/Base64.h @@ -16,8 +16,13 @@ namespace AK { ErrorOr decode_base64(StringView); ErrorOr decode_base64url(StringView); -ErrorOr encode_base64(ReadonlyBytes); -ErrorOr encode_base64url(ReadonlyBytes); +enum class OmitPadding { + No, + Yes, +}; + +ErrorOr encode_base64(ReadonlyBytes, OmitPadding = OmitPadding::No); +ErrorOr encode_base64url(ReadonlyBytes, OmitPadding = OmitPadding::No); } diff --git a/Tests/AK/TestBase64.cpp b/Tests/AK/TestBase64.cpp index 5fcad1af25b..e8006f84755 100644 --- a/Tests/AK/TestBase64.cpp +++ b/Tests/AK/TestBase64.cpp @@ -73,6 +73,22 @@ TEST_CASE(test_encode) encode_equal("foobar"sv, "Zm9vYmFy"sv); } +TEST_CASE(test_encode_omit_padding) +{ + auto encode_equal = [&](StringView input, StringView expected) { + auto encoded = MUST(encode_base64(input.bytes(), AK::OmitPadding::Yes)); + EXPECT_EQ(encoded, expected); + }; + + encode_equal(""sv, ""sv); + encode_equal("f"sv, "Zg"sv); + encode_equal("fo"sv, "Zm8"sv); + encode_equal("foo"sv, "Zm9v"sv); + encode_equal("foob"sv, "Zm9vYg"sv); + encode_equal("fooba"sv, "Zm9vYmE"sv); + encode_equal("foobar"sv, "Zm9vYmFy"sv); +} + TEST_CASE(test_urldecode) { auto decode_equal = [&](StringView input, StringView expected) { @@ -114,3 +130,24 @@ TEST_CASE(test_urlencode) encode_equal("hello!!world"sv, "aGVsbG8hIXdvcmxk"sv); } + +TEST_CASE(test_urlencode_omit_padding) +{ + auto encode_equal = [&](StringView input, StringView expected) { + auto encoded = MUST(encode_base64url(input.bytes(), AK::OmitPadding::Yes)); + EXPECT_EQ(encoded, expected); + }; + + encode_equal(""sv, ""sv); + encode_equal("f"sv, "Zg"sv); + encode_equal("fo"sv, "Zm8"sv); + encode_equal("foo"sv, "Zm9v"sv); + encode_equal("foob"sv, "Zm9vYg"sv); + encode_equal("fooba"sv, "Zm9vYmE"sv); + encode_equal("foobar"sv, "Zm9vYmFy"sv); + + encode_equal("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."sv, "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEu"sv); + encode_equal("hello?world"sv, "aGVsbG8_d29ybGQ"sv); + + encode_equal("hello!!world"sv, "aGVsbG8hIXdvcmxk"sv); +}