能力值:
( LV2,RANK:10 )
|
-
-
2 楼
quicklz
http://www.quicklz.com/
|
能力值:
(RANK:1130 )
|
-
-
3 楼
|
能力值:
( LV3,RANK:20 )
|
-
-
4 楼
多谢LS两位,我测试看看。。。
|
能力值:
( LV3,RANK:20 )
|
-
-
5 楼
现在用到这压缩库了,测试结果如下:
********************************************
CPU:Intel T7300
原始文件:魔盗.txt 4.31M
quicklz: 开启QLZ_MEMORY_SAFE,压缩后2.50M
压缩100次 3.2s
解压100次 3.4s
zlib: 最快压缩Z_BEST_SPEED方式,压缩后1.93M
压缩100次 19.0s
解压100次 4.6s
aplib: 貌似没有参数控制压缩等级,压缩后1.73M
压缩1次 10.0s -_-b
解压1次 ??.?s 压缩实在是太慢了,测试解压没有任何意义
********************************************
quicklz真是快啊,非常好,可惜我感觉解压函数不安全,解压函数的原型是
qlz_decompress(const char *source, void *destination, char *scratch_decompress);
它没有指定源的长度,这样如果精心构造原数据,即使有QLZ_MEMORY_SAFE存在也可以让程序越界访问,甚至可能导致程序挂掉。
比如可以假设某块数据压缩后占用100个字节,我用VirtualAlloc分配0x2000个字节的内存,将后0x1000的页面用VirtualProtect修改为不可访问,最后将这100个字节的前99个字节复制到0x1000 - 99的地址上去(即在前一块的末尾),然后将这个地址作为source参数,那么程序必挂,因为它必定要访问到第100个字节才能判断数据是否合法,但现在这个数据处于不可访问页面中。
虽然在正常应用中即使越界访问,问题也未必会这么严重,但是存在越界访问的可能性本身就是不允许的,特别是在“原数据是网络传输的数据”的情况下。
如果解压函数有传入原数据长度的方法就好办了
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
c = qlz_size_compressed(file_data); fread(file_data + 9, 1, c - 9, ifile); d = qlz_decompress(file_data, decompressed, scratch); printf("%u bytes decompressed into %u.\n", (unsigned int)c, (unsigned int)d); fwrite(decompressed, d, 1, ofile);
看了下例子 有个 qlz_size_compressed 函数返回解压后长度
|
能力值:
( LV3,RANK:20 )
|
-
-
7 楼
qlz_size_decompressed返回解压后的长度,qlz_size_compressed返回压缩后的长度。我现在不是怕写越界,因为可以根据qlz_size_decompressed分配内存再写,而是怕读越界。
不过听你说起qlz_size_compressed倒确实有方法解决这个问题,谢谢了。这样做应该可以万无一失了:
如果从网络上拿到一串数据lpSrc,长度为size,首先判断size>9,这样调用qlz_size_xxx才安全,然后调用qlz_size_compressed得到压缩后的长度csize,判断size>=csize(quicklz源代码表明它最多访问csize个源数据),接着根据qlz_size_decompressed分配内存,最后调用qlz_decompress就可以保证不出错了。
|
|
|