Files
VX5_KRO_GearPump/doc/scene模块健壮性更新.md
T
2026-05-23 14:16:57 +08:00

11 KiB
Raw Blame History

Scene 模块健壮性更新说明

概述

本文档针对 scene/ 目录下所有类进行健壮性审查,识别出以下几类典型问题:

  1. 外部参数输入未校验 — 公共方法接收指针、索引、容器等参数时缺少有效性检查
  2. 空指针解引用风险 — 存储的原始指针在使用前未做 null 检查
  3. 数组/容器越界访问 — 使用索引访问 QVector/QMap 时未验证边界
  4. 缺少错误处理 — 文件操作、类型转换等缺少失败路径处理
  5. 类型安全问题 — 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 — 立即修复(可能导致崩溃)

  1. 所有 bindSysPara(SysPara*) 调用处 — 添加 nullptr 检查
  2. ItemCommon::generateTxtFromDateItemModel — 所有 map 索引访问添加边界检查
  3. ItemCommon::generateTxtFromBarcodeViewModel — counterValues size 检查
  4. PicCodeItem::updateVariants — counters 容器大小校验
  5. picscene.cpp 中所有 dynamic_cast — 添加 null 检查

P1 — 尽快修复(可能导致数据错误)

  1. DateReplaceEditor 分页索引保护
  2. 条码/二维码内容长度限制
  3. ItemGeneralSettings 中 dynamic_cast 结果检查
  4. PicDateItem 日期替换表边界保护
  5. ScheduleShiftsEditor 时间区间合法性校验

P2 — 后续优化(改善代码质量)

  1. QVariant 类型安全检查
  2. 日志输出完善
  3. 无用参数清理
  4. 数值输入范围限制

修复模式参考

模式 A:指针参数校验

// 修复前
void BarcodeEditor::bindSysPara(SysPara *sysPara)
{
    m_sysPara = sysPara;
}

// 修复后
void BarcodeEditor::bindSysPara(SysPara *sysPara)
{
    if (!sysPara) {
        qWarning() << "BarcodeEditor::bindSysPara: null pointer passed";
        return;
    }
    m_sysPara = sysPara;
}

模式 B:容器索引边界检查

// 修复前
auto val = m_currCounterValues[0];

// 修复后
if (m_currCounterValues.size() < 2) {
    qWarning() << "counterValues size insufficient:" << m_currCounterValues.size();
    return QImage();
}
auto val = m_currCounterValues[0];

模式 C:Map 访问保护

// 修复前
result.replace("{M}", model.monthsMap[month - 1]);

// 修复后
if (month - 1 >= 0 && month - 1 < model.monthsMap.size()) {
    result.replace("{M}", model.monthsMap[month - 1]);
} else {
    qWarning() << "monthsMap index out of range:" << month - 1;
}

模式 D:dynamic_cast 安全使用

// 修复前
auto* textItem = dynamic_cast<PicTextItem*>(item);
textItem->setText(content);

// 修复后
auto* textItem = dynamic_cast<PicTextItem*>(item);
if (!textItem) {
    qWarning() << "dynamic_cast to PicTextItem failed";
    return;
}
textItem->setText(content);

模式 E:数值范围校验

// 修复前
void ItemGeneralSettings::setWidth(int w)
{
    item->setWidth(w);
}

// 修复后
void ItemGeneralSettings::setWidth(int w)
{
    if (w <= 0 || w > MAX_ITEM_WIDTH) {
        qWarning() << "Invalid width:" << w;
        return;
    }
    item->setWidth(w);
}

实施计划

  1. 第一阶段:修复所有 P0 问题(防崩溃)
  2. 第二阶段:修复所有 P1 问题(防数据错误)
  3. 第三阶段:完成 P2 优化(代码质量提升)

每个阶段修复后需进行编译验证和基本功能回归测试。