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

news2024/11/22 16:53:16

(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. 开发笔记之:文件读取溢出分析(JAVA版)

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

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

相关文章

工欲善其事必先利其器——开发神器(IDEA)

&#x1f525;IDEA 简介&#x1f525;IDEA的特色功能&#x1f525;IDEA的优点&#x1f525;IDEA 的使用&#x1f525;IDEA的常用快捷键 &#x1f525;IDEA 简介 IDEA 全称 IntelliJ IDEA&#xff0c;是 java 编程语言开发的集成环境&#xff0c;被公认为最好的 java 开发工具之…

如何轻松搭建一套行情回放系统

一个量化策略在生产&#xff08;交易&#xff09;环境中运行时&#xff0c;实时数据的处理通常是由事件驱动的。为确保研发和生产使用同一套代码&#xff0c;通常在研发阶段需将历史数据&#xff0c;严格按照事件发生的时间顺序进行回放&#xff0c;以此模拟交易环境。在 Dolph…

ChatGPT 提问,软件杂项部分

堆内存与栈内存一般分别 有多少 ChatGPT 堆内存和栈内存的大小取决于操作系统和编译器的限制以及程序的运行环境。以下是一些常见的默认大小范围&#xff0c;但请注意这些值可以因环境而异&#xff1a; 栈内存大小&#xff1a; Windows平台&#xff1a;默认情况下&#xff…

vue3 大致总结

一、开发、生产、测试环境的文件编写 需要以VITE开头&#xff01;&#xff01;&#xff01; 输出时&#xff1a;console.log(import.meta.env.VITE_ENV,"------***---------"); 二、路由守卫 1、全局路由守卫beforeEach和afterEach ①全局前置守卫beforeEach ②…

六、达梦8数据库适配记录

达梦数据库适配记录 记录关于我的业务微服务,适配国产达梦数据库的过程,以及遇到的一些错误问题和其解决方案。 目前的项目最初基于Mysql开发,现在要适配到达梦,不要以为迁移任务很easy,但实际过程中还是出现了很多问题。 基 由于达梦是的国产数据库,本身与MySQL数据库…

idea配置阿里云翻译

idea配置阿里云翻译 0前言1开通阿里云机器翻译2配置阿里云AccessKeyidea配置Translation 0前言 使用idea的码农们都应该对Translation这款插件不会陌生了&#xff0c;尤其是英语基础比较薄弱的盆友&#xff0c;在看源码的时候更是会经常使用Translation边翻边看源码。 但是由于…

EW代理工具的使用说明

一、EW介绍 Earthworm&#xff08;EW&#xff09; 是一套便携式的网络穿透工具&#xff0c;具有 SOCKS v5服务架设和端口转发两大核心功能&#xff0c;可在复杂网络环境下完成网络穿透。 该工具能够以“正向”、“反向”、“多级级联”等方式打通一条网络隧道&#xff0c;直达…

基于REST风格的SpringMVC请求路径设置与参数传递

文章目录 1 REST简介2 RESTful入门案例2.1 环境准备2.2 思路分析2.3 修改RESTful风格新增删除传递路径参数 修改根据ID查询查询所有 知识点1&#xff1a;PathVariable 3 RESTful快速开发知识点1&#xff1a;RestController知识点2&#xff1a;GetMapping PostMapping PutMappin…

【STL】

目录 什么是STLSTL定义两大特点两个层次 STL主要构成容器容器概念容器分类vectordequestackqueuelistset/multiset容器map/multimap容器 算法迭代器仿函数适配器空间配置器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插…

选Ubuntu 还是 Fedora ?

提起开发&#xff0c;程序员们更青睐于不同版本的Linux操作系统而不是Windows。 为什么&#xff1f;因为Linux操作起来更安全、快捷&#xff0c;最重要的是&#xff0c;它的发行版本众多。你可以根据需要挑选最适合的那一款。那么&#xff0c;问题来了&#xff0c;到底哪个版本…

开源地质建模GemPy实战

推荐&#xff1a;用 NSDT设计器 快速搭建可编程3D场景。 在设计任何类型的工程结构时&#xff0c;确定地面以下的东西并有效地将其映射出来是首要也是最重要的部分之一。 地下建模带有很大的误差范围&#xff0c;因为即使是我们今天使用的最先进的地下调查方法也无法完全绘制出…

【Linux】信号概述

目录 1、信号概念2、Linux常用信号表3、信号的5种默认处理动作 橙色 1、信号概念 信号是 Linux进程间通信的最古老的方式之一&#xff0c;是事件发生时对进程的通知机制&#xff0c;有时也称之为软件中断&#xff0c;它是在软件层次上对中断机制的一种模拟&#xff0c;是一种…

Vue3(6) Transition

目录 组件 基于CSS的过渡效果 JavaScript钩子 Vue 提供了两个内置组件&#xff0c;可以帮助你制作基于状态变化的过渡和动画&#xff1a; <Transition> 会在一个元素或组件进入和离开 DOM 时应用动画。 <TransitionGroup> 会在一个 v-for 列表中的元素或组件被…

C++模板template

我们现在有几个变量&#xff0c;我们向要实现他们的交换&#xff0c;所以我们现在写了一个swap函数 我们现在可以实现对这两个变量之间的交换&#xff0c; 那么我们有有两个变量需要交换呢&#xff1f;&#xff1f; 我们刚才的Swap函数的参数是int类型的&#xff0c;我们现在的…

ChatGPT 和对话式 AI 的未来:2023 年的进展和应用

人工智能(Artificial Intelligence)在过去一段时间以来以前所未有的速度快速发展。从自动化日常任务到重要提醒的设定,AI以各种方式渗透到我们的生活中。然而,在这个领域中迈出的最重要一步是ChatGPT。 ChatGPT被瑞银(UBS)评为“有史以来增长最快的消费者应用程序”,于…

Cy5.5-PEG-SH近红外荧光PEG试剂 Cyanine5.5-PEG-SH,Thiol-PEG-Cy5.5可用于活体成像

Cy5.5-PEG-SH &#xff0c;Cy5.5聚乙二醇巯基 英文名称&#xff1a;Cy5.5-PEG-SH 中文名称&#xff1a;Cy5.5聚乙二醇巯基 性状: 深蓝色固体或粘性液体&#xff0c;取决于分子量 溶剂&#xff1a;溶于水、 DMSO等常规性有机溶剂 激发/发射波长&#xff1a;684 nm/710 nm …

Windows操作系统重要内容

windows 常用用户&#xff1a; SYSTEM&#xff1a;本地机器上拥有最高权限的用户。&#xff08;为系统核心组件访问文件资源提供权限&#xff09;Administrator&#xff1a;默认系统管理员用户。Guest&#xff1a;只拥有相对较少的权限&#xff0c;默认被禁用。 Windows 常见…

【中医推荐】33部中医书籍,中医医书精品(在线免费阅读),值得珍藏的国粹,涵盖中药、针灸、推拿、按摩、拔罐、气功,食疗等诸多领域

中医诞生于原始社会&#xff0c;春秋战国时期中医理论已基本形成&#xff0c;之后历代均有总结发展。除此之外对汉字文化圈国家影响深远&#xff0c;如日本医学、韩国韩医学、朝鲜高丽医学、越南东医学等都是以中医为基础发展起来的。 中医承载着中国古代人民同疾病作斗争的经…

(华三AC+AP)在华三AC上通过用户mac地址或者IP地址查询在那一台AP下

起因&#xff1a;用户终端的WiFi信号一直不停地断开重连&#xff0c;发现AP的信号消失了&#xff0c;经过检查配置并没有问题&#xff0c;但是在后来发现重启可以让AP恢复使用&#xff0c;但是过一段时间还是会出现这样的问题&#xff0c;因为AP没有备用换下维修&#xff0c;这…

只需浏览器!在线完成Flutter从编程到打包全过程

本文作者&#xff1a;林梓泓 引言 云端 IDE 是基于云的集成开发环境&#xff0c;开发人员可以远程编写运行和调试代码&#xff0c;无需本地安装&#xff0c;仅通过浏览器即可开发软件。 与传统本地开发相比&#xff0c;云端开发环境主要有以下的优势&#xff1a; 快速启动项…