diff options
author | Ben Wiederhake <BenWiederhake.GitHub@gmx.de> | 2021-10-23 15:43:59 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-10-23 19:16:40 +0100 |
commit | cb868cfa41072e08987e1c32f117483445ba197d (patch) | |
tree | 89660af33860e44523b81ef66fbf375f6533eb57 /AK/Base64.cpp | |
parent | 3bf1f7ae874918365acedc3d511b60b066b9d4aa (diff) | |
download | serenity-cb868cfa41072e08987e1c32f117483445ba197d.zip |
AK+Everywhere: Make Base64 decoding fallible
Diffstat (limited to 'AK/Base64.cpp')
-rw-r--r-- | AK/Base64.cpp | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/AK/Base64.cpp b/AK/Base64.cpp index 006eeebf1d..4d0a419f4a 100644 --- a/AK/Base64.cpp +++ b/AK/Base64.cpp @@ -6,10 +6,7 @@ #include <AK/Array.h> #include <AK/Base64.h> -#include <AK/ByteBuffer.h> -#include <AK/String.h> #include <AK/StringBuilder.h> -#include <AK/StringView.h> #include <AK/Types.h> #include <AK/Vector.h> @@ -33,7 +30,8 @@ static constexpr auto make_alphabet() static constexpr auto make_lookup_table() { constexpr auto alphabet = make_alphabet(); - Array<u8, 256> table {}; + Array<i16, 256> table; + table.fill(-1); for (size_t i = 0; i < alphabet.size(); ++i) { table[alphabet[i]] = i; } @@ -50,19 +48,31 @@ size_t calculate_base64_encoded_length(ReadonlyBytes input) return ((4 * input.size() / 3) + 3) & ~3; } -ByteBuffer decode_base64(const StringView& input) +Optional<ByteBuffer> decode_base64(const StringView& input) { - auto get = [&](const size_t offset, bool* is_padding = nullptr) -> u8 { + auto get = [&](const size_t offset, bool* is_padding) -> Optional<u8> { constexpr auto table = make_lookup_table(); if (offset >= input.length()) return 0; if (input[offset] == '=') { - if (is_padding) - *is_padding = true; + if (!is_padding) + return {}; + *is_padding = true; return 0; } - return table[static_cast<unsigned char>(input[offset])]; + i16 result = table[static_cast<unsigned char>(input[offset])]; + if (result < 0) + return {}; + VERIFY(result < 256); + return { result }; }; +#define TRY_GET(index, is_padding) \ + ({ \ + auto _temporary_result = get(index, is_padding); \ + if (!_temporary_result.has_value()) \ + return {}; \ + _temporary_result.value(); \ + }) Vector<u8> output; output.ensure_capacity(calculate_base64_decoded_length(input)); @@ -71,10 +81,10 @@ ByteBuffer decode_base64(const StringView& input) bool in2_is_padding = false; bool in3_is_padding = false; - const u8 in0 = get(i); - const u8 in1 = get(i + 1); - const u8 in2 = get(i + 2, &in2_is_padding); - const u8 in3 = get(i + 3, &in3_is_padding); + const u8 in0 = TRY_GET(i, nullptr); + const u8 in1 = TRY_GET(i + 1, nullptr); + const u8 in2 = TRY_GET(i + 2, &in2_is_padding); + const u8 in3 = TRY_GET(i + 3, &in3_is_padding); const u8 out0 = (in0 << 2) | ((in1 >> 4) & 3); const u8 out1 = ((in1 & 0xf) << 4) | ((in2 >> 2) & 0xf); @@ -87,8 +97,7 @@ ByteBuffer decode_base64(const StringView& input) output.append(out2); } - // FIXME: Handle OOM failure. - return ByteBuffer::copy(output).release_value(); + return ByteBuffer::copy(output); } String encode_base64(ReadonlyBytes input) |