Scene 模块健壮性更新说明
概述
本文档针对 scene/ 目录下所有类进行健壮性审查,识别出以下几类典型问题:
- 外部参数输入未校验 — 公共方法接收指针、索引、容器等参数时缺少有效性检查
- 空指针解引用风险 — 存储的原始指针在使用前未做 null 检查
- 数组/容器越界访问 — 使用索引访问 QVector/QMap 时未验证边界
- 缺少错误处理 — 文件操作、类型转换等缺少失败路径处理
- 类型安全问题 — QVariant 类型擦除后未做类型校验
各类问题详细清单
1. BarcodeEditor
| 文件 |
问题 |
严重程度 |
建议修复 |
| BarcodeEditor.h/cpp |
bindSysPara(SysPara*) 未校验 nullptr |
高 |
入口处添加 if (!sysPara) return; 并记录日志 |
| BarcodeEditor.cpp |
applyCounterConfigToSysPara() 直接解引用 m_sysPara 无 null 检查 |
高 |
使用前添加 Q_ASSERT(m_sysPara); if (!m_sysPara) return; |
| BarcodeEditor.cpp |
bindViewModel() 中 format 字段通过 QVariant::value<T>() 取值,无类型校验 |
中 |
使用 canConvert<T>() 先行判断 |
| BarcodeEditor.cpp |
计数器相关逻辑中 counterValues 索引访问无边界检查 |
高 |
访问前检查 counterValues.size() >= 2 |
2. CounterEditor
| 文件 |
问题 |
严重程度 |
建议修复 |
| CounterEditor.cpp |
bindSysPara(SysPara*) 未校验 nullptr |
高 |
入口处添加空指针检查 |
| CounterEditor.cpp |
计数器参数(步长、初始值、最大值)未做范围校验 |
中 |
添加数值范围合法性检查(如步长不为0,最大值>最小值) |
| CounterEditor.cpp |
UI 控件取值后直接使用,未校验转换是否成功 |
低 |
toInt() 等调用使用带 ok 参数的重载 |
3. DateFormatEditor
| 文件 |
问题 |
严重程度 |
建议修复 |
| DateFormatEditor.cpp |
setDateModel(const DateItemModel&) 未校验 model 内部容器是否为空 |
中 |
检查关键 map 的 size 是否满足预期 |
| DateFormatEditor.cpp |
日期偏移量输入未做范围限制 |
低 |
限制偏移量在合理范围内(如 ±9999) |
4. DateReplaceEditor
| 文件 |
问题 |
严重程度 |
建议修复 |
| DateReplaceEditor.cpp |
onLineEditReplaceChanged(int i, QString txt) 中 mapIdx 可能为负值 |
中 |
添加 if (mapIdx < 0) return; |
| DateReplaceEditor.cpp |
on_cb_replaceType_currentIndexChanged(int index) 未校验 index 范围 |
低 |
添加 `if (index < 0 |
| DateReplaceEditor.cpp |
分页逻辑中 currPage 无上下界保护 |
中 |
翻页时 clamp 到 [0, maxPage] |
5. DlgBarcodeFormat
| 文件 |
问题 |
严重程度 |
建议修复 |
| DlgBarcodeFormat.cpp |
条码类型索引直接映射到枚举,无范围校验 |
中 |
添加枚举范围检查 |
| DlgBarcodeFormat.cpp |
条码内容长度未做上限校验 |
中 |
根据条码类型限制最大长度 |
6. DlgQrcodeFormat
| 文件 |
问题 |
严重程度 |
建议修复 |
| DlgQrcodeFormat.cpp |
二维码内容长度未做上限校验 |
中 |
限制输入长度(QR Code 最大约 4296 字符) |
| DlgQrcodeFormat.cpp |
纠错等级索引未校验 |
低 |
确保 index 在 0-3 范围内 |
7. ItemCommon
| 文件 |
问题 |
严重程度 |
建议修复 |
| ItemCommon.cpp |
generateTxtFromDateItemModel 中 monthsMap[month-1]、daysMap[day-1]、hoursMap[hour]、weeksMap[dayOfWeek-1] 均无边界检查 |
高 |
访问前检查 map/list 的 size 是否足够 |
| ItemCommon.cpp |
generateTxtFromBarcodeViewModel 中 counterValues[0]/[1] 无 size 检查 |
高 |
添加 if (counterValues.size() < 2) return QString(); |
| ItemCommon.cpp |
日期格式解析中未处理无效 datetime 的情况 |
中 |
检查 QDateTime::isValid() |
8. ItemGeneralSettings
| 文件 |
问题 |
严重程度 |
建议修复 |
| ItemGeneralSettings.cpp |
bindItem(QGraphicsItem*) 未校验 nullptr |
高 |
入口处添加空指针检查 |
| ItemGeneralSettings.cpp |
坐标/尺寸输入未做负值或零值校验 |
中 |
宽高不允许为0或负数 |
| ItemGeneralSettings.cpp |
dynamic_cast 结果未检查 |
中 |
转换后检查是否为 nullptr |
9. picscene (PicScene)
| 文件 |
问题 |
严重程度 |
建议修复 |
| picscene.cpp |
多处 dynamic_cast 后直接使用结果,未检查 nullptr |
高 |
每次 dynamic_cast 后添加 null 检查 |
| picscene.cpp |
addItem 系列方法中传入的参数(如文本内容、位置坐标)未校验 |
中 |
校验坐标在场景范围内,文本非空 |
| picscene.cpp |
场景 item 列表遍历中假设 item 类型,未做防御性检查 |
中 |
遍历时使用 qgraphicsitem_cast 并检查结果 |
| picscene.cpp |
文件读写操作缺少错误处理(如文件打开失败) |
中 |
检查 QFile::open() 返回值 |
10. piccodeitem (PicCodeItem)
| 文件 |
问题 |
严重程度 |
建议修复 |
| piccodeitem.cpp |
updateVariants(QVector<int> counters) 未校验 counters.size() >= 2 |
高 |
添加 if (counters.size() < 2) return defaultImage; |
| piccodeitem.cpp |
setBarcodeViewModel(const BarcodeViewModel& vm) 未校验 vm 字段有效性 |
中 |
检查 vm.type 和 vm.contentPattern 非空 |
| piccodeitem.cpp |
setSource(QVariant var) 参数被完全忽略 |
低 |
添加注释说明或移除无用参数 |
11. PicCounterItem
| 文件 |
问题 |
严重程度 |
建议修复 |
| PicCounterItem.cpp |
updateVariants(QVector<int> counters) 未校验容器大小 |
高 |
同 piccodeitem |
| PicCounterItem.cpp |
计数器溢出未处理(超过最大值后的行为) |
中 |
添加溢出保护逻辑 |
12. PicDateItem
| 文件 |
问题 |
严重程度 |
建议修复 |
| PicDateItem.cpp |
setDateModel(const DateItemModel&) 未校验 model 内部 map 完整性 |
高 |
检查各 map 的 size 满足最低要求 |
| PicDateItem.cpp |
日期替换表访问无边界保护 |
高 |
同 ItemCommon 中的修复 |
13. PicImageItem
| 文件 |
问题 |
严重程度 |
建议修复 |
| PicImageItem.cpp |
setSource(QVariant var) 未校验 QVariant 类型 |
低 |
使用 var.canConvert<QString>() 判断 |
| PicImageItem.cpp |
setCustomAttrs 未检查 "source" 属性是否存在 |
低 |
添加 attrs.contains("source") 检查 |
| PicImageItem.cpp |
图片加载失败无日志输出 |
低 |
添加 qWarning() 日志 |
14. PicScheduleShiftItem
| 文件 |
问题 |
严重程度 |
建议修复 |
| PicScheduleShiftItem.cpp |
findScheduleName() 存在不可达代码 |
低 |
清理逻辑 |
| PicScheduleShiftItem.cpp |
itemImage() 中存在未赋值的 QImage 返回路径 |
中 |
确保所有分支都有有效返回 |
15. pictextitem (PicTextItem)
| 文件 |
问题 |
严重程度 |
建议修复 |
| pictextitem.cpp |
文本内容设置未做长度上限校验 |
低 |
根据打印能力限制最大字符数 |
| pictextitem.cpp |
字体大小设置未做合理范围校验 |
低 |
限制在合理范围(如 1-999) |
16. ViewModels
| 文件 |
问题 |
严重程度 |
建议修复 |
| ViewModels.cpp |
makeCounterVM(SysPara*, ...) 接收指针但部分路径未检查 null |
中 |
统一在入口处检查 |
| ViewModels.cpp |
ViewModel 构造时未校验字段合法性 |
低 |
添加工厂方法中的断言 |
17. ScheduleShiftsEditor
| 文件 |
问题 |
严重程度 |
建议修复 |
| ScheduleShiftsEditor.cpp |
班次时间输入未校验逻辑合理性(如结束时间>开始时间) |
中 |
添加时间区间合法性校验 |
| ScheduleShiftsEditor.cpp |
班次数量未做上限限制 |
低 |
限制最大班次数 |
18. myview / sceneviewwidget
| 文件 |
问题 |
严重程度 |
建议修复 |
| myview.cpp |
缩放因子未做范围限制 |
低 |
限制在合理范围(如 0.1 ~ 10.0) |
| sceneviewwidget.cpp |
setScene(PicScene*) 未校验 nullptr |
中 |
添加空指针检查 |
修复优先级建议
P0 — 立即修复(可能导致崩溃)
- 所有
bindSysPara(SysPara*) 调用处 — 添加 nullptr 检查
ItemCommon::generateTxtFromDateItemModel — 所有 map 索引访问添加边界检查
ItemCommon::generateTxtFromBarcodeViewModel — counterValues size 检查
PicCodeItem::updateVariants — counters 容器大小校验
picscene.cpp 中所有 dynamic_cast — 添加 null 检查
P1 — 尽快修复(可能导致数据错误)
- DateReplaceEditor 分页索引保护
- 条码/二维码内容长度限制
- ItemGeneralSettings 中
dynamic_cast 结果检查
- PicDateItem 日期替换表边界保护
- ScheduleShiftsEditor 时间区间合法性校验
P2 — 后续优化(改善代码质量)
- QVariant 类型安全检查
- 日志输出完善
- 无用参数清理
- 数值输入范围限制
修复模式参考
模式 A:指针参数校验
模式 B:容器索引边界检查
模式 C:Map 访问保护
模式 D:dynamic_cast 安全使用
模式 E:数值范围校验
实施计划
- 第一阶段:修复所有 P0 问题(防崩溃)
- 第二阶段:修复所有 P1 问题(防数据错误)
- 第三阶段:完成 P2 优化(代码质量提升)
每个阶段修复后需进行编译验证和基本功能回归测试。