Eliminate real_LZ4_uncompress. It's unused and does not perform sufficient

check against input stream (i.e. it could read beyond specified input
buffer).
This commit is contained in:
delphij 2013-02-14 21:02:18 +00:00
parent 095b73eee8
commit 4eca904fe7

View File

@ -36,7 +36,6 @@
static int real_LZ4_compress(const char *source, char *dest, int isize,
int osize);
static int real_LZ4_uncompress(const char *source, char *dest, int osize);
static int LZ4_compressBound(int isize);
static int LZ4_uncompress_unknownOutputSize(const char *source, char *dest,
int isize, int maxOutputSize);
@ -104,16 +103,6 @@ lz4_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
* situations (input data not compressible) worst case size
* evaluation is provided by function LZ4_compressBound().
*
* real_LZ4_uncompress() :
* osize : is the output size, therefore the original size
* return : the number of bytes read in the source buffer.
* If the source stream is malformed, the function will stop
* decoding and return a negative result, indicating the byte
* position of the faulty instruction. This function never
* writes beyond dest + osize, and is therefore protected
* against malicious data packets.
* note : destination buffer must be already allocated
*
* Advanced Functions
*
* LZ4_compressBound() :
@ -137,7 +126,6 @@ lz4_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n)
* maxOutputSize, and is therefore protected against malicious
* data packets.
* note : Destination buffer must be already allocated.
* This version is slightly slower than real_LZ4_uncompress()
*
* LZ4_compressCtx() :
* This function explicitly handles the CTX memory structure.
@ -879,127 +867,15 @@ real_LZ4_compress(const char *source, char *dest, int isize, int osize)
/* Decompression functions */
/*
* Note: The decoding functions real_LZ4_uncompress() and
* LZ4_uncompress_unknownOutputSize() are safe against "buffer overflow"
* attack type. They will never write nor read outside of the provided
* output buffers. LZ4_uncompress_unknownOutputSize() also insures that
* it will never read outside of the input buffer. A corrupted input
* will produce an error result, a negative int, indicating the position
* of the error within input stream.
* Note: The decoding functionLZ4_uncompress_unknownOutputSize() is safe
* against "buffer overflow" attack type. They will never write nor
* read outside of the provided output buffers.
* LZ4_uncompress_unknownOutputSize() also insures that it will never
* read outside of the input buffer. A corrupted input will produce
* an error result, a negative int, indicating the position of the
* error within input stream.
*/
static int
real_LZ4_uncompress(const char *source, char *dest, int osize)
{
/* Local Variables */
const BYTE *restrict ip = (const BYTE *) source;
const BYTE *ref;
BYTE *op = (BYTE *) dest;
BYTE *const oend = op + osize;
BYTE *cpy;
unsigned token;
size_t length;
size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
#if LZ4_ARCH64
size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3};
#endif
/* Main Loop */
for (;;) {
/* get runlength */
token = *ip++;
if ((length = (token >> ML_BITS)) == RUN_MASK) {
size_t len;
for (; (len = *ip++) == 255; length += 255) {
}
length += len;
}
/* copy literals */
cpy = op + length;
if unlikely(cpy > oend - COPYLENGTH) {
if (cpy != oend)
/* Error: we must necessarily stand at EOF */
goto _output_error;
(void) memcpy(op, ip, length);
ip += length;
break; /* EOF */
}
LZ4_WILDCOPY(ip, op, cpy);
ip -= (op - cpy);
op = cpy;
/* get offset */
LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip);
ip += 2;
if unlikely(ref < (BYTE * const) dest)
/*
* Error: offset create reference outside destination
* buffer
*/
goto _output_error;
/* get matchlength */
if ((length = (token & ML_MASK)) == ML_MASK) {
for (; *ip == 255; length += 255) {
ip++;
}
length += *ip++;
}
/* copy repeated sequence */
if unlikely(op - ref < STEPSIZE) {
#if LZ4_ARCH64
size_t dec64 = dec64table[op-ref];
#else
const int dec64 = 0;
#endif
op[0] = ref[0];
op[1] = ref[1];
op[2] = ref[2];
op[3] = ref[3];
op += 4;
ref += 4;
ref -= dec32table[op-ref];
A32(op) = A32(ref);
op += STEPSIZE - 4;
ref -= dec64;
} else {
LZ4_COPYSTEP(ref, op);
}
cpy = op + length - (STEPSIZE - 4);
if (cpy > oend - COPYLENGTH) {
if (cpy > oend)
/*
* Error: request to write beyond destination
* buffer
*/
goto _output_error;
LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
while (op < cpy)
*op++ = *ref++;
op = cpy;
if (op == oend)
/*
* Check EOF (should never happen, since last
* 5 bytes are supposed to be literals)
*/
goto _output_error;
continue;
}
LZ4_SECURECOPY(ref, op, cpy);
op = cpy; /* correction */
}
/* end of decoding */
return (int)(((char *)ip) - source);
/* write overflow error detected */
_output_error:
return (int)(-(((char *)ip) - source));
}
static int
LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize,
int maxOutputSize)