From cd98afdd7bdc2c3f2e1a5d67089fa924035aa27c Mon Sep 17 00:00:00 2001 From: Andrew Gaul Date: Tue, 31 Aug 2021 00:15:47 +0900 Subject: [PATCH] Do not NUL terminate base64 decoded output (#1752) This is binary data and must use the explicit length. --- src/string_util.cpp | 3 +-- src/test_string_util.cpp | 24 ++++++++++++++++++------ src/test_util.h | 12 ++++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/string_util.cpp b/src/string_util.cpp index ee4ddf4..97fa601 100644 --- a/src/string_util.cpp +++ b/src/string_util.cpp @@ -438,7 +438,7 @@ unsigned char* s3fs_decode64(const char* input, size_t* plength) if(!input || 0 == strlen(input) || !plength){ return NULL; } - result = new unsigned char[strlen(input) / 4 * 3 + 1]; + result = new unsigned char[strlen(input) / 4 * 3]; unsigned char parts[4]; size_t input_len = strlen(input); @@ -460,7 +460,6 @@ unsigned char* s3fs_decode64(const char* input, size_t* plength) } result[wpos++] = ((parts[2] << 6) & 0xc0) | (parts[3] & 0x3f); } - result[wpos] = '\0'; *plength = wpos; return result; } diff --git a/src/test_string_util.cpp b/src/test_string_util.cpp index 7f5c442..22e52c0 100644 --- a/src/test_string_util.cpp +++ b/src/test_string_util.cpp @@ -64,23 +64,35 @@ void test_trim() void test_base64() { + unsigned char *buf; size_t len; + ASSERT_STREQUALS(s3fs_base64(NULL, 0), NULL); - ASSERT_STREQUALS(reinterpret_cast(s3fs_decode64(NULL, &len)), NULL); + buf = s3fs_decode64(NULL, &len); + ASSERT_BUFEQUALS(reinterpret_cast(buf), len, NULL, 0); + ASSERT_STREQUALS(s3fs_base64(reinterpret_cast(""), 0), NULL); - ASSERT_STREQUALS(reinterpret_cast(s3fs_decode64("", &len)), NULL); + buf = s3fs_decode64("", &len); + ASSERT_BUFEQUALS(reinterpret_cast(buf), len, NULL, 0); ASSERT_STREQUALS(s3fs_base64(reinterpret_cast("1"), 1), "MQ=="); - ASSERT_STREQUALS(reinterpret_cast(s3fs_decode64("MQ==", &len)), "1"); + buf = s3fs_decode64("MQ==", &len); + ASSERT_BUFEQUALS(reinterpret_cast(buf), len, "1", 1); ASSERT_EQUALS(len, static_cast(1)); + ASSERT_STREQUALS(s3fs_base64(reinterpret_cast("12"), 2), "MTI="); - ASSERT_STREQUALS(reinterpret_cast(s3fs_decode64("MTI=", &len)), "12"); + buf = s3fs_decode64("MTI=", &len); + ASSERT_BUFEQUALS(reinterpret_cast(buf), len, "12", 2); ASSERT_EQUALS(len, static_cast(2)); + ASSERT_STREQUALS(s3fs_base64(reinterpret_cast("123"), 3), "MTIz"); - ASSERT_STREQUALS(reinterpret_cast(s3fs_decode64("MTIz", &len)), "123"); + buf = s3fs_decode64("MTIz", &len); + ASSERT_BUFEQUALS(reinterpret_cast(buf), len, "123", 3); ASSERT_EQUALS(len, static_cast(3)); + ASSERT_STREQUALS(s3fs_base64(reinterpret_cast("1234"), 4), "MTIzNA=="); - ASSERT_STREQUALS(reinterpret_cast(s3fs_decode64("MTIzNA==", &len)), "1234"); + buf = s3fs_decode64("MTIzNA==", &len); + ASSERT_BUFEQUALS(reinterpret_cast(buf), len, "1234", 4); ASSERT_EQUALS(len, static_cast(4)); // TODO: invalid input diff --git a/src/test_util.h b/src/test_util.h index b3b20c9..8c13bfc 100644 --- a/src/test_util.h +++ b/src/test_util.h @@ -76,11 +76,23 @@ void assert_strequals(const char *x, const char *y, const char *file, int line) } } +void assert_bufequals(const char *x, size_t len1, const char *y, size_t len2, const char *file, int line) +{ + if(x == NULL && y == NULL){ + return; + // cppcheck-suppress nullPointerRedundantCheck + } else if(x == NULL || y == NULL || len1 != len2 || memcmp(x, y, len1) != 0){ + std::cerr << (x ? std::string(x, len1) : "null") << " != " << (y ? std::string(y, len2) : "null") << " at " << file << ":" << line << std::endl; + std::exit(1); + } +} + #define ASSERT_TRUE(x) assert_equals((x), true, __FILE__, __LINE__) #define ASSERT_FALSE(x) assert_equals((x), false, __FILE__, __LINE__) #define ASSERT_EQUALS(x, y) assert_equals((x), (y), __FILE__, __LINE__) #define ASSERT_NEQUALS(x, y) assert_nequals((x), (y), __FILE__, __LINE__) #define ASSERT_STREQUALS(x, y) assert_strequals((x), (y), __FILE__, __LINE__) +#define ASSERT_BUFEQUALS(x, len1, y, len2) assert_bufequals((x), (len1), (y), (len2), __FILE__, __LINE__) #endif // S3FS_TEST_UTIL_H_