fix(db2): 修复清理时间戳格式偏差,增加配置完整性校验
P2-1: 清理 SQL 改用 strftime 统一 T 分隔格式,消除保留期约 1 天偏移 P2-2: load_config 对 7 个必需字段做必填校验,缺失则 exit(1) 审计进度:已修复 6/9(P0×2 P1×1 P2×2 P3×1),剩余 3 项 P3
This commit is contained in:
1 parent
c45e2e13f4
commit
ec626dc8d5
2 files changed
+32
-9
No files matched your search
+20
-1
@@ -151,6 +151,25 @@ static Config load_config(int argc, char* argv[]) {
|
|||||||
|
|
||||||
// 3. 解析 INI(白名单字段)
|
// 3. 解析 INI(白名单字段)
|
||||||
IniMap ini = parse_ini(ini_text);
|
IniMap ini = parse_ini(ini_text);
|
||||||
|
|
||||||
|
// 校验必需配置项(confs 提供的 db.ini 必须包含完整配置)
|
||||||
|
static const std::pair<const char*, const char*> required_keys[] = {
|
||||||
|
{"server", "host"},
|
||||||
|
{"server", "port"},
|
||||||
|
{"server", "workers"},
|
||||||
|
{"database", "url"},
|
||||||
|
{"logs", "retention_days"},
|
||||||
|
{"logs", "max_records"},
|
||||||
|
{"logs", "cleanup_interval"},
|
||||||
|
};
|
||||||
|
for (auto& [sec, key] : required_keys) {
|
||||||
|
auto si = ini.find(sec);
|
||||||
|
if (si == ini.end() || si->second.find(key) == si->second.end()) {
|
||||||
|
std::fprintf(stderr, "[db2] missing required config: [%s] %s\n", sec, key);
|
||||||
|
std::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto get = [&](const std::string& sec, const std::string& key,
|
auto get = [&](const std::string& sec, const std::string& key,
|
||||||
const std::string& def = "") -> std::string {
|
const std::string& def = "") -> std::string {
|
||||||
auto si = ini.find(sec);
|
auto si = ini.find(sec);
|
||||||
@@ -790,7 +809,7 @@ private:
|
|||||||
|
|
||||||
// 1. 删除超过 retention_days 的记录
|
// 1. 删除超过 retention_days 的记录
|
||||||
std::string cutoff_sql =
|
std::string cutoff_sql =
|
||||||
"DELETE FROM Logs WHERE ts < datetime('now', '-"
|
"DELETE FROM Logs WHERE ts < strftime('%Y-%m-%dT%H:%M:%S','now', '-"
|
||||||
+ std::to_string(_cfg.retention_days) + " days')";
|
+ std::to_string(_cfg.retention_days) + " days')";
|
||||||
conn.exec(cutoff_sql);
|
conn.exec(cutoff_sql);
|
||||||
int expired = sqlite3_changes(conn.get());
|
int expired = sqlite3_changes(conn.get());
|
||||||
|
|||||||
@@ -13,9 +13,9 @@
|
|||||||
|--------|------|--------|--------|
|
|--------|------|--------|--------|
|
||||||
| P0 | 2 | 2 | 0 |
|
| P0 | 2 | 2 | 0 |
|
||||||
| P1 | 1 | 1 | 0 |
|
| P1 | 1 | 1 | 0 |
|
||||||
| P2 | 2 | 0 | 2 |
|
| P2 | 2 | 2 | 0 |
|
||||||
| P3 | 4 | 1 | 3 |
|
| P3 | 4 | 1 | 3 |
|
||||||
| **合计** | **9** | **4** | **5** |
|
| **合计** | **9** | **6** | **3** |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -88,8 +88,10 @@
|
|||||||
### P2-1: 清理时间戳格式不一致(T vs 空格)导致保留期偏移约 1 天
|
### P2-1: 清理时间戳格式不一致(T vs 空格)导致保留期偏移约 1 天
|
||||||
|
|
||||||
- **位置**: `db2.cpp` L54-60(`utc_now`)、L787-789(`_do_cleanup`)
|
- **位置**: `db2.cpp` L54-60(`utc_now`)、L787-789(`_do_cleanup`)
|
||||||
- **当前状态**: ❌ 未修复
|
- **当前状态**: ✅ 已修复(2026-08-07)
|
||||||
- **详情**:
|
- **修复**: 清理 SQL 改用 `strftime('%Y-%m-%dT%H:%M:%S','now','-N days')`,与 `utc_now()` 的 `T` 分隔格式完全对齐,截止时间字符串比较正确,保留期精确匹配配置天数。
|
||||||
|
|
||||||
|
- **原始问题**:
|
||||||
|
|
||||||
存储的时间戳用 `utc_now()`,格式 `%Y-%m-%dT%H:%M:%S`(T 分隔)。清理 SQL 用 SQLite 内置 `datetime('now', '-N days')`,格式 `%Y-%m-%d %H:%M:%S`(空格分隔):
|
存储的时间戳用 `utc_now()`,格式 `%Y-%m-%dT%H:%M:%S`(T 分隔)。清理 SQL 用 SQLite 内置 `datetime('now', '-N days')`,格式 `%Y-%m-%d %H:%M:%S`(空格分隔):
|
||||||
|
|
||||||
@@ -108,8 +110,10 @@
|
|||||||
### P2-2: 缺少配置完整性校验
|
### P2-2: 缺少配置完整性校验
|
||||||
|
|
||||||
- **位置**: `db2.cpp` L131-185(`load_config`)
|
- **位置**: `db2.cpp` L131-185(`load_config`)
|
||||||
- **当前状态**: ❌ 未修复
|
- **当前状态**: ✅ 已修复(2026-08-07)
|
||||||
- **详情**:
|
- **修复**: 在 INI 解析后、环境变量覆盖前,对 7 个必需字段(`[server] host/port/workers`、`[database] url`、`[logs] retention_days/max_records/cleanup_interval`)做必填校验,缺失任一则 `fprintf` 明确错误信息后 `exit(1)`,不再用错误默认值静默运行。
|
||||||
|
|
||||||
|
- **原始问题**:
|
||||||
|
|
||||||
`load_config` 对缺失配置项直接用内置默认值兜底(`get(sec, key, cfg.xxx)` 模式)。Python 版(`dbv2.py` L118-129)校验所有必需配置项,缺失则退出。
|
`load_config` 对缺失配置项直接用内置默认值兜底(`get(sec, key, cfg.xxx)` 模式)。Python 版(`dbv2.py` L118-129)校验所有必需配置项,缺失则退出。
|
||||||
|
|
||||||
@@ -154,10 +158,10 @@
|
|||||||
|
|
||||||
### 短期(72小时)
|
### 短期(72小时)
|
||||||
- [x] **P1-1**: 按 JSON 类型分别使用 `sqlite3_bind_int64` / `sqlite3_bind_double` / `sqlite3_bind_text`
|
- [x] **P1-1**: 按 JSON 类型分别使用 `sqlite3_bind_int64` / `sqlite3_bind_double` / `sqlite3_bind_text`
|
||||||
- [ ] **P2-2**: 配置完整性校验(必需字段缺失则退出)
|
- [x] **P2-2**: 配置完整性校验(必需字段缺失则退出)
|
||||||
|
|
||||||
### 中期
|
### 中期
|
||||||
- [ ] **P2-1**: 清理时间戳格式统一为 T 分隔
|
- [x] **P2-1**: 清理时间戳格式统一为 T 分隔
|
||||||
- [ ] **P3-3**: limit/offset 负值校验
|
- [ ] **P3-3**: limit/offset 负值校验
|
||||||
- [ ] **P3-4**: WHERE 条件数 / IN 数组大小上限
|
- [ ] **P3-4**: WHERE 条件数 / IN 数组大小上限
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user