diff --git a/include/spdk/base64.h b/include/spdk/base64.h index c158c2316d..86f41bba6d 100644 --- a/include/spdk/base64.h +++ b/include/spdk/base64.h @@ -64,7 +64,11 @@ static inline size_t spdk_base64_get_encoded_strlen(size_t raw_len) /** * Calculate length of raw buffer based on strlen of encoded Base64. * - * \param encoded_strlen Length of enocded Base64 string, excluding terminating null byte ('\0'). + * This length will be the max possible decoded len. The exact decoded length could be + * shorter depending on if there was padding in the Base64 string. + * + * \param encoded_strlen Length of encoded Base64 string, excluding terminating null + * byte ('\0'). * \return Length of raw buffer. */ static inline size_t spdk_base64_get_decoded_len(size_t encoded_strlen) @@ -106,13 +110,14 @@ int spdk_base64_urlsafe_encode(char *dst, const void *src, size_t src_len); * * \param dst Buffer address of decoded raw data. Its length should be enough * to contain decoded raw data, so it needs to be at least as long as - * spdk_base64_get_decoded_len(encoded_strlen). + * spdk_base64_get_decoded_len(encoded_strlen). If NULL, only dst_len will be populated + * indicating the exact decoded length. * \param dst_len Output parameter for the length of actual decoded raw data. * If NULL, the actual decoded length won't be returned. * \param src Data buffer for base64 string to be decoded. * * \return 0 on success. - * \return -EINVAL if dst or src is NULL, or content of src is illegal. + * \return -EINVAL if src is NULL, or content of src is illegal. */ int spdk_base64_decode(void *dst, size_t *dst_len, const char *src); @@ -121,13 +126,14 @@ int spdk_base64_decode(void *dst, size_t *dst_len, const char *src); * * \param dst Buffer address of decoded raw data. Its length should be enough * to contain decoded raw data, so it needs to be at least as long as - * spdk_base64_get_decoded_len(encoded_strlen). + * spdk_base64_get_decoded_len(encoded_strlen). If NULL, only dst_len will be populated + * indicating the exact decoded length. * \param dst_len Output parameter for the length of actual decoded raw data. * If NULL, the actual decoded length won't be returned. * \param src Data buffer for base64 string to be decoded. * * \return 0 on success. - * \return -EINVAL if dst or src is NULL, or content of src is illegal. + * \return -EINVAL if src is NULL, or content of src is illegal. */ int spdk_base64_urlsafe_decode(void *dst, size_t *dst_len, const char *src); diff --git a/lib/util/base64.c b/lib/util/base64.c index 0271ad6199..ade05dd460 100644 --- a/lib/util/base64.c +++ b/lib/util/base64.c @@ -163,7 +163,7 @@ _spdk_base64_decode(void *dst, size_t *_dst_len, const uint8_t *dec_table, const uint32_t tmp[4]; int i; - if (!dst || !src) { + if (!src) { return -EINVAL; } @@ -190,6 +190,12 @@ _spdk_base64_decode(void *dst, size_t *_dst_len, const uint8_t *dec_table, const if (_dst_len) { *_dst_len = spdk_base64_get_decoded_len(src_strlen); } + + /* If dst is NULL, the client is only concerned w/ _dst_len, return */ + if (!dst) { + return 0; + } + src_in = (const uint8_t *) src; #ifdef __aarch64__ diff --git a/test/unit/lib/util/base64.c/base64_ut.c b/test/unit/lib/util/base64.c/base64_ut.c index 78f8ff69c0..8cdd7b8882 100644 --- a/test/unit/lib/util/base64.c/base64_ut.c +++ b/test/unit/lib/util/base64.c/base64_ut.c @@ -148,31 +148,67 @@ test_base64_decode(void) size_t raw_len; int ret; + /* len */ + ret = spdk_base64_decode(NULL, &raw_len, text_A); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_A)); + + /* decode */ ret = spdk_base64_decode(raw, &raw_len, text_A); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_A)); CU_ASSERT(memcmp(raw, raw_A, sizeof(raw_A)) == 0); + /* len */ + ret = spdk_base64_decode(NULL, &raw_len, text_B); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_B)); + + /* decode */ ret = spdk_base64_decode(raw, &raw_len, text_B); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_B)); CU_ASSERT(memcmp(raw, raw_B, sizeof(raw_B)) == 0); + /* len */ + ret = spdk_base64_decode(NULL, &raw_len, text_C); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_C)); + + /* decode */ ret = spdk_base64_decode(raw, &raw_len, text_C); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_C)); CU_ASSERT(memcmp(raw, raw_C, sizeof(raw_C)) == 0); + /* len */ + ret = spdk_base64_decode(NULL, &raw_len, text_D); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_D)); + + /* decode */ ret = spdk_base64_decode(raw, &raw_len, text_D); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_D)); CU_ASSERT(memcmp(raw, raw_D, sizeof(raw_D)) == 0); + /* len */ + ret = spdk_base64_decode(NULL, &raw_len, text_I); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_I)); + + /* decode */ ret = spdk_base64_decode(raw, &raw_len, text_I); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_I)); CU_ASSERT(memcmp(raw, raw_I, sizeof(raw_I)) == 0); + /* len */ + ret = spdk_base64_decode(NULL, &raw_len, text_J); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_J)); + + /* decode */ ret = spdk_base64_decode(raw, &raw_len, text_J); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_J)); @@ -186,8 +222,6 @@ test_base64_decode(void) CU_ASSERT_EQUAL(ret, -EINVAL); ret = spdk_base64_decode(raw, &raw_len, text_H); CU_ASSERT_EQUAL(ret, -EINVAL); - ret = spdk_base64_decode(NULL, &raw_len, text_H); - CU_ASSERT_EQUAL(ret, -EINVAL); ret = spdk_base64_decode(raw, &raw_len, NULL); CU_ASSERT_EQUAL(ret, -EINVAL); } @@ -240,31 +274,67 @@ test_base64_urlsafe_decode(void) size_t raw_len = 0; int ret; + /* len */ + ret = spdk_base64_urlsafe_decode(NULL, &raw_len, text_A); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_A)); + + /* decode */ ret = spdk_base64_urlsafe_decode(raw, &raw_len, text_A); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_A)); CU_ASSERT(memcmp(raw, raw_A, sizeof(raw_A)) == 0); + /* len */ + ret = spdk_base64_urlsafe_decode(NULL, &raw_len, text_urlsafe_B); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_B)); + + /* decode */ ret = spdk_base64_urlsafe_decode(raw, &raw_len, text_urlsafe_B); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_B)); CU_ASSERT(memcmp(raw, raw_B, sizeof(raw_B)) == 0); + /* len */ + ret = spdk_base64_urlsafe_decode(NULL, &raw_len, text_urlsafe_C); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_C)); + + /* decode */ ret = spdk_base64_urlsafe_decode(raw, &raw_len, text_urlsafe_C); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_C)); CU_ASSERT(memcmp(raw, raw_C, sizeof(raw_C)) == 0); + /* len */ + ret = spdk_base64_urlsafe_decode(NULL, &raw_len, text_urlsafe_D); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_D)); + + /* decode */ ret = spdk_base64_urlsafe_decode(raw, &raw_len, text_urlsafe_D); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_D)); CU_ASSERT(memcmp(raw, raw_D, sizeof(raw_D)) == 0); + /* len */ + ret = spdk_base64_urlsafe_decode(NULL, &raw_len, text_urlsafe_I); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_I)); + + /* decode */ ret = spdk_base64_urlsafe_decode(raw, &raw_len, text_urlsafe_I); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_I)); CU_ASSERT(memcmp(raw, raw_I, sizeof(raw_I)) == 0); + /* len */ + ret = spdk_base64_urlsafe_decode(NULL, &raw_len, text_urlsafe_J); + CU_ASSERT_EQUAL(ret, 0); + CU_ASSERT_EQUAL(raw_len, sizeof(raw_J)); + + /* decode */ ret = spdk_base64_urlsafe_decode(raw, &raw_len, text_urlsafe_J); CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(raw_len, sizeof(raw_J)); @@ -278,8 +348,6 @@ test_base64_urlsafe_decode(void) CU_ASSERT_EQUAL(ret, -EINVAL); ret = spdk_base64_urlsafe_decode(raw, &raw_len, text_H); CU_ASSERT_EQUAL(ret, -EINVAL); - ret = spdk_base64_urlsafe_decode(NULL, &raw_len, text_H); - CU_ASSERT_EQUAL(ret, -EINVAL); ret = spdk_base64_urlsafe_decode(raw, &raw_len, NULL); CU_ASSERT_EQUAL(ret, -EINVAL); }