feat test base64

This commit is contained in:
tqcq
2024-03-22 21:24:11 +08:00
parent 6aa8791ce8
commit e96e8d9ad7
7 changed files with 90 additions and 26 deletions

View File

@@ -1,20 +1,12 @@
#include "sled/strings/base64.h"
#include "sled/synchronization/call_once.h"
#include <fmt/format.h>
#include <sstream>
namespace sled {
const char kBase64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const int kInvBase64Chars[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
-1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};
static int kInvBase64Chars[(1 << sizeof(char))];
static OnceFlag once_flag;
inline bool
IsBase64(char c)
@@ -22,14 +14,26 @@ IsBase64(char c)
return isalnum(c) || c == '+' || c == '/';
}
std::string
Base64::Encode(void *ptr, size_t len)
{
auto data = reinterpret_cast<unsigned char *>(ptr);
return Encode(std::vector<unsigned char>(data, data + len));
}
std::string
Base64::Encode(const std::string &input)
{
return Encode((void *) input.data(), input.length());
}
std::string
Base64::Encode(const std::vector<unsigned char> &data)
{
std::stringstream ss;
const unsigned char *data = reinterpret_cast<const unsigned char *>(input.c_str());
int value = 0;
int value_bits = 0;
for (unsigned char c : input) {
for (unsigned char c : data) {
value = (value << 8) + c;
value_bits += 8;
while (value_bits >= 6) {
@@ -52,6 +56,11 @@ Base64::Encode(const std::string &input)
StatusOr<std::string>
Base64::Decode(const std::string &input)
{
CallOnce(once_flag, [&] {
std::fill(kInvBase64Chars, kInvBase64Chars + sizeof(kInvBase64Chars), -1);
for (int i = 0; i < sizeof(kBase64Chars); i++) { kInvBase64Chars[kBase64Chars[i]] = i; }
});
std::stringstream ss;
int value = 0;
int value_bits = 0;

View File

@@ -0,0 +1,18 @@
#include <sled/log/log.h>
#include <sled/strings/base64.h>
#include <stdlib.h>
#include <string.h>
extern "C" int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
std::string encoded = sled::Base64::Encode((void *) data, size);
auto decoded_or = sled::Base64::Decode(encoded);
ASSERT(decoded_or.ok(), "decoded failed");
auto decoded = decoded_or.value();
ASSERT(decoded.size() == size, "decoded size mismatch");
ASSERT(memcmp(decoded.data(), data, size) == 0, "decoded data mismatch");
return 0;
}

View File

@@ -4,19 +4,20 @@
#define CONCAT_IMPL(A, B) A##B
#define CONCAT(A, B) CONCAT_IMPL(A, B)
#define TEST_ENCODE_DECODE(base64, text) \
do { \
ASSERT_EQ(sled::Base64::Encode(text), base64); \
auto CONCAT(res, __LINE__) = sled::Base64::Decode(base64); \
ASSERT_TRUE(CONCAT(res, __LINE__).ok()); \
ASSERT_EQ(CONCAT(res, __LINE__).value(), text); \
#define TEST_ENCODE_DECODE(base64, text) \
do { \
ASSERT_EQ(sled::Base64::Encode(text), base64); \
auto CONCAT(res, __LINE__) = sled::Base64::Decode(base64); \
ASSERT_TRUE(CONCAT(res, __LINE__).ok()); \
ASSERT_EQ(CONCAT(res, __LINE__).value(), text); \
} while (0)
TEST(Base64, EncodeAndDecode)
{
TEST_ENCODE_DECODE("aGVsbG8gd29ybGQK", "hello world\n");
TEST_ENCODE_DECODE("U2VuZCByZWluZm9yY2VtZW50cwo=", "Send reinforcements\n");
TEST_ENCODE_DECODE("", "");
TEST_ENCODE_DECODE("U2VuZCByZWluZm9yY2VtZW50cwo=", "Send reinforcements\n");
TEST_ENCODE_DECODE(" ", " ");
TEST_ENCODE_DECODE("AA==", std::string("\0", 1));
TEST_ENCODE_DECODE("AAA=", std::string("\0\0", 2));
TEST_ENCODE_DECODE("AAAA", std::string("\0\0\0", 3));