zdelta压缩库段错误

时间:2013-05-28 22:24:55

标签: c compression

我正在使用zdelta库(http://cis.poly.edu/zdelta/)来压缩一堆二进制文件,并且已经遇到解压缩几乎总是段错误的问题,即使使用命令行界面也是如此。只是想知道是否有人之前碰到过这个?
我做了一些错误隔离:我的代码的压缩输出与我从CLI获得的压缩输出(命令是./zdc reference.bin fileToCompress.bin > compressedFile.bin.del)所以我认为压缩工作正常。令人困惑的部分是说我使用A.bin作为参考并压缩自己,然后一切都很完美。一旦我尝试不同的文件,就会出现段错误(例如,压缩B.binA.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库深处进行段错误,看起来像是一个糟糕的目的地(除了我上面提到的情况)。以前有人有过这个问题吗?谢谢!

1 个答案:

答案 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);