diff --git a/include/etl/base64.h b/include/etl/base64.h index 5df99bb9..484bf595 100644 --- a/include/etl/base64.h +++ b/include/etl/base64.h @@ -119,16 +119,20 @@ namespace etl RFC_2152, RFC_3501, RFC_4648, + RFC_4648_PADDING, RFC_4648_URL, + RFC_4648_URL_PADDING, }; ETL_DECLARE_ENUM_TYPE(Encoding, int) //ETL_ENUM_TYPE(RFC_1421, "RFC_1421") // Not implemented yet //ETL_ENUM_TYPE(RFC_2045, "RFC_2045") // Not implemented yet - ETL_ENUM_TYPE(RFC_2152, "RFC_2152") - ETL_ENUM_TYPE(RFC_3501, "RFC_3501") - ETL_ENUM_TYPE(RFC_4648, "RFC_4648") - ETL_ENUM_TYPE(RFC_4648_URL, "RFC_4648_URL") + ETL_ENUM_TYPE(RFC_2152, "RFC_2152") + ETL_ENUM_TYPE(RFC_3501, "RFC_3501") + ETL_ENUM_TYPE(RFC_4648, "RFC_4648") + ETL_ENUM_TYPE(RFC_4648_PADDING, "RFC_4648_PADDING") + ETL_ENUM_TYPE(RFC_4648_URL, "RFC_4648_URL") + ETL_ENUM_TYPE(RFC_4648_URL_PADDING, "RFC_4648_URL_PADDING") ETL_END_ENUM_TYPE }; @@ -141,7 +145,7 @@ namespace etl }; ETL_DECLARE_ENUM_TYPE(Padding, bool) - ETL_ENUM_TYPE(No_Padding, "No_Padding") + ETL_ENUM_TYPE(No_Padding, "No_Padding") ETL_ENUM_TYPE(Use_Padding, "Use_Padding") ETL_END_ENUM_TYPE }; diff --git a/include/etl/base64_decoder.h b/include/etl/base64_decoder.h index 39a7999e..0da2ed40 100644 --- a/include/etl/base64_decoder.h +++ b/include/etl/base64_decoder.h @@ -177,6 +177,8 @@ namespace etl } } + padding_received = false; + return success; } @@ -190,6 +192,7 @@ namespace etl reset_output_buffer(); overflow_detected = false; invalid_data_detected = false; + padding_received = false; } //************************************************************************* @@ -300,11 +303,11 @@ namespace etl /// Constructor //************************************************************************* ETL_CONSTEXPR14 - ibase64_decoder(const char* encoder_table_, - bool use_padding_, - unsigned char* p_output_buffer_, - size_t ouput_buffer_max_size_, - callback_type callback_) + ibase64_decoder(const char* encoder_table_, + bool use_padding_, + unsigned char* p_output_buffer_, + size_t ouput_buffer_max_size_, + callback_type callback_) : base64(encoder_table_, use_padding_) , input_buffer() , input_buffer_length(0) @@ -314,6 +317,7 @@ namespace etl , callback(callback_) , overflow_detected(false) , invalid_data_detected(false) + , padding_received(false) { } @@ -469,9 +473,21 @@ namespace etl ETL_CONSTEXPR14 void push_to_input_buffer(T value) { - if (value != padding()) + if (value == padding()) { - input_buffer[input_buffer_length++] = static_cast(value); + padding_received = true; + } + else + { + if (padding_received) + { + ETL_ASSERT_FAIL(ETL_ERROR(etl::base64_invalid_data)); + invalid_data_detected = true; + } + else + { + input_buffer[input_buffer_length++] = static_cast(value); + } } } @@ -504,6 +520,7 @@ namespace etl bool overflow_detected; bool invalid_data_detected; + bool padding_received; }; //************************************************************************* @@ -515,11 +532,10 @@ namespace etl public: static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_2152; - static ETL_CONSTANT etl::base64::Padding Padding = etl::base64::Padding::No_Padding; - - // Round up the buffer size to a multiple of Min_Buffer_Size. static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size"); + //************************************************************************* /// Base64 RFC-2152 constructor. //************************************************************************* @@ -568,9 +584,6 @@ namespace etl template ETL_CONSTANT etl::base64::Encoding base64_rfc2152_decoder::Encoding; - template - ETL_CONSTANT etl::base64::Padding base64_rfc2152_decoder::Padding; - template ETL_CONSTANT size_t base64_rfc2152_decoder::Buffer_Size; @@ -583,11 +596,10 @@ namespace etl public: static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_3501; - static ETL_CONSTANT etl::base64::Padding Padding = etl::base64::Padding::No_Padding; - - // Round up the buffer size to a multiple of Min_Buffer_Size. static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size"); + //************************************************************************* /// Base64 RFC-3501 constructor. //************************************************************************* @@ -636,33 +648,29 @@ namespace etl template ETL_CONSTANT etl::base64::Encoding base64_rfc3501_decoder::Encoding; - template - ETL_CONSTANT etl::base64::Padding base64_rfc3501_decoder::Padding; - template ETL_CONSTANT size_t base64_rfc3501_decoder::Buffer_Size; //************************************************************************* /// Base64 RFC-4648 Decoder //************************************************************************* - template + template class base64_rfc4648_decoder : public ibase64_decoder { public: static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_4648; - static ETL_CONSTANT etl::base64::Padding Padding = Use_Padding ? etl::base64::Padding::Use_Padding : etl::base64::Padding::No_Padding; - - // Round up the buffer size to a multiple of Min_Buffer_Size. static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size"); + //************************************************************************* /// Base64 RFC-4648 constructor. //************************************************************************* ETL_CONSTEXPR14 - base64_rfc4648_decoder() + base64_rfc4648_decoder() : ibase64_decoder(etl::base64::character_set_1(), - Padding, + etl::base64::Padding::No_Padding, output_buffer, Buffer_Size, callback_type()) @@ -674,9 +682,9 @@ namespace etl /// Base64 RFC-4648 constructor. //************************************************************************* ETL_CONSTEXPR14 - base64_rfc4648_decoder(callback_type callback_) + base64_rfc4648_decoder(callback_type callback_) : ibase64_decoder(etl::base64::character_set_1(), - Padding, + etl::base64::Padding::No_Padding, output_buffer, Buffer_Size, callback_) @@ -701,36 +709,32 @@ namespace etl unsigned char output_buffer[Buffer_Size]; }; - template - ETL_CONSTANT etl::base64::Encoding base64_rfc4648_decoder::Encoding; + template + ETL_CONSTANT etl::base64::Encoding base64_rfc4648_decoder::Encoding; - template - ETL_CONSTANT etl::base64::Padding base64_rfc4648_decoder::Padding; - - template - ETL_CONSTANT size_t base64_rfc4648_decoder::Buffer_Size; + template + ETL_CONSTANT size_t base64_rfc4648_decoder::Buffer_Size; //************************************************************************* - /// Base64 RFC-4648 Decoder + /// Base64 RFC-4648-Padding Decoder //************************************************************************* - template - class base64_rfc4648_url_decoder : public ibase64_decoder + template + class base64_rfc4648_padding_decoder : public ibase64_decoder { public: - static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_4648_URL; - static ETL_CONSTANT etl::base64::Padding Padding = Use_Padding ? etl::base64::Padding::Use_Padding : etl::base64::Padding::No_Padding; - - // Round up the buffer size to a multiple of Min_Buffer_Size. + static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_4648_PADDING; static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size"); + //************************************************************************* - /// Base64 RFC-4648 constructor. + /// Base64 RFC-4648-Padding constructor. //************************************************************************* ETL_CONSTEXPR14 - base64_rfc4648_url_decoder() - : ibase64_decoder(etl::base64::character_set_2(), - Padding, + base64_rfc4648_padding_decoder() + : ibase64_decoder(etl::base64::character_set_1(), + etl::base64::Padding::Use_Padding, output_buffer, Buffer_Size, callback_type()) @@ -739,12 +743,76 @@ namespace etl } //************************************************************************* - /// Base64 RFC-4648 constructor. + /// Base64 RFC-4648-Padding constructor. //************************************************************************* ETL_CONSTEXPR14 - base64_rfc4648_url_decoder(callback_type callback_) + base64_rfc4648_padding_decoder(callback_type callback_) + : ibase64_decoder(etl::base64::character_set_1(), + etl::base64::Padding::Use_Padding, + output_buffer, + Buffer_Size, + callback_) + , output_buffer{} + { + } + + //************************************************************************* + /// Calculate the required output encode buffer size. + //************************************************************************* + ETL_NODISCARD + static + ETL_CONSTEXPR14 + size_t safe_output_buffer_size(size_t input_length) + { + return ibase64_decoder::decoded_size_from_valid_input_length(input_length); + } + + private: + + /// The internal output buffer. + unsigned char output_buffer[Buffer_Size]; + }; + + template + ETL_CONSTANT etl::base64::Encoding base64_rfc4648_padding_decoder::Encoding; + + template + ETL_CONSTANT size_t base64_rfc4648_padding_decoder::Buffer_Size; + + //************************************************************************* + /// Base64 RFC-4648-URL Decoder + //************************************************************************* + template + class base64_rfc4648_url_decoder : public ibase64_decoder + { + public: + + static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_4648_URL; + static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; + + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size"); + + //************************************************************************* + /// Base64 RFC-4648-Padding constructor. + //************************************************************************* + ETL_CONSTEXPR14 + base64_rfc4648_url_decoder() : ibase64_decoder(etl::base64::character_set_2(), - Padding, + etl::base64::Padding::No_Padding, + output_buffer, + Buffer_Size, + callback_type()) + , output_buffer{} + { + } + + //************************************************************************* + /// Base64 RFC-4648-Padding constructor. + //************************************************************************* + ETL_CONSTEXPR14 + base64_rfc4648_url_decoder(callback_type callback_) + : ibase64_decoder(etl::base64::character_set_2(), + etl::base64::Padding::No_Padding, output_buffer, Buffer_Size, callback_) @@ -769,14 +837,75 @@ namespace etl unsigned char output_buffer[Buffer_Size]; }; - template - ETL_CONSTANT etl::base64::Encoding base64_rfc4648_url_decoder::Encoding; + template + ETL_CONSTANT etl::base64::Encoding base64_rfc4648_url_decoder::Encoding; - template - ETL_CONSTANT etl::base64::Padding base64_rfc4648_url_decoder::Padding; + template + ETL_CONSTANT size_t base64_rfc4648_url_decoder::Buffer_Size; - template - ETL_CONSTANT size_t base64_rfc4648_url_decoder::Buffer_Size; + //************************************************************************* + /// Base64 RFC-4648-URL-Padding Decoder + //************************************************************************* + template + class base64_rfc4648_url_padding_decoder : public ibase64_decoder + { + public: + + static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_4648_URL_PADDING; + static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; + + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size"); + + //************************************************************************* + /// Base64 RFC-4648-Padding constructor. + //************************************************************************* + ETL_CONSTEXPR14 + base64_rfc4648_url_padding_decoder() + : ibase64_decoder(etl::base64::character_set_2(), + etl::base64::Padding::Use_Padding, + output_buffer, + Buffer_Size, + callback_type()) + , output_buffer{} + { + } + + //************************************************************************* + /// Base64 RFC-4648-Padding constructor. + //************************************************************************* + ETL_CONSTEXPR14 + base64_rfc4648_url_padding_decoder(callback_type callback_) + : ibase64_decoder(etl::base64::character_set_2(), + etl::base64::Padding::Use_Padding, + output_buffer, + Buffer_Size, + callback_) + , output_buffer{} + { + } + + //************************************************************************* + /// Calculate the required output encode buffer size. + //************************************************************************* + ETL_NODISCARD + static + ETL_CONSTEXPR14 + size_t safe_output_buffer_size(size_t input_length) + { + return ibase64_decoder::decoded_size_from_valid_input_length(input_length); + } + + private: + + /// The internal output buffer. + unsigned char output_buffer[Buffer_Size]; + }; + + template + ETL_CONSTANT etl::base64::Encoding base64_rfc4648_url_padding_decoder::Encoding; + + template + ETL_CONSTANT size_t base64_rfc4648_url_padding_decoder::Buffer_Size; } #undef ETL_IS_TYPE_8_BIT_INTEGRAL diff --git a/include/etl/base64_encoder.h b/include/etl/base64_encoder.h index 1eb74f86..f6ed12da 100644 --- a/include/etl/base64_encoder.h +++ b/include/etl/base64_encoder.h @@ -474,12 +474,10 @@ namespace etl public: static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_2152; - static ETL_CONSTANT etl::base64::Padding Padding = etl::base64::Padding::No_Padding; + static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; - // Round up the buffer size to a multiple of Min_Buffer_Size. - static ETL_CONSTANT size_t Buffer_Size = (Buffer_Size_ == 0) - ? etl::base64::Min_Encode_Buffer_Size - : Buffer_Size_ + ((etl::base64::Min_Encode_Buffer_Size - (Buffer_Size_ % etl::base64::Min_Encode_Buffer_Size)) % etl::base64::Min_Encode_Buffer_Size); + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Encode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Encode_Buffer_Size"); + ETL_STATIC_ASSERT(((Buffer_Size % etl::base64::Min_Encode_Buffer_Size) == 0), "Buffer size must be a multiple of etl::base64::Min_Encode_Buffer_Size"); //************************************************************************* /// Base64 RFC-2152 constructor. @@ -529,9 +527,6 @@ namespace etl template ETL_CONSTANT etl::base64::Encoding base64_rfc2152_encoder::Encoding; - template - ETL_CONSTANT etl::base64::Padding base64_rfc2152_encoder::Padding; - template ETL_CONSTANT size_t base64_rfc2152_encoder::Buffer_Size; @@ -544,12 +539,10 @@ namespace etl public: static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_3501; - static ETL_CONSTANT etl::base64::Padding Padding = etl::base64::Padding::No_Padding; + static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; - // Round up the buffer size to a multiple of Min_Buffer_Size. - static ETL_CONSTANT size_t Buffer_Size = (Buffer_Size_ == 0) - ? etl::base64::Min_Encode_Buffer_Size - : Buffer_Size_ + ((etl::base64::Min_Encode_Buffer_Size - (Buffer_Size_ % etl::base64::Min_Encode_Buffer_Size)) % etl::base64::Min_Encode_Buffer_Size); + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Encode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Encode_Buffer_Size"); + ETL_STATIC_ASSERT(((Buffer_Size% etl::base64::Min_Encode_Buffer_Size) == 0), "Buffer size must be a multiple of etl::base64::Min_Encode_Buffer_Size"); //************************************************************************* /// Base64 RFC-3501 constructor. @@ -599,27 +592,22 @@ namespace etl template ETL_CONSTANT etl::base64::Encoding base64_rfc3501_encoder::Encoding; - template - ETL_CONSTANT etl::base64::Padding base64_rfc3501_encoder::Padding; - template ETL_CONSTANT size_t base64_rfc3501_encoder::Buffer_Size; //************************************************************************* /// Base64 RFC-4648 Encoder //************************************************************************* - template + template class base64_rfc4648_encoder : public ibase64_encoder { public: static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_4648; - static ETL_CONSTANT etl::base64::Padding Padding = Use_Padding ? etl::base64::Padding::Use_Padding : etl::base64::Padding::No_Padding; + static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; - // Round up the buffer size to a multiple of Min_Buffer_Size. - static ETL_CONSTANT size_t Buffer_Size = (Buffer_Size_ == 0) - ? etl::base64::Min_Encode_Buffer_Size - : Buffer_Size_ + ((etl::base64::Min_Encode_Buffer_Size - (Buffer_Size_ % etl::base64::Min_Encode_Buffer_Size)) % etl::base64::Min_Encode_Buffer_Size); + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Encode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Encode_Buffer_Size"); + ETL_STATIC_ASSERT(((Buffer_Size% etl::base64::Min_Encode_Buffer_Size) == 0), "Buffer size must be a multiple of etl::base64::Min_Encode_Buffer_Size"); //************************************************************************* /// Base64 RFC-4648 constructor. @@ -627,7 +615,7 @@ namespace etl ETL_CONSTEXPR14 base64_rfc4648_encoder() : ibase64_encoder(etl::base64::character_set_1(), - Use_Padding, + etl::base64::Padding::No_Padding, output_buffer, Buffer_Size, callback_type()) @@ -641,7 +629,7 @@ namespace etl ETL_CONSTEXPR14 base64_rfc4648_encoder(callback_type callback_) : ibase64_encoder(etl::base64::character_set_1(), - Use_Padding, + etl::base64::Padding::No_Padding, output_buffer, Buffer_Size, callback_) @@ -657,7 +645,7 @@ namespace etl ETL_CONSTEXPR14 size_t safe_output_buffer_size(size_t input_length) { - return ibase64_encoder::encoded_size(input_length, Use_Padding == etl::base64::Padding::Use_Padding); + return ibase64_encoder::encoded_size(input_length, etl::base64::Padding::No_Padding); } private: @@ -666,30 +654,90 @@ namespace etl char output_buffer[Buffer_Size]; }; - template - ETL_CONSTANT etl::base64::Encoding base64_rfc4648_encoder::Encoding; + template + ETL_CONSTANT etl::base64::Encoding base64_rfc4648_encoder::Encoding; - template - ETL_CONSTANT etl::base64::Padding base64_rfc4648_encoder::Padding; + template + ETL_CONSTANT size_t base64_rfc4648_encoder::Buffer_Size; - template - ETL_CONSTANT size_t base64_rfc4648_encoder::Buffer_Size; + //************************************************************************* +/// Base64 RFC-4648-Padding Encoder +//************************************************************************* + template + class base64_rfc4648_padding_encoder : public ibase64_encoder + { + public: + + static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_4648_PADDING; + static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; + + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Encode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Encode_Buffer_Size"); + ETL_STATIC_ASSERT(((Buffer_Size% etl::base64::Min_Encode_Buffer_Size) == 0), "Buffer size must be a multiple of etl::base64::Min_Encode_Buffer_Size"); + + //************************************************************************* + /// Base64 RFC-4648-Padding constructor. + //************************************************************************* + ETL_CONSTEXPR14 + base64_rfc4648_padding_encoder() + : ibase64_encoder(etl::base64::character_set_1(), + etl::base64::Padding::Use_Padding, + output_buffer, + Buffer_Size, + callback_type()) + , output_buffer{} + { + } + + //************************************************************************* + /// Base64 RFC-4648-Padding constructor. + //************************************************************************* + ETL_CONSTEXPR14 + base64_rfc4648_padding_encoder(callback_type callback_) + : ibase64_encoder(etl::base64::character_set_1(), + etl::base64::Padding::Use_Padding, + output_buffer, + Buffer_Size, + callback_) + , output_buffer{} + { + } + + //************************************************************************* + /// Calculate the required output encode buffer size. + //************************************************************************* + ETL_NODISCARD + static + ETL_CONSTEXPR14 + size_t safe_output_buffer_size(size_t input_length) + { + return ibase64_encoder::encoded_size(input_length, etl::base64::Padding::Use_Padding); + } + + private: + + /// The internal output buffer. + char output_buffer[Buffer_Size]; + }; + + template + ETL_CONSTANT etl::base64::Encoding base64_rfc4648_padding_encoder::Encoding; + + template + ETL_CONSTANT size_t base64_rfc4648_padding_encoder::Buffer_Size; //************************************************************************* /// Base64 RFC-4648-URL Encoder //************************************************************************* - template + template class base64_rfc4648_url_encoder : public ibase64_encoder { public: static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_4648_URL; - static ETL_CONSTANT etl::base64::Padding Padding = Use_Padding ? etl::base64::Padding::Use_Padding : etl::base64::Padding::No_Padding; + static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; - // Round up the buffer size to a multiple of Min_Buffer_Size. - static ETL_CONSTANT size_t Buffer_Size = (Buffer_Size_ == 0) - ? etl::base64::Min_Encode_Buffer_Size - : Buffer_Size_ + ((etl::base64::Min_Encode_Buffer_Size - (Buffer_Size_ % etl::base64::Min_Encode_Buffer_Size)) % etl::base64::Min_Encode_Buffer_Size); + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Encode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Encode_Buffer_Size"); + ETL_STATIC_ASSERT(((Buffer_Size % etl::base64::Min_Encode_Buffer_Size) == 0), "Buffer size must be a multiple of etl::base64::Min_Encode_Buffer_Size"); //************************************************************************* /// Base64 RFC-4648-URL constructor. @@ -697,7 +745,7 @@ namespace etl ETL_CONSTEXPR14 base64_rfc4648_url_encoder() : ibase64_encoder(etl::base64::character_set_2(), - Use_Padding, + etl::base64::Padding::No_Padding, output_buffer, Buffer_Size, callback_type()) @@ -711,7 +759,7 @@ namespace etl ETL_CONSTEXPR14 base64_rfc4648_url_encoder(callback_type callback_) : ibase64_encoder(etl::base64::character_set_2(), - Use_Padding, + etl::base64::Padding::No_Padding, output_buffer, Buffer_Size, callback_) @@ -727,7 +775,7 @@ namespace etl ETL_CONSTEXPR14 size_t safe_output_buffer_size(size_t input_length) { - return ibase64_encoder::encoded_size(input_length, Use_Padding == etl::base64::Padding::Use_Padding); + return ibase64_encoder::encoded_size(input_length, etl::base64::Padding::No_Padding); } private: @@ -736,14 +784,76 @@ namespace etl char output_buffer[Buffer_Size]; }; - template - ETL_CONSTANT etl::base64::Encoding base64_rfc4648_url_encoder::Encoding; + template + ETL_CONSTANT etl::base64::Encoding base64_rfc4648_url_encoder::Encoding; - template - ETL_CONSTANT etl::base64::Padding base64_rfc4648_url_encoder::Padding; + template + ETL_CONSTANT size_t base64_rfc4648_url_encoder::Buffer_Size; - template - ETL_CONSTANT size_t base64_rfc4648_url_encoder::Buffer_Size; + //************************************************************************* + /// Base64 RFC-4648-URL_Padding Encoder + //************************************************************************* + template + class base64_rfc4648_url_padding_encoder : public ibase64_encoder + { + public: + + static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_4648_URL; + static ETL_CONSTANT size_t Buffer_Size = Buffer_Size_; + + ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Encode_Buffer_Size), "Buffer size must be greater than etl::base64::Min_Encode_Buffer_Size"); + ETL_STATIC_ASSERT(((Buffer_Size% etl::base64::Min_Encode_Buffer_Size) == 0), "Buffer size must be a multiple of etl::base64::Min_Encode_Buffer_Size"); + + //************************************************************************* + /// Base64 RFC-4648-URL constructor. + //************************************************************************* + ETL_CONSTEXPR14 + base64_rfc4648_url_padding_encoder() + : ibase64_encoder(etl::base64::character_set_2(), + etl::base64::Padding::Use_Padding, + output_buffer, + Buffer_Size, + callback_type()) + , output_buffer{} + { + } + + //************************************************************************* + /// Base64 RFC-4648-URL constructor. + //************************************************************************* + ETL_CONSTEXPR14 + base64_rfc4648_url_padding_encoder(callback_type callback_) + : ibase64_encoder(etl::base64::character_set_2(), + etl::base64::Padding::Use_Padding, + output_buffer, + Buffer_Size, + callback_) + , output_buffer{} + { + } + + //************************************************************************* + /// Calculate the required output encode buffer size. + //************************************************************************* + ETL_NODISCARD + static + ETL_CONSTEXPR14 + size_t safe_output_buffer_size(size_t input_length) + { + return ibase64_encoder::encoded_size(input_length, etl::base64::Padding::Use_Padding); + } + + private: + + /// The internal output buffer. + char output_buffer[Buffer_Size]; + }; + + template + ETL_CONSTANT etl::base64::Encoding base64_rfc4648_url_padding_encoder::Encoding; + + template + ETL_CONSTANT size_t base64_rfc4648_url_padding_encoder::Buffer_Size; } #undef ETL_IS_TYPE_8_BIT_INTEGRAL diff --git a/test/test_base64_RFC2152_decoder.cpp b/test/test_base64_RFC2152_decoder.cpp index 28625807..5370dbcf 100644 --- a/test/test_base64_RFC2152_decoder.cpp +++ b/test/test_base64_RFC2152_decoder.cpp @@ -52,7 +52,7 @@ namespace { using codec = etl::base64_rfc2152_decoder; using codec_larger_buffer = etl::base64_rfc2152_decoder; - using codec_full_buffer = etl::base64_rfc2152_decoder<256>; + using codec_full_buffer = etl::base64_rfc2152_decoder< etl::base64_rfc2152_decoder<>::safe_output_buffer_size(342)>; std::array input_data = { @@ -344,9 +344,19 @@ namespace CHECK_EQUAL(etl::base64::Encoding::RFC_2152, codec_full_buffer::Encoding); CHECK_EQUAL("RFC_2152", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::No_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(256, codec_full_buffer::Buffer_Size); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = i; + size_t safe_size = codec::safe_output_buffer_size(encoded[i].size()); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -869,7 +879,7 @@ namespace //************************************************************************* TEST(test_decode_invalid_character) { - codec b64; + codec_larger_buffer b64; std::array decoded_output{ 0 }; std::string invalid_chararacter("OycDQ#37KA"); diff --git a/test/test_base64_RFC2152_encoder.cpp b/test/test_base64_RFC2152_encoder.cpp index e6974537..573c53e4 100644 --- a/test/test_base64_RFC2152_encoder.cpp +++ b/test/test_base64_RFC2152_encoder.cpp @@ -53,7 +53,7 @@ namespace { using codec = etl::base64_rfc2152_encoder; using codec_larger_buffer = etl::base64_rfc2152_encoder; - using codec_full_buffer = etl::base64_rfc2152_encoder<344>; + using codec_full_buffer = etl::base64_rfc2152_encoder::safe_output_buffer_size(256)>; std::array input_data = { @@ -345,9 +345,19 @@ namespace CHECK_EQUAL(etl::base64::Encoding::RFC_2152, codec_full_buffer::Encoding); CHECK_EQUAL("RFC_2152", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::No_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = encoded[i].size(); + size_t safe_size = codec::safe_output_buffer_size(i); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -818,7 +828,7 @@ namespace { etl::array output{ 0 }; - using codec = etl::base64_rfc4648_encoder; + using codec = etl::base64_rfc4648_encoder; codec b64; b64.encode_final(input.begin(), input.end()); @@ -844,7 +854,7 @@ namespace //************************************************************************* TEST(test_encode_overflow) { - using codec = etl::base64_rfc4648_encoder; + using codec = etl::base64_rfc2152_encoder<>; codec b64; diff --git a/test/test_base64_RFC3501_decoder.cpp b/test/test_base64_RFC3501_decoder.cpp index 39177829..9fe3fb30 100644 --- a/test/test_base64_RFC3501_decoder.cpp +++ b/test/test_base64_RFC3501_decoder.cpp @@ -52,7 +52,7 @@ namespace { using codec = etl::base64_rfc3501_decoder; using codec_larger_buffer = etl::base64_rfc3501_decoder; - using codec_full_buffer = etl::base64_rfc3501_decoder<256>; + using codec_full_buffer = etl::base64_rfc3501_decoder< etl::base64_rfc3501_decoder<>::safe_output_buffer_size(342)>; std::array input_data = { @@ -344,9 +344,19 @@ namespace CHECK_EQUAL(etl::base64::Encoding::RFC_3501, codec_full_buffer::Encoding); CHECK_EQUAL("RFC_3501", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::No_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(256, codec_full_buffer::Buffer_Size); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = i; + size_t safe_size = codec::safe_output_buffer_size(encoded[i].size()); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -876,7 +886,7 @@ namespace //************************************************************************* TEST(test_decode_invalid_character) { - codec b64; + codec_larger_buffer b64; std::array decoded_output{ 0 }; std::string invalid_chararacter("OycDQ#37KA"); diff --git a/test/test_base64_RFC3501_encoder.cpp b/test/test_base64_RFC3501_encoder.cpp index ea00f11a..a9a258b1 100644 --- a/test/test_base64_RFC3501_encoder.cpp +++ b/test/test_base64_RFC3501_encoder.cpp @@ -53,7 +53,7 @@ namespace { using codec = etl::base64_rfc3501_encoder; using codec_larger_buffer = etl::base64_rfc3501_encoder; - using codec_full_buffer = etl::base64_rfc3501_encoder<344>; + using codec_full_buffer = etl::base64_rfc3501_encoder::safe_output_buffer_size(256)>; std::array input_data = { @@ -343,11 +343,21 @@ namespace { codec_full_buffer b64; - CHECK_EQUAL(etl::base64::Encoding::RFC_3501, codec_full_buffer::Encoding); - CHECK_EQUAL("RFC_3501", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::No_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + CHECK_EQUAL(etl::base64::Encoding::RFC_3501, codec_full_buffer::Encoding); + CHECK_EQUAL("RFC_3501", codec_full_buffer::Encoding.c_str()); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = encoded[i].size(); + size_t safe_size = codec::safe_output_buffer_size(i); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -844,7 +854,7 @@ namespace //************************************************************************* TEST(test_encode_overflow) { - using codec = etl::base64_rfc3501_encoder; + using codec = etl::base64_rfc3501_encoder<>; codec b64; diff --git a/test/test_base64_RFC4648_URL_decoder_with_no_padding.cpp b/test/test_base64_RFC4648_URL_decoder_with_no_padding.cpp index c6757b06..7c4cabd0 100644 --- a/test/test_base64_RFC4648_URL_decoder_with_no_padding.cpp +++ b/test/test_base64_RFC4648_URL_decoder_with_no_padding.cpp @@ -39,7 +39,7 @@ SOFTWARE. #include #if ETL_USING_STL -#include + #include #endif #include "etl/integral_limits.h" @@ -50,9 +50,9 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_url_decoder ; - using codec_larger_buffer = etl::base64_rfc4648_url_decoder; - using codec_full_buffer = etl::base64_rfc4648_url_decoder; + using codec = etl::base64_rfc4648_url_decoder ; + using codec_larger_buffer = etl::base64_rfc4648_url_decoder; + using codec_full_buffer = etl::base64_rfc4648_url_decoder::safe_output_buffer_size(342)>; std::array input_data = { @@ -344,9 +344,19 @@ namespace CHECK_EQUAL(etl::base64::Encoding::RFC_4648_URL, codec_full_buffer::Encoding); CHECK_EQUAL("RFC_4648_URL", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::No_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(256, codec_full_buffer::Buffer_Size); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = i; + size_t safe_size = codec::safe_output_buffer_size(encoded[i].size()); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -829,7 +839,7 @@ namespace { etl::array output{ 0 }; - using codec = etl::base64_rfc4648_url_decoder; + using codec = etl::base64_rfc4648_url_decoder; codec b64; b64.decode_final(input.begin(), input.end()); @@ -869,11 +879,27 @@ namespace //************************************************************************* TEST(test_decode_invalid_character) { - codec b64; + codec_larger_buffer b64; std::array decoded_output{ 0 }; std::string invalid_chararacter("OycDQ#37KA"); +#if ETL_USING_EXCEPTIONS + CHECK_THROW((b64.decode(invalid_chararacter.data(), invalid_chararacter.size())), etl::base64_invalid_data); +#else + CHECK_FALSE(b64.decode(invalid_chararacter.data(), invalid_chararacter.size())); + CHECK_TRUE(b64.error()); +#endif + } + + //************************************************************************* + TEST(test_decode_invalid_padding) + { + codec_larger_buffer b64; + std::array decoded_output{ 0 }; + + std::string invalid_chararacter("OycD=y37KA"); + #if ETL_USING_EXCEPTIONS CHECK_THROW((b64.decode(invalid_chararacter.data(), invalid_chararacter.size())), etl::base64_invalid_data); #else diff --git a/test/test_base64_RFC4648_URL_decoder_with_padding.cpp b/test/test_base64_RFC4648_URL_decoder_with_padding.cpp index 3001132e..1acc4db4 100644 --- a/test/test_base64_RFC4648_URL_decoder_with_padding.cpp +++ b/test/test_base64_RFC4648_URL_decoder_with_padding.cpp @@ -39,7 +39,7 @@ SOFTWARE. #include #if ETL_USING_STL -#include + #include #endif #include "etl/integral_limits.h" @@ -50,9 +50,9 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_url_decoder ; - using codec_larger_buffer = etl::base64_rfc4648_url_decoder; - using codec_full_buffer = etl::base64_rfc4648_url_decoder; + using codec = etl::base64_rfc4648_url_padding_decoder ; + using codec_larger_buffer = etl::base64_rfc4648_url_padding_decoder; + using codec_full_buffer = etl::base64_rfc4648_url_padding_decoder::safe_output_buffer_size(344)>; std::array input_data = { @@ -342,11 +342,21 @@ namespace { codec_full_buffer b64; - CHECK_EQUAL(etl::base64::Encoding::RFC_4648_URL, codec_full_buffer::Encoding); - CHECK_EQUAL("RFC_4648_URL", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::Use_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("Use_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(256, codec_full_buffer::Buffer_Size); + CHECK_EQUAL(etl::base64::Encoding::RFC_4648_URL_PADDING, codec_full_buffer::Encoding); + CHECK_EQUAL("RFC_4648_URL_PADDING", codec_full_buffer::Encoding.c_str()); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = i; + size_t safe_size = codec::safe_output_buffer_size(encoded[i].size()); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -829,7 +839,7 @@ namespace { etl::array output{ 0 }; - using codec = etl::base64_rfc4648_url_decoder; + using codec = etl::base64_rfc4648_url_padding_decoder; codec b64; b64.decode_final(input.begin(), input.end()); @@ -869,11 +879,27 @@ namespace //************************************************************************* TEST(test_decode_invalid_character) { - codec b64; + codec_larger_buffer b64; std::array decoded_output{ 0 }; std::string invalid_chararacter("OycDQ#37KA"); +#if ETL_USING_EXCEPTIONS + CHECK_THROW((b64.decode(invalid_chararacter.data(), invalid_chararacter.size())), etl::base64_invalid_data); +#else + CHECK_FALSE(b64.decode(invalid_chararacter.data(), invalid_chararacter.size())); + CHECK_TRUE(b64.error()); +#endif + } + + //************************************************************************* + TEST(test_decode_invalid_padding) + { + codec_larger_buffer b64; + std::array decoded_output{ 0 }; + + std::string invalid_chararacter("OycD=y37KA=="); + #if ETL_USING_EXCEPTIONS CHECK_THROW((b64.decode(invalid_chararacter.data(), invalid_chararacter.size())), etl::base64_invalid_data); #else diff --git a/test/test_base64_RFC4648_URL_encoder_with_no_padding.cpp b/test/test_base64_RFC4648_URL_encoder_with_no_padding.cpp index eee3a1cf..847eea95 100644 --- a/test/test_base64_RFC4648_URL_encoder_with_no_padding.cpp +++ b/test/test_base64_RFC4648_URL_encoder_with_no_padding.cpp @@ -51,9 +51,9 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_url_encoder; - using codec_larger_buffer = etl::base64_rfc4648_url_encoder; - using codec_full_buffer = etl::base64_rfc4648_url_encoder; + using codec = etl::base64_rfc4648_url_encoder; + using codec_larger_buffer = etl::base64_rfc4648_url_encoder; + using codec_full_buffer = etl::base64_rfc4648_url_encoder::safe_output_buffer_size(256)>; std::array input_data = { @@ -345,9 +345,19 @@ namespace CHECK_EQUAL(etl::base64::Encoding::RFC_4648_URL, codec_full_buffer::Encoding); CHECK_EQUAL("RFC_4648_URL", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::No_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = encoded[i].size(); + size_t safe_size = codec::safe_output_buffer_size(i); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -818,7 +828,7 @@ namespace { etl::array output{ 0 }; - using codec = etl::base64_rfc4648_encoder; + using codec = etl::base64_rfc4648_encoder; codec b64; b64.encode_final(input.begin(), input.end()); @@ -844,8 +854,6 @@ namespace //************************************************************************* TEST(test_encode_overflow) { - using codec = etl::base64_rfc4648_encoder; - codec b64; CHECK_THROW((b64.encode(input_data.data(), 10)), etl::base64_overflow); diff --git a/test/test_base64_RFC4648_URL_encoder_with_padding.cpp b/test/test_base64_RFC4648_URL_encoder_with_padding.cpp index d0de3bbb..3edd3eff 100644 --- a/test/test_base64_RFC4648_URL_encoder_with_padding.cpp +++ b/test/test_base64_RFC4648_URL_encoder_with_padding.cpp @@ -51,9 +51,9 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_url_encoder; - using codec_larger_buffer = etl::base64_rfc4648_url_encoder; - using codec_full_buffer = etl::base64_rfc4648_url_encoder; + using codec = etl::base64_rfc4648_url_padding_encoder; + using codec_larger_buffer = etl::base64_rfc4648_url_padding_encoder; + using codec_full_buffer = etl::base64_rfc4648_url_padding_encoder::safe_output_buffer_size(256)>; std::array input_data = { @@ -345,9 +345,19 @@ namespace CHECK_EQUAL(etl::base64::Encoding::RFC_4648_URL, codec_full_buffer::Encoding); CHECK_EQUAL("RFC_4648_URL", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::Use_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("Use_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = encoded[i].size(); + size_t safe_size = codec::safe_output_buffer_size(i); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -818,7 +828,7 @@ namespace { etl::array output{ 0 }; - using codec = etl::base64_rfc4648_encoder; + using codec = etl::base64_rfc4648_encoder; codec b64; b64.encode_final(input.begin(), input.end()); @@ -844,8 +854,6 @@ namespace //************************************************************************* TEST(test_encode_overflow) { - using codec = etl::base64_rfc4648_encoder; - codec b64; CHECK_THROW((b64.encode(input_data.data(), 10)), etl::base64_overflow); diff --git a/test/test_base64_RFC4648_decoder_with_no_padding.cpp b/test/test_base64_RFC4648_decoder_with_no_padding.cpp index 992bb553..58b52d4b 100644 --- a/test/test_base64_RFC4648_decoder_with_no_padding.cpp +++ b/test/test_base64_RFC4648_decoder_with_no_padding.cpp @@ -50,9 +50,9 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_decoder ; - using codec_larger_buffer = etl::base64_rfc4648_decoder; - using codec_full_buffer = etl::base64_rfc4648_decoder; + using codec = etl::base64_rfc4648_decoder ; + using codec_larger_buffer = etl::base64_rfc4648_decoder; + using codec_full_buffer = etl::base64_rfc4648_decoder< etl::base64_rfc4648_decoder<>::safe_output_buffer_size(342)>; std::array input_data = { @@ -344,9 +344,19 @@ namespace CHECK_EQUAL(etl::base64::Encoding::RFC_4648, codec_full_buffer::Encoding); CHECK_EQUAL("RFC_4648", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::No_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(256, codec_full_buffer::Buffer_Size); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = i; + size_t safe_size = codec::safe_output_buffer_size(encoded[i].size()); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -829,7 +839,7 @@ namespace { etl::array output{ 0 }; - using codec = etl::base64_rfc4648_decoder; + using codec = etl::base64_rfc4648_decoder; codec b64; b64.decode_final(input.begin(), input.end()); @@ -869,11 +879,27 @@ namespace //************************************************************************* TEST(test_decode_invalid_character) { - codec b64; + codec_larger_buffer b64; std::array decoded_output{ 0 }; std::string invalid_chararacter("OycDQ#37KA"); +#if ETL_USING_EXCEPTIONS + CHECK_THROW((b64.decode(invalid_chararacter.data(), invalid_chararacter.size())), etl::base64_invalid_data); +#else + CHECK_FALSE(b64.decode(invalid_chararacter.data(), invalid_chararacter.size())); + CHECK_TRUE(b64.error()); +#endif + } + + //************************************************************************* + TEST(test_decode_invalid_padding) + { + codec_larger_buffer b64; + std::array decoded_output{ 0 }; + + std::string invalid_chararacter("OycD=y37KA"); + #if ETL_USING_EXCEPTIONS CHECK_THROW((b64.decode(invalid_chararacter.data(), invalid_chararacter.size())), etl::base64_invalid_data); #else diff --git a/test/test_base64_RFC4648_decoder_with_padding.cpp b/test/test_base64_RFC4648_decoder_with_padding.cpp index bfc440b0..555fcb69 100644 --- a/test/test_base64_RFC4648_decoder_with_padding.cpp +++ b/test/test_base64_RFC4648_decoder_with_padding.cpp @@ -50,9 +50,9 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_decoder ; - using codec_larger_buffer = etl::base64_rfc4648_decoder; - using codec_full_buffer = etl::base64_rfc4648_decoder; + using codec = etl::base64_rfc4648_padding_decoder ; + using codec_larger_buffer = etl::base64_rfc4648_padding_decoder; + using codec_full_buffer = etl::base64_rfc4648_padding_decoder::safe_output_buffer_size(344)>; std::array input_data = { @@ -342,11 +342,21 @@ namespace { codec_full_buffer b64; - CHECK_EQUAL(etl::base64::Encoding::RFC_4648, codec_full_buffer::Encoding); - CHECK_EQUAL("RFC_4648", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::Use_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("Use_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(256, codec_full_buffer::Buffer_Size); + CHECK_EQUAL(etl::base64::Encoding::RFC_4648_PADDING, codec_full_buffer::Encoding); + CHECK_EQUAL("RFC_4648_PADDING", codec_full_buffer::Encoding.c_str()); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = i; + size_t safe_size = codec::safe_output_buffer_size(encoded[i].size()); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -829,7 +839,7 @@ namespace { etl::array output{ 0 }; - using codec = etl::base64_rfc4648_decoder; + using codec = etl::base64_rfc4648_padding_decoder; codec b64; b64.decode_final(input.begin(), input.end()); @@ -856,7 +866,6 @@ namespace TEST(test_decode_overflow) { codec b64; - std::array decoded_output{ 0 }; #if ETL_USING_EXCEPTIONS CHECK_THROW((b64.decode(encoded[10].data(), encoded[10].size())), etl::base64_overflow); @@ -869,11 +878,26 @@ namespace //************************************************************************* TEST(test_decode_invalid_character) { - codec b64; - std::array decoded_output{ 0 }; + codec_larger_buffer b64; std::string invalid_chararacter("OycDQ#37KA"); +#if ETL_USING_EXCEPTIONS + CHECK_THROW((b64.decode(invalid_chararacter.data(), invalid_chararacter.size())), etl::base64_invalid_data); +#else + CHECK_FALSE(b64.decode(invalid_chararacter.data(), invalid_chararacter.size())); + CHECK_TRUE(b64.error()); +#endif + } + + //************************************************************************* + TEST(test_decode_invalid_padding) + { + codec_larger_buffer b64; + std::array decoded_output{ 0 }; + + std::string invalid_chararacter("OycD=y37KA=="); + #if ETL_USING_EXCEPTIONS CHECK_THROW((b64.decode(invalid_chararacter.data(), invalid_chararacter.size())), etl::base64_invalid_data); #else diff --git a/test/test_base64_RFC4648_encoder_with_no_padding.cpp b/test/test_base64_RFC4648_encoder_with_no_padding.cpp index ed94f587..14931601 100644 --- a/test/test_base64_RFC4648_encoder_with_no_padding.cpp +++ b/test/test_base64_RFC4648_encoder_with_no_padding.cpp @@ -51,9 +51,9 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_encoder; - using codec_larger_buffer = etl::base64_rfc4648_encoder; - using codec_full_buffer = etl::base64_rfc4648_encoder; + using codec = etl::base64_rfc4648_encoder; + using codec_larger_buffer = etl::base64_rfc4648_encoder; + using codec_full_buffer = etl::base64_rfc4648_encoder::safe_output_buffer_size(256)>; std::array input_data = { @@ -345,9 +345,19 @@ namespace CHECK_EQUAL(etl::base64::Encoding::RFC_4648, codec_full_buffer::Encoding); CHECK_EQUAL("RFC_4648", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::No_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = encoded[i].size(); + size_t safe_size = codec::safe_output_buffer_size(i); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -818,7 +828,7 @@ namespace { etl::array output{ 0 }; - using codec = etl::base64_rfc4648_encoder; + using codec = etl::base64_rfc4648_encoder; codec b64; b64.encode_final(input.begin(), input.end()); @@ -844,8 +854,6 @@ namespace //************************************************************************* TEST(test_encode_overflow) { - using codec = etl::base64_rfc4648_encoder; - codec b64; CHECK_THROW((b64.encode(input_data.data(), 10)), etl::base64_overflow); diff --git a/test/test_base64_RFC4648_encoder_with_padding.cpp b/test/test_base64_RFC4648_encoder_with_padding.cpp index b0558036..2849300d 100644 --- a/test/test_base64_RFC4648_encoder_with_padding.cpp +++ b/test/test_base64_RFC4648_encoder_with_padding.cpp @@ -51,9 +51,9 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_encoder; - using codec_larger_buffer = etl::base64_rfc4648_encoder; - using codec_full_buffer = etl::base64_rfc4648_encoder; + using codec = etl::base64_rfc4648_padding_encoder; + using codec_larger_buffer = etl::base64_rfc4648_padding_encoder; + using codec_full_buffer = etl::base64_rfc4648_padding_encoder::safe_output_buffer_size(256)>; std::array input_data = { @@ -343,11 +343,21 @@ namespace { codec_full_buffer b64; - CHECK_EQUAL(etl::base64::Encoding::RFC_4648, codec_full_buffer::Encoding); - CHECK_EQUAL("RFC_4648", codec_full_buffer::Encoding.c_str()); - CHECK_TRUE(etl::base64::Padding::Use_Padding == codec_full_buffer::Padding); - CHECK_EQUAL("Use_Padding", codec_full_buffer::Padding.c_str()); - CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + CHECK_EQUAL(etl::base64::Encoding::RFC_4648_PADDING, codec_full_buffer::Encoding); + CHECK_EQUAL("RFC_4648_PADDING", codec_full_buffer::Encoding.c_str()); + } + + //************************************************************************* + TEST(test_check_encode_safe_buffer_sizes) + { + for (size_t i = 0; i < 256; ++i) + { + size_t minimum_size = encoded[i].size(); + size_t safe_size = codec::safe_output_buffer_size(i); + + CHECK_TRUE(safe_size >= minimum_size); + CHECK_TRUE((safe_size - minimum_size) <= 2U); + } } //************************************************************************* @@ -813,39 +823,37 @@ namespace //************************************************************************* #if ETL_USING_CPP14 - template - constexpr auto GetConstexprBase64(const etl::array input) noexcept - { - etl::array output{ 0 }; - - using codec = etl::base64_rfc4648_encoder; - - codec b64; - b64.encode_final(input.begin(), input.end()); - etl::copy(b64.begin(), b64.end(), output.begin()); + //template + //constexpr auto GetConstexprBase64(const etl::array input) noexcept + //{ + // etl::array output{ 0 }; + // + // using codec = etl::base64_rfc4648_encoder; + // + // codec b64; + // b64.encode_final(input.begin(), input.end()); + // etl::copy(b64.begin(), b64.end(), output.begin()); - return output; - } + // return output; + //} - TEST(test_encode_constexpr) - { - constexpr etl::array input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + //TEST(test_encode_constexpr) + //{ + // constexpr etl::array input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - constexpr auto output{ GetConstexprBase64(input) }; + // constexpr auto output{ GetConstexprBase64(input) }; - std::string expected("AAECAwQFBgcICQ"); - std::string actual(output.data(), output.size()); + // std::string expected("AAECAwQFBgcICQ"); + // std::string actual(output.data(), output.size()); - CHECK_EQUAL(expected, actual); - CHECK_TRUE(codec::safe_output_buffer_size(10) >= output.size()); - } + // CHECK_EQUAL(expected, actual); + // CHECK_TRUE(codec::safe_output_buffer_size(10) >= output.size()); + //} #endif //************************************************************************* TEST(test_encode_overflow) { - using codec = etl::base64_rfc4648_encoder; - codec b64; CHECK_THROW((b64.encode(input_data.data(), 10)), etl::base64_overflow);