我正在使用zdelta库(http://cis.poly.edu/zdelta/)来压缩一堆二进制文件,并且已经遇到解压缩几乎总是段错误的问题,即使使用命令行界面也是如此。只是想知道是否有人之前碰到过这个?
我做了一些错误隔离:我的代码的压缩输出与我从CLI获得的压缩输出(命令是./zdc reference.bin fileToCompress.bin > compressedFile.bin.del
)所以我认为压缩工作正常。令人困惑的部分是说我使用A.bin
作为参考并压缩自己,然后一切都很完美。一旦我尝试不同的文件,就会出现段错误(例如,压缩B.bin
,A.bin
作为参考。与减压CLI相同。
压缩代码,bufferIn
是未压缩的数据,bufferOut
是一个足够大的输出缓冲区(输入缓冲区的十倍,所以即使压缩增长文件事情应该仍然有效):
int rv = zd_compress(reference, refSize,
bufferIn, inputSize,
bufferOut, &outputSize);
压缩文档:
433 /* computes zdelta difference between target data and reference data
434 *
435 * INPUT:
436 * ref pointer to reference data set
437 * rsize size of reference data set
438 * tar pointer to targeted data set
439 * tsize size of targeted data set
440 * delta pointer to delta buffer
441 * the delta buffer IS allocated by the user
442 * *dsize size of delta buffer
443 *
444 *
445 * OUTPUT parameters:
446 * delta pointer to zdelta difference
447 * *dsize size of zdelta difference
448 *
449 * zd_compress returns ZD_OK on success,
450 * ZD_MEM_ERROR if there was not enough memory,
451 * ZD_BUF_ERROR if there was not enough room in the output
452 * buffer.
453 */
454 ZEXTERN int ZEXPORT zd_compress OF ((const Bytef *ref, uLong rsize,
455 const Bytef *tar, uLong tsize,
456 Bytef *delta, uLongf* dsize));
==============================
解压缩代码,bufferIn
是压缩数据,bufferOut
是输出缓冲区,是输入的1000倍(不好的做法是,但我想首先找出段错误..):
int rv = zd_uncompress(reference, refSize,
bufferOut, &outputSize,
bufferIn, inputSize);
解压缩文档:
518 /* rebuilds target data from reference data and zdelta difference
519 *
520 * INPUT:
521 * ref pointer to reference data set
522 * rsize size of reference data set
523 * tar pointer to target buffer
524 * this buffer IS allocated by the user
525 * tsize size of target buffer
526 * delta pointer to zdelta difference
527 * dsize size of zdelta difference
528 *
529 *
530 * OUTPUT parameters:
531 * tar pointer to recomputed target data
532 * *tsize size of recomputed target data
533 *
534 * zd_uncompress returns ZD_OK on success,
535 * ZD_MEM_ERROR if there was not enough memory,
536 * ZD_BUF_ERROR if there was not enough room in the output
537 * buffer.
538 */
539 ZEXTERN int ZEXPORT zd_uncompress OF ((const Bytef *ref, uLong rsize,
540 Bytef *tar, uLongf *tsize,
541 const Bytef *delta, uLong dsize));
大小变量都已正确初始化。每当我运行解压缩时,它会在memcpy
zdelta/inffast.c
内的zdelta库深处进行段错误,看起来像是一个糟糕的目的地(除了我上面提到的情况)。以前有人有过这个问题吗?谢谢!
答案 0 :(得分:2)
我认为这个问题是由于无符号变量的否定引起的,在文件inffast.c第138行:
ptr = rwptr[best_ptr] + (sign == ZD_PLUS ? d : -d);
d
被声明为uInt
类型,因此false部分中的否定将(很可能)溢出,这是memcpy()
的错误目标地址的原因。
简单地将其改为:
if(ZD_PLUS == sign)
{
ptr = rwptr[best_ptr] + d;
}
else
{
ptr = rwptr[best_ptr] - d;
}
解决了这个问题。
infcodes.c中第257行的相同故事:
c->bp = rwptr[best_ptr] + (c->sign == ZD_PLUS ? c->dist : -c->dist);