c-如何知道当用LZ4解压缩时输出缓冲区太小



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

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

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

这方面存在一个问题,目前还没有公共的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;

所以只有两种情况:

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

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

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

  • 如果第二次解压缩尝试成功,那就太好了
  • 如果第二次解压缩尝试在相同位置失败
  • 否则,您必须再次尝试使用更大的缓冲区

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


限制

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

如果由于输出缓冲区太小而导致解码失败,并且新的输出缓冲区对于length来说仍然太小,则即使输入不一定格式错误,解码也将在相同位置失败。

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

  • 通过检查返回位置处的输入流来解码length
  • 只需根据Mark Adler的答案分配255 * <input size> - 2526,这对于小输入来说是合理的

最新更新