Files
VX5_KRO_GearPump/doc/BarcodeEditor_Robustness_Analysis.md
2026-07-01 08:16:05 +08:00

94 lines
3.9 KiB
Markdown
Raw Permalink 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.
# BarcodeEditor 健壮性分析报告
## 涉及文件
| 文件 | 说明 |
|------|------|
| [scene/BarcodeEditor.h](../scene/BarcodeEditor.h) | `BarcodeViewModel` 结构体 + `BarcodeEditor` 类声明 |
| [scene/BarcodeEditor.cpp](../scene/BarcodeEditor.cpp) | `BarcodeEditor` 类实现 |
---
## 🔴 高风险(必定崩溃)
### 1. `applyCounterConfigToSysPara()` — `m_sysPara->devOp` 无 null 检查
**文件**: [BarcodeEditor.cpp:260](../scene/BarcodeEditor.cpp#L260)
```cpp
m_sysPara->devOp->writeFpgaCalandar(0);
```
**问题**:函数开头已经检查 `if (!m_sysPara) return;`,但 `m_sysPara` 不为 null 不代表 `m_sysPara->devOp` 不为 null。`devOp` 仍可能为 null,此时直接访问会崩溃。
---
## 🟡 中风险(特定条件下逻辑错误)
### 2. `BarcodeViewModel::saveToXml()` — `QVariant::value<T>()` 类型不一致
**文件**: [BarcodeEditor.cpp:515-534](../scene/BarcodeEditor.cpp#L515-L534)
```cpp
if(vm.type == BARCODE_TYPE_BARCODE) {
DlgBarcodeFormatVM barcodeFormat = vm.format.value<DlgBarcodeFormatVM>();
// ...
}
else {
DlgQrcodeFormatVM qrcodeFormat = vm.format.value<DlgQrcodeFormatVM>();
// ...
}
```
**问题**:如果 `vm.type` 与 `vm.format` 中实际存储的类型不一致,`QVariant::value<T>()` 会返回默认构造对象,不会崩溃但会导致数据丢失。QVariant 本身保证不崩溃。
---
### 3. `bindViewModel()` 和 `onContentChanged()` — `m_sysPara` 可能为 null 传给 `makeCounterVM`
**文件**: [BarcodeEditor.cpp:135-140](../scene/BarcodeEditor.cpp#L135-L140) 和 [BarcodeEditor.cpp:467-472](../scene/BarcodeEditor.cpp#L467-L472)
```cpp
m_counterEditor->setViewModel(makeCounterVM(m_sysPara, ...));
```
**问题**:`m_sysPara` 可能为 null(`bindSysPara()` 未被调用时),虽然 `makeCounterVM` 内部已有 `if(!sysPara) return vm;` 保护,不会崩溃,但返回的空 VM 可能导致计数器显示不正确。
---
## 🟢 低风险(健壮性瑕疵,不会崩溃)
### 4. 构造函数中 `m_dateFormatEditor` / `m_dateReplaceEditor` / `m_counterEditor` 未设置 parent
**文件**: [BarcodeEditor.cpp:50-55](../scene/BarcodeEditor.cpp#L50-L55)
```cpp
m_dateFormatEditor = new DateFormatEditor();
m_dateReplaceEditor = new DateReplaceEditor();
m_counterEditor = new CounterEditor();
```
析构中手动 delete,不会内存泄漏。但无 parent 意味着 Qt 父子对象机制不适用,需确保析构顺序正确。
---
## 已经做得好的地方
- ✅ `bindSysPara()` 对 null 输入有检查 + 日志输出
- ✅ `applyCounterConfigToSysPara()` 对 `m_sysPara` null 有检查 + 日志输出
- ✅ `m_dateFormatEditor` / `m_dateReplaceEditor` / `m_counterEditor` 在构造中 new,析构中 delete,内存管理正确
- ✅ 删除标签页使用 `indexOf()` 检查 `-1` 后才移除,不会 remove 不存在的 tab
- ✅ `makeCounterVM()` 对 `sysPara` null 有检查,返回默认构造的 VM
- ✅ `eventFilter` 中对 `cursor < 0` 做了检查
- ✅ `m_barcodeFormatEditor` / `m_qrcodeFormatEditor` 作为成员变量(非指针),构造时自动初始化,永远有效
- ✅ `Q_DECLARE_METATYPE` 已声明,QVariant 类型转换安全
---
## 📋 需要修复的问题汇总
| 优先级 | 位置 | 问题 | 修复方案 |
|--------|------|------|----------|
| **P1** | `BarcodeEditor::applyCounterConfigToSysPara()` L260 | `m_sysPara->devOp` 无 null 检查 | 在访问 `devOp` 前加 `if(m_sysPara->devOp)` 保护 |
| **P2** | `bindViewModel()` L134-141 + `onContentChanged()` L466-473 | `m_sysPara` 可能为 null 传给 `makeCounterVM` | 虽然 `makeCounterVM` 自己能处理,但建议加日志或确认 `bindSysPara` 调用时机 |
---
## 总结
BarcodeEditor 类的整体健壮性较好,主要问题仅有一个:
**`applyCounterConfigToSysPara()` 中 `m_sysPara->devOp` 无 null 检查**,与先前 PrintSetting 报告中发现的同类问题相同,属于 `SysPara` 中 `devOp` 指针使用的普遍模式缺陷。
---
## 生成时间
2026-06-29