actpred: 代码审计(16项发现全部修复)+ 文档更新
审计报告: docs/reviews/actpred_CODE_AUDIT_20260808.md - P0(2项): episode索引错位(dataset.py)、推理归一化静默失败(predict.py) - P1(6项): 空训练集校验、图像自然排序、空样本防御、形状校验、 MobileNet下载错误提示、stats路径校验 - P2(8项): README示例修正、公共属性、glob优化、版本约束、 单元测试(17项)、GPU安装说明、BooleanOptionalAction、ONNX验证 新增文件: actpred/test_actpred.py (17项单元测试, 全部通过) 更新文档: README.md配置表扩充、INDEX.md、审计报告修复总结
This commit is contained in:
1 parent
1e34348d6c
commit
3d03f7a1ce
19 files changed
+850
-177
No files matched your search
+34
-42
@@ -1,14 +1,18 @@
|
||||
#pragma once
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include "Crypto_Basic.hpp"
|
||||
|
||||
struct BIO_deleter_b64 {
|
||||
void operator()(BIO* bio) const { BIO_free_all(bio); }
|
||||
};
|
||||
using BIO_ptr_b64 = std::unique_ptr<BIO, BIO_deleter_b64>;
|
||||
|
||||
namespace qing {
|
||||
class Base64 : public qing::Crypto_Basic {
|
||||
public:
|
||||
@@ -44,36 +48,33 @@ namespace qing {
|
||||
|
||||
/* 静态方法:直接编码字节向量(工具函数) */
|
||||
static std::string base64_encode(const std::vector<unsigned char>& input_bytes) {
|
||||
// 创建BIO链:内存BIO -> Base64 BIO
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
// 创建BIO链:内存BIO -> Base64 BIO(RAII 自动释放)
|
||||
BIO_ptr_b64 bio(BIO_new(BIO_s_mem()));
|
||||
CRYPTO_CHECK(bio != nullptr, "无法创建内存BIO");
|
||||
|
||||
BIO* b64 = BIO_new(BIO_f_base64());
|
||||
CRYPTO_CHECK(b64 != nullptr, "无法创建Base64 BIO");
|
||||
|
||||
// 将Base64 BIO连接到内存BIO
|
||||
bio = BIO_push(b64, bio);
|
||||
bio.reset(BIO_push(b64, bio.release()));
|
||||
|
||||
// 设置不添加换行符(默认会添加换行)
|
||||
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
|
||||
BIO_set_flags(bio.get(), BIO_FLAGS_BASE64_NO_NL);
|
||||
|
||||
// 写入数据
|
||||
int written = BIO_write(bio, input_bytes.data(), input_bytes.size());
|
||||
CRYPTO_CHECK(written == (int)input_bytes.size(), "Base64编码写入失败");
|
||||
int written = BIO_write(bio.get(), input_bytes.data(), static_cast<int>(input_bytes.size()));
|
||||
CRYPTO_CHECK(written == static_cast<int>(input_bytes.size()), "Base64编码写入失败");
|
||||
|
||||
// 刷新缓冲区
|
||||
CRYPTO_CHECK(BIO_flush(bio) == 1, "Base64编码刷新失败");
|
||||
CRYPTO_CHECK(BIO_flush(bio.get()) == 1, "Base64编码刷新失败");
|
||||
|
||||
// 读取编码结果
|
||||
BUF_MEM* bptr;
|
||||
BIO_get_mem_ptr(bio, &bptr);
|
||||
BIO_get_mem_ptr(bio.get(), &bptr);
|
||||
|
||||
// 复制结果到字符串(不包括空终止符)
|
||||
std::string result(bptr->data, bptr->length);
|
||||
|
||||
// 清理BIO
|
||||
BIO_free_all(bio);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -85,18 +86,18 @@ namespace qing {
|
||||
|
||||
/* 静态方法:直接解码为字节向量(工具函数) */
|
||||
static std::vector<unsigned char> base64_decode_to_bytes(const std::string& base64_text) {
|
||||
// 创建BIO链:Base64 BIO -> 内存BIO
|
||||
BIO* bio = BIO_new_mem_buf(base64_text.c_str(), -1);
|
||||
// 创建BIO链:Base64 BIO -> 内存BIO(RAII 自动释放)
|
||||
BIO_ptr_b64 bio(BIO_new_mem_buf(base64_text.c_str(), -1));
|
||||
CRYPTO_CHECK(bio != nullptr, "无法创建内存BIO");
|
||||
|
||||
BIO* b64 = BIO_new(BIO_f_base64());
|
||||
CRYPTO_CHECK(b64 != nullptr, "无法创建Base64 BIO");
|
||||
|
||||
// 将Base64 BIO连接到内存BIO
|
||||
bio = BIO_push(b64, bio);
|
||||
bio.reset(BIO_push(b64, bio.release()));
|
||||
|
||||
// 设置不添加换行符(解码时也要匹配)
|
||||
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
|
||||
BIO_set_flags(bio.get(), BIO_FLAGS_BASE64_NO_NL);
|
||||
|
||||
// 准备接收缓冲区
|
||||
std::vector<unsigned char> result;
|
||||
@@ -104,47 +105,38 @@ namespace qing {
|
||||
int bytes_read;
|
||||
|
||||
// 循环读取解码数据
|
||||
while ((bytes_read = BIO_read(bio, buffer, sizeof(buffer))) > 0) {
|
||||
while ((bytes_read = BIO_read(bio.get(), buffer, sizeof(buffer))) > 0) {
|
||||
result.insert(result.end(), buffer, buffer + bytes_read);
|
||||
}
|
||||
|
||||
// 检查是否解码成功(BIO_read返回0表示结束,负值表示错误)
|
||||
CRYPTO_CHECK(bytes_read >= 0, "Base64解码失败");
|
||||
|
||||
// 清理BIO
|
||||
BIO_free_all(bio);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 验证Base64格式是否有效 */
|
||||
static bool is_valid_base64(const std::string& base64_text) {
|
||||
// 检查是否只包含Base64字符(A-Z, a-z, 0-9, +, /, =)
|
||||
if (base64_text.empty()) return false;
|
||||
// 长度必须是4的倍数
|
||||
if (base64_text.size() % 4 != 0) return false;
|
||||
|
||||
for (char c : base64_text) {
|
||||
if (!((c >= 'A' && c <= 'Z') ||
|
||||
(c >= 'a' && c <= 'z') ||
|
||||
(c >= '0' && c <= '9') ||
|
||||
c == '+' || c == '/' || c == '=')) {
|
||||
size_t padding = 0;
|
||||
for (size_t i = 0; i < base64_text.size(); ++i) {
|
||||
char c = base64_text[i];
|
||||
if (c == '=') {
|
||||
padding++;
|
||||
// '=' 只能出现在末尾且不超过2个
|
||||
if (padding > 2 || i < base64_text.size() - padding) return false;
|
||||
} else if (!((c >= 'A' && c <= 'Z') ||
|
||||
(c >= 'a' && c <= 'z') ||
|
||||
(c >= '0' && c <= '9') ||
|
||||
c == '+' || c == '/')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* 打印编码结果(调试用) */
|
||||
static void print_encoded(const std::string& encoded_text) {
|
||||
std::cerr << "Base64 Encoded: " << encoded_text << std::endl;
|
||||
}
|
||||
|
||||
/* 打印解码结果(调试用) */
|
||||
static void print_decoded(const std::vector<unsigned char>& decoded_bytes) {
|
||||
std::cerr << "Decoded bytes: ";
|
||||
for (unsigned char byte : decoded_bytes) {
|
||||
std::cerr << std::setw(2) << static_cast<int>(byte);
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user