From 1703cee349db35f41401ea55e692b0ad3b79874d Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 9 Jan 2020 22:59:08 +0300 Subject: [PATCH] Common base64_decode implementation. GitOrigin-RevId: 87bdf798a181799b2f51be9831d77fabf41e3820 --- tdutils/td/utils/base64.cpp | 69 ++++++++++++++++++--------------- tdutils/td/utils/filesystem.cpp | 1 + 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/tdutils/td/utils/base64.cpp b/tdutils/td/utils/base64.cpp index 2408826d..0085d0e8 100644 --- a/tdutils/td/utils/base64.cpp +++ b/tdutils/td/utils/base64.cpp @@ -66,6 +66,14 @@ string base64_encode_impl(Slice input) { return base64; } +string base64_encode(Slice input) { + return base64_encode_impl(input); +} + +string base64url_encode(Slice input) { + return base64_encode_impl(input); +} + template Result base64_drop_padding(Slice base64) { size_t padding_length = 0; @@ -85,9 +93,7 @@ Result base64_drop_padding(Slice base64) { return base64; } -template -Status base64_do_decode(Slice base64, F &&append) { - auto table = get_character_table(); +static Status do_base64_decode_impl(Slice base64, const unsigned char *table, char *ptr) { for (size_t i = 0; i < base64.size();) { size_t left = min(base64.size() - i, static_cast(4)); int c = 0; @@ -98,58 +104,57 @@ Status base64_do_decode(Slice base64, F &&append) { } c |= value << ((3 - t) * 6); } - append(static_cast(static_cast(c >> 16))); // implementation-defined + *ptr++ = static_cast(static_cast(c >> 16)); // implementation-defined if (left == 2) { if ((c & ((1 << 16) - 1)) != 0) { return Status::Error("Wrong padding in the string"); } } else { - append(static_cast(static_cast(c >> 8))); // implementation-defined + *ptr++ = static_cast(static_cast(c >> 8)); // implementation-defined if (left == 3) { if ((c & ((1 << 8) - 1)) != 0) { return Status::Error("Wrong padding in the string"); } } else { - append(static_cast(static_cast(c))); // implementation-defined + *ptr++ = static_cast(static_cast(c)); // implementation-defined } } } return Status::OK(); } -Result base64_decode(Slice base64) { - TRY_RESULT_ASSIGN(base64, base64_drop_padding(base64)); +template +static T create_empty(size_t size); - string output; - output.reserve((base64.size() >> 2) * 3 + (((base64.size() & 3) + 1) >> 1)); - TRY_STATUS(base64_do_decode(base64, [&output](char c) { output += c; })); - return output; +template <> +string create_empty(size_t size) { + return string(size, '\0'); +} + +template <> +SecureString create_empty(size_t size) { + return SecureString{size}; +} + +template +static Result base64_decode_impl(Slice base64) { + TRY_RESULT_ASSIGN(base64, base64_drop_padding(base64)); + + T result = create_empty(base64.size() / 4 * 3 + ((base64.size() & 3) + 1) / 2); + TRY_STATUS(do_base64_decode_impl(base64, get_character_table(), as_mutable_slice(result).begin())); + return result; +} + +Result base64_decode(Slice base64) { + return base64_decode_impl(base64); } Result base64_decode_secure(Slice base64) { - TRY_RESULT_ASSIGN(base64, base64_drop_padding(base64)); - - SecureString output((base64.size() >> 2) * 3 + (((base64.size() & 3) + 1) >> 1)); - char *ptr = output.as_mutable_slice().begin(); - TRY_STATUS(base64_do_decode(base64, [&ptr](char c) { *ptr++ = c; })); - return std::move(output); -} - -string base64_encode(Slice input) { - return base64_encode_impl(input); -} - -string base64url_encode(Slice input) { - return base64_encode_impl(input); + return base64_decode_impl(base64); } Result base64url_decode(Slice base64) { - TRY_RESULT_ASSIGN(base64, base64_drop_padding(base64)); - - string output; - output.reserve((base64.size() >> 2) * 3 + (((base64.size() & 3) + 1) >> 1)); - TRY_STATUS(base64_do_decode(base64, [&output](char c) { output += c; })); - return output; + return base64_decode_impl(base64); } template diff --git a/tdutils/td/utils/filesystem.cpp b/tdutils/td/utils/filesystem.cpp index 5706b4ec..092fcb1b 100644 --- a/tdutils/td/utils/filesystem.cpp +++ b/tdutils/td/utils/filesystem.cpp @@ -32,6 +32,7 @@ template <> BufferSlice create_empty(size_t size) { return BufferSlice{size}; } + template <> SecureString create_empty(size_t size) { return SecureString{size};