diff --git a/include/tscore/ink_base64.h b/include/tscore/ink_base64.h index a3c4d510afc..1473a312a51 100644 --- a/include/tscore/ink_base64.h +++ b/include/tscore/ink_base64.h @@ -42,5 +42,16 @@ bool ats_base64_encode(const unsigned char *inBuffer, size_t inBufferSize, char bool ats_base64_decode(const char *inBuffer, size_t inBufferSize, unsigned char *outBuffer, size_t outBufSize, size_t *length); // Little helper functions to calculate minimum required output buffer for encoding/decoding. -#define ATS_BASE64_ENCODE_DSTLEN(_length) ((_length * 8) / 6 + 4) -#define ATS_BASE64_DECODE_DSTLEN(_length) (((_length + 3) / 4) * 3) +// These sizes include one byte for null termination, because ats_base64_encode and ats_base64_decode will always write a null +// terminator. +inline constexpr size_t +ats_base64_encode_dstlen(size_t length) +{ + return ((length + 2) / 3) * 4 + 1; +} + +inline constexpr size_t +ats_base64_decode_dstlen(size_t length) +{ + return ((length + 3) / 4) * 3 + 1; +} diff --git a/plugins/experimental/access_control/unit_tests/test_utils.cc b/plugins/experimental/access_control/unit_tests/test_utils.cc index 43b1f5c49a3..5040964aa1f 100644 --- a/plugins/experimental/access_control/unit_tests/test_utils.cc +++ b/plugins/experimental/access_control/unit_tests/test_utils.cc @@ -36,7 +36,7 @@ TEST_CASE("Base64: estimate buffer size needed to encode a message", "[Base64][a /* Test with a zero decoded message length */ encodedLen = cryptoBase64EncodedSize(0); - CHECK(4 == encodedLen); + CHECK(1 == encodedLen); /* Test with a random non-zero decoded message length */ encodedLen = cryptoBase64EncodedSize(64); @@ -44,11 +44,11 @@ TEST_CASE("Base64: estimate buffer size needed to encode a message", "[Base64][a /* Test the space for padding. Size of encoding that would result in 2 x "=" padding */ encodedLen = cryptoBase64EncodedSize(strlen("176a1620e31b14782ba2b66de3edc5b3cb19630475b2ce2ee292d5fd0fe41c3abc")); - CHECK(92 == encodedLen); + CHECK(89 == encodedLen); /* Test the space for padding. Size of encoding that would result in 1 x "=" padding */ encodedLen = cryptoBase64EncodedSize(strlen("176a1620e31b14782ba2b66de3edc5b3cb19630475b2ce2ee292d5fd0fe41c3ab")); - CHECK(90 == encodedLen); + CHECK(89 == encodedLen); /* Test the space for padding. Size of encoding that would result in no padding */ encodedLen = cryptoBase64EncodedSize(strlen("176a1620e31b14782ba2b66de3edc5b3cb19630475b2ce2ee292d5fd0fe41c3a")); @@ -63,27 +63,27 @@ TEST_CASE("Base64: estimate buffer size needed to decode a message", "[Base64][a /* Padding with 2 x '=' */ encoded = "MTc2YTE2MjBlMzFiMTQ3ODJiYTJiNjZkZTNlZGM1YjNjYjE5NjMwNDc1YjJjZTJlZTI5MmQ1ZmQwZmU0MWMzYQ=="; encodedLen = cryptoBase64DecodeSize(encoded, strlen(encoded)); - CHECK(66 == encodedLen); + CHECK(67 == encodedLen); /* Padding with 1 x '=' */ encoded = "MTc2YTE2MjBlMzFiMTQ3ODJiYTJiNjZkZTNlZGM1YjNjYjE5NjMwNDc1YjJjZTJlZTI5MmQ1ZmQwZmU0MWMzYWI="; encodedLen = cryptoBase64DecodeSize(encoded, strlen(encoded)); - CHECK(66 == encodedLen); + CHECK(67 == encodedLen); /* Padding with 0 x "=" */ encoded = "MTc2YTE2MjBlMzFiMTQ3ODJiYTJiNjZkZTNlZGM1YjNjYjE5NjMwNDc1YjJjZTJlZTI5MmQ1ZmQwZmU0MWMzYWJj"; encodedLen = cryptoBase64DecodeSize(encoded, strlen(encoded)); - CHECK(66 == encodedLen); + CHECK(67 == encodedLen); /* Test empty encoded message calculation */ encoded = ""; encodedLen = cryptoBase64DecodeSize(encoded, strlen(encoded)); - CHECK(0 == encodedLen); + CHECK(1 == encodedLen); /* Test empty encoded message calculation */ encoded = nullptr; encodedLen = cryptoBase64DecodeSize(encoded, 0); - CHECK(0 == encodedLen); + CHECK(1 == encodedLen); } TEST_CASE("Base64: quick encode / decode", "[Base64][access_control][utility]") @@ -103,7 +103,7 @@ TEST_CASE("Base64: quick encode / decode", "[Base64][access_control][utility]") encodedMessageLen)); size_t decodedMessageEstimatedLen = cryptoBase64DecodeSize(encodedMessage, encodedMessageLen); - CHECK(66 == decodedMessageEstimatedLen); + CHECK(67 == decodedMessageEstimatedLen); char decodedMessage[encodedMessageEstimatedLen]; size_t decodedMessageLen = cryptoBase64Decode(encodedMessage, encodedMessageLen, decodedMessage, encodedMessageLen); diff --git a/plugins/experimental/access_control/utils.cc b/plugins/experimental/access_control/utils.cc index 53911e463b3..211716da5f0 100644 --- a/plugins/experimental/access_control/utils.cc +++ b/plugins/experimental/access_control/utils.cc @@ -296,7 +296,7 @@ cryptoMessageDigestEqual(const char *md1, size_t md1Len, const char *md2, size_t size_t cryptoBase64EncodedSize(size_t decodedSize) { - return ATS_BASE64_ENCODE_DSTLEN(decodedSize); + return ats_base64_encode_dstlen(decodedSize); } /** @@ -308,7 +308,7 @@ cryptoBase64EncodedSize(size_t decodedSize) size_t cryptoBase64DecodeSize(const char *encoded, size_t encodedLen) { - return ATS_BASE64_DECODE_DSTLEN(encodedLen); + return ats_base64_decode_dstlen(encodedLen); } /** diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc index 9f7d201a410..b8eae9a8cb5 100644 --- a/plugins/experimental/metalink/metalink.cc +++ b/plugins/experimental/metalink/metalink.cc @@ -693,7 +693,7 @@ location_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */) const char *value; int length; - char digest[33]; /* ATS_BASE64_DECODE_DSTLEN() */ + char digest[33]; /* ats_base64_decode_dstlen() */ SendData *data = static_cast(TSContDataGet(contp)); TSContDestroy(contp); diff --git a/src/tscore/ink_base64.cc b/src/tscore/ink_base64.cc index a1da352f36e..bc68758bc94 100644 --- a/src/tscore/ink_base64.cc +++ b/src/tscore/ink_base64.cc @@ -28,8 +28,6 @@ * authentication scheme does not require them. This implementation is * intended for web-related use, and line breaks are not implemented. * - * These routines return char*'s to malloc-ed strings. The caller is - * responsible for freeing the strings. */ #include "tscore/ink_platform.h" #include "tscore/ink_base64.h" @@ -44,7 +42,7 @@ ats_base64_encode(const unsigned char *inBuffer, size_t inBufferSize, char *outB char *obuf = outBuffer; char in_tail[4]; - if (outBufSize < ATS_BASE64_ENCODE_DSTLEN(inBufferSize)) { + if (outBufSize < ats_base64_encode_dstlen(inBufferSize)) { return false; } @@ -130,7 +128,7 @@ ats_base64_decode(const char *inBuffer, size_t inBufferSize, unsigned char *outB int inputBytesDecoded = 0; // Make sure there is sufficient space in the output buffer - if (outBufSize < ATS_BASE64_DECODE_DSTLEN(inBufferSize)) { + if (outBufSize < ats_base64_decode_dstlen(inBufferSize)) { return false; }