如何判断使用LZ4解压缩时输出缓冲区是否太小?

4

LZ4_decompress_safe 的文档描述如下:

/*! LZ4_decompress_safe() :
    compressedSize : is the precise full size of the compressed block.
    maxDecompressedSize : is the size of destination buffer, which must be already allocated.
    return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize)
             If destination buffer is not large enough, decoding will stop and output an error code (<0).
             If the source stream is detected malformed, the function will stop decoding and return a negative result.
             This function is protected against buffer overflow exploits, including malicious data packets.
             It never writes outside output buffer, nor reads outside input buffer.
*/
LZ4LIB_API int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);

但它没有说明如何区分问题是由于目标缓冲区过小还是由于输入格式不正确/参数组合错误等导致的问题...

如果我不知道目标解压后的大小,我怎么知道是否应该用更大的缓冲区重试呢?

1个回答

4

有一个有关此事的问题已经被提出,目前没有公共API可用于区分错误。


作为一种启发式方法,查看代码显示可能的返回值:

    /* end of decoding */
    if (endOnInput)
       return (int) (((char*)op)-dest);     /* Nb of output bytes decoded */
    else
       return (int) (((const char*)ip)-source);   /* Nb of input bytes read */

    /* Overflow error detected */
_output_error:
    return (int) (-(((const char*)ip)-source))-1;

因此只有两种情况:

  • 要么解码成功,您会得到一个正结果(其意义取决于您是否处于全模式或部分模式)
  • 要么解码失败并且您会得到一个负结果

在负结果的情况下,该值为 -(输入位置+1)

这表明,通过使用更大的缓冲区重新尝试并检查失败是否发生在相同位置,可以很好地猜测目标缓冲区是否太小,并且有很大的成功可能性:

  • 如果第二次解压缩尝试成功,则一切正常!
  • 如果第二次解压缩尝试在相同位置失败,则问题可能出在输入上,
  • 否则,您必须再次尝试使用更大的缓冲区。

换句话说,只要结果不同,请重试,否则就是您的结果。


限制

输入指针不一定每次都前进一个字节,它可能在读取并未绑定的length字节的两个位置上前进length字节。

如果解码失败,因为输出缓冲区太小,并且新的输出缓冲区仍然对于length来说太小,则即使输入不是(必要)格式错误,解码也会在相同位置失败。

如果假阳性是一个问题,则可以尝试:

  • 通过检查返回的位置处的输入流解码length
  • 按照Mark Adler的答案,简单地分配255 * <input size> - 2526,这对于小输入是合理的。

先生,我想和您谈一些事情,可以聊聊吗? - Suraj Jain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接