开发笔记之:文件读取值溢出bug分析(QT C++版)

news2025/1/12 15:59:05

(1)引言

 以下是QT C++读取数据文件(QDataStream)的代码:

/**
 * 按双字读取
 * @param fis						文件输入流
 * @param isBigEndian				是否大头(字节序)
 * @return				双字值
 */
DWORD FsFileUtil::readAsDword(QDataStream &fis, const bool isBigEndian) {
    BYTE byte1 = -1, byte2 = -1, byte3 = -1, byte4 = -1;
    DWORD val = -1;

    fis >> byte1 >> byte2 >> byte3 >> byte4;

    //EoF checking
    if((-1 == byte4)||(-1 == byte3)||(-1 == byte2)||(-1 == byte1)) {
        return (-1);
    }
    if(isBigEndian) {
        val = ((byte1 << 24)|(byte2 << 16)|(byte3 << 8)|byte4);
    } else {
        val = ((byte4 << 24)|(byte3 << 16)|(byte2 << 8)|byte1);
    }
    return (val);
}

 其意图很简单:从当前游标位置读取一个双字(4字节)数据。
稍微复杂一点的就是一个字节序的考虑。

(2)问题

 该代码做UT(单元测试)时,遇到了读取无法中断(就是读起来没完没了)。以下是数据文件内容:
数据文件sample中断的原因就是一直没有获取到约定的 EOF(-1)。
经调试跟踪,在读取完毕后,函数的返回值还是 4,294,967,2950xFFFFFF),没有返回 -1
经查,QDataSteam的 >> 即便读取到文件末尾了,也不会返回 -1,而需要使用方法 atEnd 来判定。

(2.1)对策一

将判断 EOF的语句修改为:

//EoF checking
if(fis.atEnd()) {
    return (-1);
}

再次调试,则判定文件末尾正常,但函数还是不会返回 -1。其原因是函数返回值类型是无符号型 DWORD
-1 的DWORD值是0xFFFFFF

(2.2)对策二

将函数的返回值类型扩展为带符号型 int64。即:

