暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

(C)使用fread函数读取文件时请注意

ERGOisTESTING 2019-02-02
838

【背景】

    同一脚本,剧情发展,点击链接跳转查看:

  1. 【LR】从文件读取内容作为参数

  2. 【LR脚本】webservice返回base64密文处理案例一则

  3. 【LR脚本】自定义函数中的字符串拼接与局部变量参数化

    表面看来是这个原因(下图,截图自上文3),最后分析完发现真相差得有点远……



【排查过程】

STEP1、缺陷暴露与初步观察

    读取1000kb以上文件发送报文,接口返回“解密异常”,初步怀疑发出去的密文不完整导致,首先想到的是文件太大。于是试了一个136bk大小的密文读取发送,可以成功提交。又试了一个137kb大小的密文发送,返回“解密异常”。

    试了其他几份136kb与137kb的文件都是一样的情况,136kb提交成功,137kb返回解密异常,推测136kb/137kb之间存在一个过度值。难道是字符指针变量大小存在某种限制?可是在网上搜索了一下,不管是136kb还是137kb在计算机领域来说并不是一个有特殊意义的值……

    当然最大的前提就是这些136kb和137kb的文件如果通过soapUI发出都能正常提交成功,排除文件本身原因。


STEP2、将缺陷定位至自定义函数testfn()

    在Action()中将用于存放读取文件后的字符指针变量打印出来,返回为“解密异常”的报文,提交时确实漏了最后一部分数据内容。

    需要确定是否在文件读取时就没有将这部分内容读进来,于是在自定义函数testfn()中输出读取的文本长度与文本内容。

    结果确实是读取的时候就已经丢失了后面部分的内容。这样就将返回缩小到了自定义函数,即便真的是变量或者内存大小的问题,也只发生在该区域内。


STEP3、将缺陷定位至fread函数

    考虑到136kb这个值没有什么特殊意义,大胆推测下这个137kb的限制只是一个巧合。最终通过以下两项尝试验证了这个假设:

    ①另找一份500kb文件断读处已大于137kb;

    ②扩大字符指针的内存大小(原始设定为文件大小),未能因此将多余的1kb读进;

    再将目光转向用于文件读取的fread函数,先看下函数结构:

size_t   fread(   void   *buffer,   size_t   size,   size_t   count,   FILE   *stream   ) 

fread(buffer, sizeof(char), filelenth, file_stream);

    buffer是读取内容存放指针;size是每次读取大小,这里的值是sizeof(char),即为1;count是读取次数,沿用了之前的文件大小变量filelenth;stream是要读取得文件指针,使用了前文定义的文件开始位置值file_stream。

    给函数赋值的变量取值似乎没什么问题,假设是这个函数本身有问题。在网上查询这个函数资料时,不难了解到一种评论“fread可以读二进制文件,有时用字符方式去读文件不能读完整个文件,但是二进制方式就可以”,可以说看到这里就是柳暗花明了……


STEP4、缺陷修复

    系统系统默认文件结束符为ctrl+z,其ASCII值为“0x1A”,fread函数遇到这个字符串时自动结束文件读取。回头看看那些文件中断点,やっぱり!

    改成以二进制读取即可避免这个问题

file_stream = fopen(filename, "r")改成

file_stream = fopen(filename, "rb")

    r是以只读方式打开,rb是以二进制只读方式打开。换成rb后果然没毛病了,一口气读1MB不喘气,yooooo~~~

我真是个机智的狗儿~



【结语】

    如果我对fread函数有足够的了解,可能一眼就能看出症结所在,不过现在这样也好,从实践反推理论和,记忆深刻……

    这个脚本前后陆续撸了快一周了,到这个bug修复差不多应该结束了,跟出连续剧似的……




↓↓扫一扫,防脱发↓↓


文章转载自ERGOisTESTING,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论