mirror of
https://github.com/jackwener/wx-cli.git
synced 2026-10-09 00:25:46 +00:00
fix: 深度 review 修复 10 个 bug/问题
Critical & High: - daemon 日志:启动时将 stdout/stderr 重定向到 ~/.wx-cli/daemon.log 而非 /dev/null,使 wx daemon logs 真正可用 - q_history 找不到聊天时改为 bail! 而非 ok:true+error 字段, 避免 CLI 静默返回空输出 - init 写 config.json 默认路径改为 ~/.wx-cli/config.json, 避免写入系统 bin 目录(/usr/local/bin/config.json) - LIKE 通配符:搜索关键词中的 %/_/\ 现在正确转义 - WAL 路径:改用 OsString.push 拼接 "-wal" 后缀, 避免 display() 在非 UTF-8 路径上失效 - cmd_stop:检查 kill() 返回值,ESRCH 时给出明确提示 Performance & Code quality: - full_decrypt:改为流式逐页读写,峰值内存从 2×文件大小降为 O(1) - Regex:msg_table_re() 用 OnceLock 静态编译,避免热路径重复编译 - mtime_nanos:消除 daemon/mod.rs 与 cache.rs 的重复定义 - use super::super::cli::transport → use super::transport - 删除未使用的 save_config、Request::to_json_line 死代码
This commit is contained in:
+17
-16
@@ -4,6 +4,7 @@ use anyhow::{bail, Result};
|
||||
use aes::Aes256;
|
||||
use cbc::Decryptor;
|
||||
use cbc::cipher::{BlockDecryptMut, KeyIvInit};
|
||||
use std::io::{Read, Write};
|
||||
use std::path::Path;
|
||||
|
||||
pub const PAGE_SZ: usize = 4096;
|
||||
@@ -73,34 +74,34 @@ fn aes_cbc_decrypt(key: &[u8; 32], iv: &[u8; 16], data: &[u8]) -> Result<Vec<u8>
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
/// 完整解密一个 SQLCipher 数据库文件
|
||||
/// 完整解密一个 SQLCipher 数据库文件(流式,逐页读写避免全量载入内存)
|
||||
///
|
||||
/// 读取 `db_path`,按 PAGE_SZ 分页解密,写入 `out_path`
|
||||
pub fn full_decrypt(db_path: &Path, out_path: &Path, enc_key: &[u8; 32]) -> Result<()> {
|
||||
let data = std::fs::read(db_path)?;
|
||||
if data.is_empty() {
|
||||
bail!("数据库文件为空: {}", db_path.display());
|
||||
}
|
||||
|
||||
if let Some(parent) = out_path.parent() {
|
||||
std::fs::create_dir_all(parent)?;
|
||||
}
|
||||
|
||||
let total_pages = (data.len() + PAGE_SZ - 1) / PAGE_SZ;
|
||||
let mut out = Vec::with_capacity(data.len());
|
||||
let mut input = std::fs::File::open(db_path)?;
|
||||
let file_size = input.metadata()?.len() as usize;
|
||||
if file_size == 0 {
|
||||
bail!("数据库文件为空: {}", db_path.display());
|
||||
}
|
||||
|
||||
let mut output = std::fs::File::create(out_path)?;
|
||||
let total_pages = (file_size + PAGE_SZ - 1) / PAGE_SZ;
|
||||
let mut page_buf = vec![0u8; PAGE_SZ];
|
||||
|
||||
for pgno in 1..=total_pages {
|
||||
let offset = (pgno - 1) * PAGE_SZ;
|
||||
let end = std::cmp::min(offset + PAGE_SZ, data.len());
|
||||
let mut page = data[offset..end].to_vec();
|
||||
let n = input.read(&mut page_buf)?;
|
||||
if n == 0 { break; }
|
||||
// 不足一页则补零
|
||||
if page.len() < PAGE_SZ {
|
||||
page.resize(PAGE_SZ, 0);
|
||||
if n < PAGE_SZ {
|
||||
page_buf[n..].fill(0);
|
||||
}
|
||||
let dec = decrypt_page(enc_key, &page, pgno as u32)?;
|
||||
out.extend_from_slice(&dec);
|
||||
let dec = decrypt_page(enc_key, &page_buf, pgno as u32)?;
|
||||
output.write_all(&dec)?;
|
||||
}
|
||||
|
||||
std::fs::write(out_path, &out)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user