Files
QRGen/docs/code-review-report.md
T
Serendipity feb5ae709f fix: 4 个 CRITICAL bug 修复
- C1: placement.rs 删除列偏移特殊处理 (col==6→5),place_bit 已自动跳过保留区
- C2: version.rs V5-H 纠错表 h_g1: 4→2 (总码字数 200→134)
- C3: mode.rs Kanji 编码删除冗余 if/else 重复分支
- C4: galois.rs div() 返回 Option<u8> 替代 panic!
2026-06-17 08:58:29 +08:00

101 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# QRGen 全面代码审查报告
**日期**: 2026-06-17
**审查方式**: 三重并行审查(算法正确性 + 安全性 + 架构/代码质量)
**测试状态**: 69 tests pass | clippy: 14 风格警告
---
## CRITICAL — 必须立即修复
### C1. placement.rs:20 — 数据排列列偏移 bug(所有版本)
当 zigzag 扫描到 `col == 6`(时序图案列)时,代码改为 `col = 5` 并处理列 (5, 4)。下一轮 `col = 4` 处理列 (4, 3)。**列 4 被写入两次**,第一次写入的数据被覆盖丢失。
**修复**: 删除特殊处理。`place_bit` 已自动跳过保留区:
```rust
// 错误:
let actual_col = if col == 6 { 5 } else { col as usize };
// 正确:
let actual_col = col as usize;
```
### C2. version.rs:273 — V5-H 纠错表数据错误
`h_g1: 4` 应为 `h_g1: 2`。当前值导致总码字数不匹配 (200 ≠ 134)Version 5 + H 级生成的 QR 码数据错乱。
### C3. mode.rs:165-181 — Kanji Shift-JIS 编码 if/else 分支完全相同
`unicode_to_shift_jis` 中的 `if sjis <= 0x9FFC { ... } else { ... }` 两个分支代码完全一致。`else` 分支应使用 `h - 0xC1` 替代 `h - 0x81`
### C4. galois.rs:75 — 库函数中 panic!()
`div(a, b)``b == 0` 时 panic。库函数不应 panic,应返回 `Option<u8>``Result`
---
## HIGH — 应尽快修复
### H1. patterns.rs — 定位图案分隔符未标记为保留区
ISO 18004 要求定位图案周围有 1 模块宽的白色分隔符。当前未 `reserve()`,数据可能写入该区域,导致扫码器识别失败。
### H2. gui/src-frontend/src/hooks/useQrEncode.ts — setTimeout 未在组件卸载时清理
React Strict Mode 下或快速切换模式时,stale callback 可能在 unmount 后触发 dispatch。
### H3. version.rs — 1352 行超 800 行限制
VERSION_TABLE 占 ~1100 行。建议拆出 `version/table.rs`
### H4. 缺少 Kanji 编码单元测试
`encode_kanji``unicode_to_shift_jis` 零直接测试。
### H5. 历史记录未持久化
`AppState.history` 仅存内存,重启丢失。`tauri-plugin-store` 已注册但未接线。
### H6. 14 个 clippy 警告(12 个可 auto-fix
---
## MEDIUM
| # | 文件 | 问题 |
|---|------|------|
| M1 | QrPreview.tsx:20 | `dangerouslySetInnerHTML` — 如 SVG 渲染器未来嵌入用户文本则有 XSS 风险 |
| M2 | ExportPanel.tsx / useQrEncode.ts | 3 处 `console.error` 在生产代码中 |
| M3 | App.tsx | 缺少 React Error Boundary |
| M4 | mode.rs:148 | Kanji 编码是"近似映射",非完整 Shift JIS 转换 |
| M5 | gui/lib.rs | 边距参数无上限验证 (0-255),极端值可导致 OOM |
| M6 | svg.rs | SVG 渲染用大量 `format!` 拼接,大版本效率低 |
---
## LOW
| # | 文件 | 问题 |
|---|------|------|
| L1 | render/png.rs:38 | `.expect()` 而非错误传播 |
| L2 | galois.rs | `OnceLock` 可替换为 `LazyLock` |
| L3 | mask.rs:188 | 不必要的 `matrix.clone()` |
| L4 | version.rs | `ec_info()` 每次都分配 Vec |
| L5 | App.tsx:20 | emoji 在标题栏 |
---
## 已验证正确
- ✅ Galois GF(2⁸) 四则运算 + exp/log 表
- ✅ Reed-Solomon 生成多项式 + 长除法 + 交错
- ✅ 四种编码模式的比特计数(符合 ISO 18004)
- ✅ 比特流终止符 + 0xEC/0x11 填充
- ✅ 版本容量表(除 V5-H 外全部数学验证通过)
- ✅ BCH(15,5) + BCH(18,6) 编码
- ✅ 8 种掩码 + 四规则惩罚评分
- ✅ 定位/对齐/时序图案位置
- ✅ 格式信息 XOR 掩码 0x5412
- ✅ 零 `unsafe` 块 | 零硬编码密钥 | 零命令注入