int64 FsFileUtil::readAsDword(QDataStream &fis, const bool isBigEndian) {
    BYTE byte1 = -1, byte2 = -1, byte3 = -1, byte4 = -1;
    int64 val = -1;

再次调试,遇到了读取中断的问题(就是文件还没读取完就提前中断了)。
经调试跟踪,在读取第1个 0xFFFFFF 时,每个字节的读取都正常(255),问题发生在代码的 return 语句处,返回 -1值了:

val = ((byte1 << 24)|(byte2 << 16)|(byte3 << 8)|byte4);

问题也秒了,无符号类型计算转换为带符号类型时,发生了值溢出。

(2.3)对策三

返回值val需要扩展,要不用带符号类型int64,在值计算时把值强制扩展为int64;
或者用无符号类型DWORD。即:

int64 FsFileUtil::readAsDword(QDataStream &fis, const bool isBigEndian) {
    BYTE byte1 = -1, byte2 = -1, byte3 = -1, byte4 = -1;
    int64 val = -1;
    。。。
    val = (((int64)byte1 << 24)|((int64)byte2 << 16)|((int64)byte3 << 8)|(int64)byte4);

或者:

int64 FsFileUtil::readAsDword(QDataStream &fis, const bool isBigEndian) {
    BYTE byte1 = -1, byte2 = -1, byte3 = -1, byte4 = -1;
    DWORD val = -1;
    。。。
    val = (((DWORD)byte1 << 24)|((DWORD)byte2 << 16)|((DWORD)byte3 << 8)|(DWORD)byte4);

相比之下,第1种方案的可读性要好一些。

(3)结论

数据文件读取需关注的点:

  1. 判定是否到达文件末尾(End of File)的方式
  2. 目标的值域范围(宁大勿小)
  3. 无符号类型与带符号类型之间的转换
(4)相关文档
  1. 开发笔记之:文件读取值溢出bug分析(JAVA版)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/541278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么用问卷工具做市场调研?

对于希望开发新产品或服务、拓展新市场或确定潜在客户的公司来说&#xff0c;市场调查是一个至关重要的过程。然而&#xff0c;进行市场调查可能既耗时又昂贵&#xff0c;特别是在涉及对大量人群进行调查的情况下。今天&#xff0c;小编将来聊一聊调查问卷工具如何帮助企业进行…

微信小程序-基础知识

文章目录 AppIdOpenIDUnionId处理方法session_key AppId appid 是微信账号的唯一标识&#xff0c;这个是固定不变的&#xff1b; 如果了解微信公众号开发的就需要注意一下&#xff0c;小程序的appid 和 公众号的appid 是不一致的 OpenID 为了识别用户&#xff0c;每个用户针…

如何成为自动化测试工程师?8年测试总结,自动化测试岗晋升的技能...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Python自动化测试&…

程序设计入门——C语言2023年5月18日

程序设计入门——C语言 第二周 计算表达式 课程来源&#xff1a;链接: 浙江大学 翁恺 程序设计入门——C语言 学习日期&#xff1a;2023年5月18日 第二周 计算 表达式 有两个变量a和b&#xff0c;交换a和b的值。 老师举例&#xff1a;有两杯液体&#xff0c;一杯茶&#xff…

03)FastDFS配置nginx 服务,使用http方式访问图片

FastDFS是没有文件访问功能的,需要借助其他工具实现图片HTTP访问的。 没安装nginx时比如前端html网页想获取 FastDFS的一张图片显示,需要java写个controller,然后使用 FastDFS-java client客户端调用文件获取api,HttpServletResponre在返回图片流.给前端显示。 安装了nginx…

HTTP介绍、原理

HTTP 与 HTTPS 有哪些区别&#xff1f; HTTP 是超文本传输协议&#xff0c;信息是明文传输&#xff0c;存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷&#xff0c;在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议&#xff0c;使得报文能够加密传输。HTTP 连接建立相…

带头 双向 循环 链表——C语言实现

既然有带头 那么就有不带头 为什么我要将带头 而不讲不带头&#xff1f; 在之前我讲单链表时就说过 如果不带头会出现讨论的情况 为什么会出现讨论的情况 假设链表有一个节点 进行尾插 就只是将新的节点连接到链表的尾节点之后 那么如果链表没有节点 就没有尾节点 自然也就不能…

网络编程 (一)网络协议TCP,UDP

文章目录 &#x1f412;个人主页&#x1f3c5;JavaSE系列专栏&#x1f4d6;前言&#xff1a;&#x1f380;计算机网络概述&#x1f380;网络编程&#x1f380;那么是如何精确找到计算机网络中的目标主机呢&#xff1f;&#x1f380;网络模型&#x1f380;TCP协议&#x1f380;U…

GitLAB CI-CD语法

GitLAB CI-CD语法 目录 1、Pipeline核心语法 gitlab-ci语法&#xff1a; https://docs.gitlab.com/ee/ci/yaml/ stages 阶段控制 .pre阶段的作业总是在流水线开始时执行&#xff1b;.post阶段的作业总是在流水线结束时执行&#xff1b; CI代码&#xff1a; stages:- build…

Servlet的详解

Servlet 的主要工作 允许程序员注册一个类&#xff0c;在 Tomcat 收到的某个特定的 HTTP 请求的时候&#xff0c;执行这个类中的一些代码 帮助程序员解析 HTTP 请求&#xff0c;把 HTTP 请求从一个字符串解析成一个 HttpRequest 对象 帮助程序员构造 HTTP 响应&#xff0c;程序…

用 CSS 自定义滚动条

简介 首先需要介绍一下滚动条的组成部分。滚动条包含 track 和 thumb&#xff0c;如下图所示&#xff1a; track是滚动条的基础&#xff0c;其中的 thumb是用户拖动支页面或章节内的滚动。 案例&#xff1a; 案例代码&#xff1a; <!DOCTYPE html> <html><he…

python 递归下降分析法的设计与实验原理 编译原理

本文内容&#xff1a; 本文章实现的文法&#xff1a; E->T|ET; T->F|T*F; F->i|(E);利用上一篇文章&#xff1a;python 预备实验2 LL(1)文法构造转化后的输出&#xff1a; E->TE; T->FT; F->i|(E); E->TE|; T->*FT|; 手工测试&#xff0c;是LL(1)文…

Flink+Pulsar、Kafka问题分析及方案 -- 事务阻塞

Pulsar、Kafka的事务设计 Pulsar跟Kafka在设计事务功能时&#xff0c;在消费者读取消息的顺序方面&#xff0c;都采用了类似的设计。 比如说&#xff0c;先创建txn1&#xff0c;然后创建txn2&#xff0c;这两个事务生产消息到同一个topic/partition里&#xff0c;但是txn2比tx…

【前端知识】常见的加密算法介绍

【前端知识】常见的加密算法介绍 1 常见的加密算法&#xff08;1&#xff09;哈希函数&#xff08;2&#xff09;对称加密&#xff08;3&#xff09;非对称加密&#xff08;4&#xff09;消息认证码&#xff08;MAC&#xff09; 2.总结 1 常见的加密算法 略微介绍一下前端中常…

Kerberos

序言 kerberos 除了说帮我们验证Java程序是否具有权限来请求Hadoop的服务,也可以来帮助我们检查新增的节点是是否是真实的节点,还是黑客为了套取数据的节点. 比如为HDFS新增一个DataNode节点,如果没有Kerberos验证, 随便一个节点只要连接上NameNode就会存储数据,黑客就可以获…

LeetCode:23. 合并 K 个升序链表

23. 合并 K 个升序链表 1&#xff09;题目2&#xff09;过程3&#xff09;代码1. 最开始2.初步优化 4&#xff09;结果1. 最开始2. 初步优化 1&#xff09;题目 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合…

机器学习基础认识(一)

机器学习应用 机器学习的应用&#xff0c;主要分为两类&#xff1a;预测、分类 预测&#xff0c;一般是指&#xff1a;根据数据&#xff0c;预测数值 分类&#xff0c;一般是指&#xff1a;根据数据&#xff0c;进行分类 预测与分类的关系【个人理解】 分类&#xff0c;本质…

零基础怎么入门网络安全?看这篇就够啦!

由于我之前写了不少网络安全技术相关的故事文章&#xff0c;不少读者朋友知道我是从事网络安全相关的工作&#xff0c;于是经常有人在微信里问我&#xff1a; 我刚入门网络安全&#xff0c;该怎么学&#xff1f;要学哪些东西&#xff1f;有哪些方向&#xff1f;怎么选&#xff…

Centos7.6部署postgresql15主从

目录 安装pg15&#xff08;master和standby&#xff09;主数据库配置(master)初始化数据库创建归档日志目录设置数据库访问权限修改数据库配置文件开启数据库 从数据库配置(standby)同步主库的数据文件创建文件standby.signal启动从数据库 主从状态验证master上验证standby上验…

H5性能测试怎么做?这些关键指标你得搞清楚

目录 01、Http相关 02、组件是否压缩 03、图片格式和大小是否合适 04、CSS放在顶部 05、JS放在底部 06、JS &CSS压缩 07、是否添加缓存 08、避免非200返回值 09、使用CDN 03、WebView相关 学习资源分享 软件测试面试小程序 01、Http相关 01、Http请求个数 有…