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

但没有指定如何区分问题是目标缓冲区太小还是输入格式错误/参数组合错误/...

在我不知道目标解压缩大小的情况下,我如何知道是否应该使用更大的缓冲区重试?

4

1 回答 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;

所以只有2种情况:

  • 要么解码成功,你得到一个肯定的结果(其意义取决于你是处于完全模式还是部分模式)
  • 或者解码不成功,你得到一个否定的结果

在否定结果的情况下,值为-(position_in_input + 1)

这表明猜测目标缓冲区是否太小可以通过使用(大得多的)更大的缓冲区重试并检查失败是否发生在同一位置来完成,并很有可能成功:

  • 如果第二次减压尝试成功,你就很好!
  • 如果第二次减压尝试在同一位置失败,则问题可能与输入有关,
  • 否则,您必须再次尝试使用更大的缓冲区。

或者说,只要结果不同,再试一次,否则,就是你的结果。


局限性

输入指针不一定每次前进一个字节,它可能会在从输入读取和无界length的两个位置前进字节。length

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

如果误报是一个问题,那么可以尝试:

  • 通过检查返回位置的输入流来解码length,
  • 只需255 * <input size> - 2526按照Mark Adler 的回答进行分配,这对于小投入是合理的。
于 2017-02-08T13:42:30.047 回答