Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Checks:
# 过于常见的用法而忽略
- "-bugprone-easily-swappable-parameters" # 参数容易被隐式转换而被调用者传错顺序
- "-misc-no-recursion" # 递归调用
- "-misc-include-cleaner" # 包含清理,某些头文件互相依赖时容易被误判
- "-performance-move-const-arg" # 无意义的move可用于标记生命周期
- "-cppcoreguidelines-pro-type-const-cast" # 使用const_cast的地方通常都是故意使用的
- "-modernize-use-nodiscard"
Expand All @@ -64,6 +65,7 @@ Checks:
- "-modernize-use-ranges"
- "-modernize-use-starts-ends-with"
- "-readability-use-anyofallof"
- "-readability-use-concise-preprocessor-directives"
# 以下检查由于性能问题被关闭(@see https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clangd/TidyFastChecks.inc)
- "-misc-confusable-identifiers"
- "-misc-const-correctness"
Expand Down
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ include("${CMAKE_CURRENT_LIST_DIR}/project/cmake/ProjectBuildOption.cmake")

# Link RPATH
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH YES)
set(CMAKE_BUILD_WITH_INSTALL_RPATH NO)
set(CMAKE_BUILD_RPATH_USE_ORIGIN YES)

set(ATFRAMEWORK_UTILS_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
Expand Down
2 changes: 0 additions & 2 deletions include/algorithm/compression.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@

# include <cstddef>
# include <cstdint>
# include <string>
# include <vector>

ATFRAMEWORK_UTILS_NAMESPACE_BEGIN
Expand Down Expand Up @@ -149,4 +148,3 @@ ATFRAMEWORK_UTILS_NAMESPACE_END
#endif // ATFW_UTIL_MACRO_COMPRESSION_ENABLED

#endif // UTIL_ALGORITHM_COMPRESSION_H

7 changes: 3 additions & 4 deletions include/algorithm/sha.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ class sha {
ATFRAMEWORK_UTILS_API sha();
ATFRAMEWORK_UTILS_API ~sha();

ATFRAMEWORK_UTILS_API sha(sha&&);
ATFRAMEWORK_UTILS_API sha& operator=(sha&&);
ATFRAMEWORK_UTILS_API sha(sha&&) noexcept;
ATFRAMEWORK_UTILS_API sha& operator=(sha&&) noexcept;

ATFRAMEWORK_UTILS_API bool init(type);
ATFRAMEWORK_UTILS_API void close();
ATFRAMEWORK_UTILS_API void swap(sha& other);
ATFRAMEWORK_UTILS_API void swap(sha& other) noexcept;

ATFRAMEWORK_UTILS_API bool update(const unsigned char* in, size_t inlen);
ATFRAMEWORK_UTILS_API bool final();
Expand Down Expand Up @@ -95,4 +95,3 @@ class sha {
ATFRAMEWORK_UTILS_NAMESPACE_END

#endif

121 changes: 72 additions & 49 deletions src/algorithm/base64.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
// Copyright 2026 atframework

#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <limits>
// Project namespace/API macros are provided by the public header and are intentionally used through it here.
// NOLINTBEGIN(misc-include-cleaner)

#include <cassert>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <string>

#include "algorithm/base64.h"

#define BASE64_SIZE_T_MAX ((size_t)-1) /* SIZE_T_MAX is not standard */
#define BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */
#define BASE64_SIZE_T_MAX ((size_t)-1) /* SIZE_T_MAX is not standard */
#define BASE64_INVALID_CHARACTER (-0x002C) /**< Invalid character in input. */

ATFRAMEWORK_UTILS_NAMESPACE_BEGIN

namespace detail {
namespace {
using base_enc_map_t = const unsigned char[64];
using base_dec_map_t = const unsigned char[128];
static base_enc_map_t base64_enc_map_basic = {
Expand Down Expand Up @@ -56,15 +58,26 @@ static constexpr const unsigned char base64_dec_map_url[128] = {
23, 24, 25, 127, 127, 127, 127, 63, 127, 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, 127, 127, 127, 127, 127};

static inline char *get_writable_string_data(std::string &value) noexcept {
if (value.empty()) {
return nullptr;
}
#if (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L
return value.data();
#else
return &value[0]; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index,modernize-use-data)
#endif
}

static int base64_encode_inner(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen,
base_enc_map_t &base64_enc_map, unsigned char padding_char) {
size_t i, n, nopadding;
int C1, C2, C3;
unsigned char *p;
size_t i = 0, n = 0, nopadding = 0;
int C1 = 0, C2 = 0, C3 = 0;
unsigned char *p = nullptr;

if (slen == 0) {
*olen = 0;
return (0);
return 0;
}

n = (slen + 2) / 3;
Expand Down Expand Up @@ -123,7 +136,7 @@ static int base64_encode_inner(unsigned char *dst, size_t dlen, size_t *olen, co
*olen = static_cast<size_t>(p - dst);
*p = 0;

return (0);
return 0;
}

static inline int base64_encode_inner(std::string &dst, const unsigned char *src, size_t slen,
Expand All @@ -136,8 +149,8 @@ static inline int base64_encode_inner(std::string &dst, const unsigned char *src
return 0;
}

int ret = base64_encode_inner(reinterpret_cast<unsigned char *>(&dst[0]), dst.size(), &olen, src, slen,
base64_enc_map, padding_char);
int ret = base64_encode_inner(reinterpret_cast<unsigned char *>(get_writable_string_data(dst)), dst.size(), &olen,
src, slen, base64_enc_map, padding_char);
assert(0 != ret || dst.size() == olen + 1);
// pop back last zero
if (!dst.empty() && *dst.rbegin() == 0) {
Expand All @@ -154,10 +167,10 @@ static inline int base64_encode_inner(std::string &dst, const std::string &in, b

static int base64_decode_inner(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen,
base_dec_map_t &base64_dec_map, unsigned char padding_char) {
size_t i, n;
size_t j, x;
size_t valid_slen, line_len;
unsigned char *p;
size_t i = 0, n = 0;
size_t j = 0, x = 0;
size_t valid_slen = 0, line_len = 0;
unsigned char *p = nullptr;

/* First pass: check for validity and get output length */
for (i = n = j = valid_slen = line_len = 0; i < slen; i++) {
Expand All @@ -169,37 +182,46 @@ static int base64_decode_inner(unsigned char *dst, size_t dlen, size_t *olen, co
}

/* Spaces at end of buffer are OK */
if (i == slen) break;
if (i == slen) {
break;
}

if (src[i] == '\r' || src[i] == '\n') {
line_len = 0;
continue;
}

/* Space inside a line is an error */
if (x != 0 && line_len != 0) return -2;
if (x != 0 && line_len != 0) {
return -2;
}

++valid_slen;
++line_len;
if (src[i] == padding_char) {
if (++j > 2) {
return -2;
} else if ((valid_slen & 3) == 1 || (valid_slen & 3) == 2) {
}
if ((valid_slen & 3) == 1 || (valid_slen & 3) == 2) {
// First and second char of every group can not be padding char
return -2;
}
} else {
if (src[i] > 127 || base64_dec_map[src[i]] == 127) return -2;
if (src[i] > 127 || base64_dec_map[src[i]] == 127) {
return -2;
}
}

if (base64_dec_map[src[i]] < 64 && j != 0) return -2;
if (base64_dec_map[src[i]] < 64 && j != 0) {
return -2;
}

n++;
}

if (n == 0) {
*olen = 0;
return (0);
return 0;
}

// no padding, add j to padding length
Expand All @@ -212,7 +234,7 @@ static int base64_decode_inner(unsigned char *dst, size_t dlen, size_t *olen, co
* risk of integer overflow in n:
* n = ( ( n * 6 ) + 7 ) >> 3;
*/
n = (6 * (n >> 3)) + ((6 * (n & 0x7) + 7) >> 3);
n = (6 * (n >> 3)) + (((6 * (n & 0x7)) + 7) >> 3);
n -= j;

if (dst == nullptr || dlen < n) {
Expand All @@ -221,30 +243,34 @@ static int base64_decode_inner(unsigned char *dst, size_t dlen, size_t *olen, co
}

for (n = x = 0, p = dst; i > 0; i--, src++) {
if (*src == '\r' || *src == '\n' || *src == ' ' || *src == '\t') continue;
if (*src == padding_char) continue;
if (*src == '\r' || *src == '\n' || *src == ' ' || *src == '\t') {
continue;
}
if (*src == padding_char) {
continue;
}

x = (x << 6) | (base64_dec_map[*src] & 0x3F);

if (++n == 4) {
n = 0;
*p++ = (unsigned char)(x >> 16);
*p++ = (unsigned char)(x >> 8);
*p++ = (unsigned char)(x);
*p++ = static_cast<unsigned char>(x >> 16);
*p++ = static_cast<unsigned char>(x >> 8);
*p++ = static_cast<unsigned char>(x);
}
}

// no padding, the tail code
if (n == 2) {
*p++ = (unsigned char)(x >> 4);
*p++ = static_cast<unsigned char>(x >> 4);
} else if (n == 3) {
*p++ = (unsigned char)(x >> 10);
*p++ = (unsigned char)(x >> 2);
*p++ = static_cast<unsigned char>(x >> 10);
*p++ = static_cast<unsigned char>(x >> 2);
}

*olen = static_cast<size_t>(p - dst);

return (0);
return 0;
}

static inline int base64_decode_inner(std::string &dst, const unsigned char *src, size_t slen,
Expand All @@ -260,8 +286,8 @@ static inline int base64_decode_inner(std::string &dst, const unsigned char *src
}

dst.resize(olen);
int ret = base64_decode_inner(reinterpret_cast<unsigned char *>(&dst[0]), dst.size(), &olen, src, slen,
base64_dec_map, padding_char);
int ret = base64_decode_inner(reinterpret_cast<unsigned char *>(get_writable_string_data(dst)), dst.size(), &olen,
src, slen, base64_dec_map, padding_char);
assert(0 != ret || olen == dst.size());
return ret;
}
Expand Down Expand Up @@ -320,39 +346,36 @@ static inline unsigned char base64_get_padding_char(base64_mode_t::type mode) {
return '=';
}
}
} // namespace detail
} // namespace

ATFRAMEWORK_UTILS_API int base64_encode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src,
size_t slen, base64_mode_t::type mode) {
return detail::base64_encode_inner(dst, dlen, olen, src, slen, detail::base64_get_enc_map(mode),
detail::base64_get_padding_char(mode));
return base64_encode_inner(dst, dlen, olen, src, slen, base64_get_enc_map(mode), base64_get_padding_char(mode));
}

ATFRAMEWORK_UTILS_API int base64_encode(std::string &dst, const unsigned char *src, size_t slen,
base64_mode_t::type mode) {
return detail::base64_encode_inner(dst, src, slen, detail::base64_get_enc_map(mode),
detail::base64_get_padding_char(mode));
return base64_encode_inner(dst, src, slen, base64_get_enc_map(mode), base64_get_padding_char(mode));
}

ATFRAMEWORK_UTILS_API int base64_encode(std::string &dst, const std::string &in, base64_mode_t::type mode) {
return detail::base64_encode_inner(dst, in, detail::base64_get_enc_map(mode), detail::base64_get_padding_char(mode));
return base64_encode_inner(dst, in, base64_get_enc_map(mode), base64_get_padding_char(mode));
}

ATFRAMEWORK_UTILS_API int base64_decode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src,
size_t slen, base64_mode_t::type mode) {
return detail::base64_decode_inner(dst, dlen, olen, src, slen, detail::base64_get_dec_map(mode),
detail::base64_get_padding_char(mode));
return base64_decode_inner(dst, dlen, olen, src, slen, base64_get_dec_map(mode), base64_get_padding_char(mode));
}

ATFRAMEWORK_UTILS_API int base64_decode(std::string &dst, const unsigned char *src, size_t slen,
base64_mode_t::type mode) {
return detail::base64_decode_inner(dst, src, slen, detail::base64_get_dec_map(mode),
detail::base64_get_padding_char(mode));
return base64_decode_inner(dst, src, slen, base64_get_dec_map(mode), base64_get_padding_char(mode));
}

ATFRAMEWORK_UTILS_API int base64_decode(std::string &dst, const std::string &in, base64_mode_t::type mode) {
return detail::base64_decode_inner(dst, in, detail::base64_get_dec_map(mode), detail::base64_get_padding_char(mode));
return base64_decode_inner(dst, in, base64_get_dec_map(mode), base64_get_padding_char(mode));
}

ATFRAMEWORK_UTILS_NAMESPACE_END

// NOLINTEND(misc-include-cleaner)
Loading
Loading