util/base64: Extend b64 decode to calculate exact len
When attempting to decode a base64 string, while there is a way to calculate the maximum possible decode length, there isn't a way to calculate the exact decode length without duplicating some base64 specific logic located in spdk_base64_decode. With this change, the spdk_base64_decode function can now optionally calculate the exact decode length without actually performing the decode by passing NULL in as the dst argument. Change-Id: Ice83db979f86a6fe9f39d236d3083102ca37ec68 Signed-off-by: Mike Carlin <mikefcarlin@protonmail.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479479 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Xiaodong Liu <xiaodong.liu@intel.com> Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
parent
1c06235ab3
commit
06fc4cadbe
@ -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);
|
||||
|
||||
|
@ -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__
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user