static int __lz4_decompress_crypto(const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen, void *ctx) { int out_len = LZ4_decompress_safe(src, dst, slen, *dlen); if (out_len < 0) return out_len; *dlen = out_len; return 0; }
static int lz4_uncompress(void *dest, void *src, int size, int outsize, int *error) { int res = LZ4_decompress_safe(src, dest, size, outsize); if(res < 0) { *error = res; return -1; } return res; }
static ZEND_FUNCTION(lz4_uncompress) { zval *data; int output_len, data_size; char *output; long max_size = -1, offset = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ll", &data, &max_size, &offset) == FAILURE) { RETURN_FALSE; } if (Z_TYPE_P(data) != IS_STRING) { zend_error(E_WARNING, "lz4_uncompress : expects parameter to be string."); RETURN_FALSE; } if (max_size > 0) { data_size = max_size; if (!offset) { offset = sizeof(int); } } else { /* Get data length */ offset = sizeof(int); memcpy(&data_size, Z_STRVAL_P(data), offset); } if (data_size < 0) { zend_error(E_WARNING, "lz4_uncompress : allocate size error"); RETURN_FALSE; } output = (char *)emalloc(data_size + 1); if (!output) { zend_error(E_WARNING, "lz4_uncompress : memory error"); RETURN_FALSE; } output_len = LZ4_decompress_safe(Z_STRVAL_P(data) + offset, output, Z_STRLEN_P(data) - offset, data_size); if (output_len <= 0) { zend_error(E_WARNING, "lz4_uncompress : data error"); RETVAL_FALSE; } else { RETVAL_STRINGL(output, output_len, 1); } efree(output); }
size_t lz4_input_stream::uncompress(void const* source, size_t size) { VAST_ENTER_WITH(VAST_ARG(source, size)); // LZ4 does not offer functionality to estimate the output size. It operates // on at most 64KB blocks, so we need to ensure this maximum. VAST_ASSERT(uncompressed_.size() >= 64 << 10); auto n = LZ4_decompress_safe( reinterpret_cast<char const*>(source), reinterpret_cast<char*>(uncompressed_.data()), static_cast<int>(size), static_cast<int>(uncompressed_.size())); VAST_ASSERT(n > 0); VAST_RETURN(n); }
int main01(int argc, const char * argv[]) { struct stat buf; FILE *inf; int rsize, fsize; int csize, dsize; void *lz4state; stat(argv[1], &buf); fsize = (int)buf.st_size; inf = fopen(argv[1], "r"); // dumpFile is a 512KB file if(NULL == inf) { fprintf(stderr, "open fail\n"); return -1; } lz4state = malloc(LZ4_sizeofState()); if(NULL == lz4state) { fclose(inf); return -1; } while((rsize = (int)fread(in, 1, BLOCK_SIZE_MAX, inf)) > 0) { csize = LZ4_compress_withState(lz4state, in, out, rsize); if(csize > 0) { //dsize = LZ4_decompress_fast(); dsize = LZ4_decompress_safe(out, uncomp, csize, rsize); if(dsize < 0) { fprintf(stderr, "decompress fail, rsize=%d, csize=%d, dsize=%d\n", rsize, csize, dsize); break; } } else { fprintf(stderr, "compress fail, rsize=%d, csize=%d\n",rsize, csize); break; } } fclose(inf); free(lz4state); return 0; }
unsigned int decompress(byte* src, byte* dest, unsigned int srclen, unsigned int destlen) { #ifdef NSL_COMPRESSION_HIGH uLongf resultSize = destlen; unsigned int state = ::uncompress(dest, &resultSize, src, srclen); if (state == Z_OK) { return resultSize; } else { return 0; } #else return LZ4_decompress_safe((const char *)src, (char *)dest, srclen, destlen); #endif }
bool Packet::uncompress() { unsigned char buf[ZT_PROTO_MAX_PACKET_LENGTH]; if ((compressed())&&(size() >= ZT_PROTO_MIN_PACKET_LENGTH)) { if (size() > ZT_PACKET_IDX_PAYLOAD) { unsigned int compLen = size() - ZT_PACKET_IDX_PAYLOAD; int ucl = LZ4_decompress_safe((const char *)field(ZT_PACKET_IDX_PAYLOAD,compLen),(char *)buf,compLen,sizeof(buf)); if ((ucl > 0)&&(ucl <= (int)(capacity() - ZT_PACKET_IDX_PAYLOAD))) { setSize((unsigned int)ucl + ZT_PACKET_IDX_PAYLOAD); memcpy(field(ZT_PACKET_IDX_PAYLOAD,(unsigned int)ucl),buf,ucl); } else return false; } (*this)[ZT_PACKET_IDX_VERB] &= (char)(~ZT_PROTO_VERB_FLAG_COMPRESSED); } return true; }
log_group * deserialize_from_lz4_proto_buf(const unsigned char * buffer, size_t buf_size, size_t raw_buf_size) { char * buf = (char *)malloc(raw_buf_size); if (LZ4_decompress_safe((const char* )buffer, buf, buf_size, raw_buf_size) <= 0) { free(buf); aos_fatal_log("LZ4_decompress_safe error"); return NULL; } log_group * grp = sls_logs__log_group__unpack(NULL, raw_buf_size, (const uint8_t *)buf); free(buf); if (grp == NULL) { aos_fatal_log("sls_logs__log_group__unpack error"); } return grp; }
/* * lz4_decompress -- * WiredTiger LZ4 decompression. */ static int lz4_decompress(WT_COMPRESSOR *compressor, WT_SESSION *session, uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len, size_t *result_lenp) { WT_EXTENSION_API *wt_api; char *compressed_data; int decoded; size_t src_data_len; wt_api = ((LZ4_COMPRESSOR *)compressor)->wt_api; /* Retrieve compressed length from start of the data buffer. */ src_data_len = *(size_t *)src; if (src_data_len + sizeof(size_t) > src_len) { (void)wt_api->err_printf(wt_api, session, "lz4_decompress: stored size exceeds buffer size"); return (WT_ERROR); } /* Skip over the data size to the start of compressed data. */ compressed_data = (char *)src + sizeof(size_t); /* * The destination buffer length should always be sufficient because * wiredtiger keeps track of the byte count before compression. Use * safe decompression: we may be relying on decompression to detect * corruption. */ decoded = LZ4_decompress_safe( compressed_data, (char *)dst, (int)src_data_len, (int)dst_len); if (decoded < 0) return (lz4_error(compressor, session, "LZ4 decompress error", decoded)); /* return the uncompressed data length */ *result_lenp = dst_len; return (0); }
std::unique_ptr<IOBuf> LZ4Codec::doUncompress( const IOBuf* data, uint64_t uncompressedLength) { std::unique_ptr<IOBuf> clone; if (data->isChained()) { // LZ4 doesn't support streaming, so we have to coalesce clone = data->clone(); clone->coalesce(); data = clone.get(); } folly::io::Cursor cursor(data); uint64_t actualUncompressedLength; if (encodeSize()) { actualUncompressedLength = decodeVarintFromCursor(cursor); if (uncompressedLength != UNKNOWN_UNCOMPRESSED_LENGTH && uncompressedLength != actualUncompressedLength) { throw std::runtime_error("LZ4Codec: invalid uncompressed length"); } } else { actualUncompressedLength = uncompressedLength; if (actualUncompressedLength == UNKNOWN_UNCOMPRESSED_LENGTH || actualUncompressedLength > maxUncompressedLength()) { throw std::runtime_error("LZ4Codec: invalid uncompressed length"); } } auto sp = StringPiece{cursor.peekBytes()}; auto out = IOBuf::create(actualUncompressedLength); int n = LZ4_decompress_safe( sp.data(), reinterpret_cast<char*>(out->writableTail()), sp.size(), actualUncompressedLength); if (n < 0 || uint64_t(n) != actualUncompressedLength) { throw std::runtime_error(to<std::string>( "LZ4 decompression returned invalid value ", n)); } out->append(actualUncompressedLength); return out; }
/* Decompress and bitunshuffle a single block. */ int64_t bshuf_decompress_lz4_block(ioc_chain *C_ptr, const size_t size, const size_t elem_size) { int64_t nbytes, count; size_t this_iter; void *in = ioc_get_in(C_ptr, &this_iter); int32_t nbytes_from_header = bshuf_read_uint32_BE(in); ioc_set_next_in(C_ptr, &this_iter, (void*) ((char*) in + nbytes_from_header + 4)); void *out = ioc_get_out(C_ptr, &this_iter); ioc_set_next_out(C_ptr, &this_iter, (void *) ((char *) out + size * elem_size)); void* tmp_buf = malloc(size * elem_size); if (tmp_buf == NULL) return -1; #ifdef BSHUF_LZ4_DECOMPRESS_FAST nbytes = LZ4_decompress_fast((const char*) in + 4, (char*) tmp_buf, size * elem_size); CHECK_ERR_FREE_LZ(nbytes, tmp_buf); if (nbytes != nbytes_from_header) { free(tmp_buf); return -91; } #else nbytes = LZ4_decompress_safe((const char*) in + 4, (char *) tmp_buf, nbytes_from_header, size * elem_size); CHECK_ERR_FREE_LZ(nbytes, tmp_buf); if (nbytes != size * elem_size) { free(tmp_buf); return -91; } nbytes = nbytes_from_header; #endif count = bshuf_untrans_bit_elem(tmp_buf, out, size, elem_size); CHECK_ERR_FREE(count, tmp_buf); nbytes += 4; free(tmp_buf); return nbytes; }
static mrb_value mrb_LZ4_decompress_safe(mrb_state *mrb, mrb_value self) { char *source; mrb_int compressedSize, maxDecompressedSize; mrb_get_args(mrb, "si", &source, &compressedSize, &maxDecompressedSize); if (unlikely(maxDecompressedSize < 0)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "maxDecompressedSize mustn't be negative"); } mrb_value dest = mrb_str_buf_new(mrb, maxDecompressedSize); int decompressedSize = LZ4_decompress_safe(source, RSTRING_PTR(dest), compressedSize, RSTRING_CAPA(dest)); if (decompressedSize >= 0) { return mrb_str_resize(mrb, dest, decompressedSize); } else { mrb_raise(mrb, E_LZ4_ERROR, "cannot decompress, source may be malformed or maxDecompressedSize is too small"); } }
// No longer useful; included into issue 134 int FUZ_Issue52(void) { char* output; char* input; int i, r; // Overflow test, by Ludwig Strigeus printf("Overflow test (issue 52)..."); input = (char*) malloc (20<<20); output = (char*) malloc (20<<20); input[0] = 0x0F; input[1] = 0x00; input[2] = 0x00; for(i = 3; i < 16840000; i++) input[i] = 0xff; r = LZ4_decompress_safe(input, output, 20<<20, 20<<20); free(input); free(output); printf(" Passed (return = %i < 0)\n",r); return 0; }
void TestUnitCompression::testLz4() { int32_t size=LZ4_compress_fast(text.data(),buffer,text.size(),sizeof(buffer),6); if(size<=0 || (uint32_t)size>(text.size()+text.size()/10)) { std::cerr << "compress Lz4: Failed" << std::endl; finalResult=false; return; } else std::cout << "compress Lz4: Ok, ratio: " << size << "/" << text.size() << "=" << ((float)text.size()/(float)size) << std::endl; int32_t size2=LZ4_decompress_safe(buffer,buffer2,size,sizeof(buffer2)); if(size2!=(int32_t)text.size() || buffer2!=text) { std::cerr << "decompress Lz4: Failed" << std::endl; finalResult=false; return; } else std::cout << "decompress Lz4: Ok" << std::endl; }
static VALUE rubylz4_raw_decompress(VALUE self, VALUE input, VALUE max_decompresed_size_value) { Check_Type(input, RUBY_T_STRING); const char* input_data = RSTRING_PTR(input); int input_size = RSTRING_LEN(input); Check_Type(max_decompresed_size_value, RUBY_T_FIXNUM); int max_decompresed_size = FIX2INT(max_decompresed_size_value); VALUE output = rb_str_new(NULL, max_decompresed_size); char* output_data = RSTRING_PTR(output); int decompress_size = LZ4_decompress_safe(input_data, output_data, input_size, max_decompresed_size); if (decompress_size < 0) { rb_raise(rb_eRuntimeError, "%s", "decompress failed"); } else { rb_str_resize(output, decompress_size); return output; } }
JNIEXPORT jint JNICALL Java_org_apache_hadoop_io_compress_lz4_Lz4Decompressor_decompressBytesDirect (JNIEnv *env, jobject thisj){ const char *compressed_bytes; char *uncompressed_bytes; // Get members of Lz4Decompressor jobject clazz = (*env)->GetStaticObjectField(env,thisj, Lz4Decompressor_clazz); jobject compressed_direct_buf = (*env)->GetObjectField(env,thisj, Lz4Decompressor_compressedDirectBuf); jint compressed_direct_buf_len = (*env)->GetIntField(env,thisj, Lz4Decompressor_compressedDirectBufLen); jobject uncompressed_direct_buf = (*env)->GetObjectField(env,thisj, Lz4Decompressor_uncompressedDirectBuf); size_t uncompressed_direct_buf_len = (*env)->GetIntField(env, thisj, Lz4Decompressor_directBufferSize); // Get the input direct buffer LOCK_CLASS(env, clazz, "Lz4Decompressor"); compressed_bytes = (const char*)(*env)->GetDirectBufferAddress(env, compressed_direct_buf); UNLOCK_CLASS(env, clazz, "Lz4Decompressor"); if (compressed_bytes == 0) { return (jint)0; } // Get the output direct buffer LOCK_CLASS(env, clazz, "Lz4Decompressor"); uncompressed_bytes = (char *)(*env)->GetDirectBufferAddress(env, uncompressed_direct_buf); UNLOCK_CLASS(env, clazz, "Lz4Decompressor"); if (uncompressed_bytes == 0) { return (jint)0; } uncompressed_direct_buf_len = LZ4_decompress_safe(compressed_bytes, uncompressed_bytes, compressed_direct_buf_len, uncompressed_direct_buf_len); if (uncompressed_direct_buf_len < 0) { THROW(env, "java/lang/InternalError", "LZ4_uncompress_unknownOutputSize failed."); } (*env)->SetIntField(env, thisj, Lz4Decompressor_compressedDirectBufLen, 0); return (jint)uncompressed_direct_buf_len; }
void APC::unCompress() { if (!isCompressed()) { return; } int dest_len = *(int *)data; char *dest = new char[dest_len+1]; int ret = LZ4_decompress_safe(data+4, dest, data_len-4, dest_len); // int ret = LZ4_decompress_fast(data+4, dest, dest_len); if (ret < 0) { CCLOG("unCompress error ret=%d",ret); delete[] dest; } else { if (data != NULL) { delete[] data; } CCLOG("data len %d, dest len %d", data_len, dest_len); data = dest; data_len = dest_len; data[data_len] = '\0'; } setUnCompressFlag(); }
int decompress_blob_lz4(const void *src, uint64_t src_size, void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) { #ifdef HAVE_LZ4 char* out; int r, size; /* LZ4 uses int for size */ assert(src); assert(src_size > 0); assert(dst); assert(dst_alloc_size); assert(dst_size); assert(*dst_alloc_size == 0 || *dst); if (src_size <= 8) return -EBADMSG; size = le64toh( *(le64_t*)src ); if (size < 0 || (le64_t) size != *(le64_t*)src) return -EFBIG; if ((size_t) size > *dst_alloc_size) { out = realloc(*dst, size); if (!out) return -ENOMEM; *dst = out; *dst_alloc_size = size; } else out = *dst; r = LZ4_decompress_safe(src + 8, out, src_size - 8, size); if (r < 0 || r != size) return -EBADMSG; *dst_size = size; return 0; #else return -EPROTONOSUPPORT; #endif }
void decompress_data(Data *d) { int obuflen = 0; int ocnt = 0; int lz4tries = 3; /* abort */ char *obuf = NULL; do { obuflen += 0xFA00; if(obuf) free(obuf); obuf = malloc(obuflen); GUARD_MALLOC(obuf); } while((ocnt = LZ4_decompress_safe((const char*)d->data, obuf, d->datalen, obuflen)) < 0 && (lz4tries-- > 0)); free(d->data); d->datalen = ocnt; d->data = malloc(d->datalen); GUARD_MALLOC(d->data); memcpy(d->data, (const void*) obuf, d->datalen); free(obuf); }
/* * Class: net_jpountz_lz4_LZ4 * Method: LZ4_decompress_unknownOutputSize * Signature: ([BII[BI)I */ JNIEXPORT jint JNICALL Java_net_jpountz_lz4_LZ4JNI_LZ4_1decompress_1safe (JNIEnv *env, jclass cls, jbyteArray srcArray, jobject srcBuffer, jint srcOff, jint srcLen, jbyteArray destArray, jobject destBuffer, jint destOff, jint maxDestLen) { char* in; char* out; jint decompressed; if (srcArray != NULL) { in = (char*) (*env)->GetPrimitiveArrayCritical(env, srcArray, 0); } else { in = (char*) (*env)->GetDirectBufferAddress(env, srcBuffer); } if (in == NULL) { throw_OOM(env); return 0; } if (destArray != NULL) { out = (char*) (*env)->GetPrimitiveArrayCritical(env, destArray, 0); } else { out = (char*) (*env)->GetDirectBufferAddress(env, destBuffer); } if (out == NULL) { throw_OOM(env); return 0; } decompressed = LZ4_decompress_safe(in + srcOff, out + destOff, srcLen, maxDestLen); if (destArray != NULL) { (*env)->ReleasePrimitiveArrayCritical(env, destArray, out, 0); } if (srcArray != NULL) { (*env)->ReleasePrimitiveArrayCritical(env, srcArray, in, 0); } return decompressed; }
static int _decompress_data_lz4(file_bcast_msg_t *req) { #if HAVE_LZ4 char *out_buf; int out_len; if (!req->block_len) return 0; out_buf = xmalloc(req->uncomp_len); out_len = LZ4_decompress_safe(req->block, out_buf, req->block_len, req->uncomp_len); xfree(req->block); req->block = out_buf; if (req->uncomp_len != out_len) { error("lz4 decompression error, original block length != decompressed length"); return -1; } req->block_len = out_len; return 0; #else return -1; #endif }
int64_t lzbench_lz4_decompress(char *inbuf, size_t insize, char *outbuf, size_t outsize, size_t, size_t, char*) { return LZ4_decompress_safe(inbuf, outbuf, insize, outsize); }
int lz4_decompress_safe_native(const char* source, char* dest, int compressedSize, int maxDecompressedSize) { return LZ4_decompress_safe(source, dest, compressedSize, maxDecompressedSize); }
int RemoteDesktop::Compression_Handler::Decompress(const char* source, char* dest, int compressedSize, int maxDecompressedSize){ return LZ4_decompress_safe(source + sizeof(int), dest, compressedSize - sizeof(int), maxDecompressedSize); }
int FUZ_test(U32 seed, int nbCycles, int startCycle, double compressibility) { unsigned long long bytes = 0; unsigned long long cbytes = 0; unsigned long long hcbytes = 0; unsigned long long ccbytes = 0; void* CNBuffer; char* compressedBuffer; char* decodedBuffer; # define FUZ_max LZ4_COMPRESSBOUND(LEN) unsigned int randState=seed; int ret, cycleNb; # define FUZ_CHECKTEST(cond, ...) if (cond) { printf("Test %i : ", testNb); printf(__VA_ARGS__); \ printf(" (seed %u, cycle %i) \n", seed, cycleNb); goto _output_error; } # define FUZ_DISPLAYTEST { testNb++; ((displayLevel<3) || no_prompt) ? 0 : printf("%2i\b\b", testNb); if (displayLevel==4) fflush(stdout); } void* stateLZ4 = malloc(LZ4_sizeofState()); void* stateLZ4HC = malloc(LZ4_sizeofStateHC()); void* LZ4continue; LZ4_stream_t LZ4dict; U32 crcOrig, crcCheck; int displayRefresh; // init memset(&LZ4dict, 0, sizeof(LZ4dict)); // Create compressible test buffer CNBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH); FUZ_fillCompressibleNoiseBuffer(CNBuffer, COMPRESSIBLE_NOISE_LENGTH, compressibility, &randState); compressedBuffer = malloc(LZ4_compressBound(FUZ_MAX_BLOCK_SIZE)); decodedBuffer = malloc(FUZ_MAX_DICT_SIZE + FUZ_MAX_BLOCK_SIZE); // display refresh rate switch(displayLevel) { case 0: displayRefresh = nbCycles+1; break; case 1: displayRefresh=FUZ_MAX(1, nbCycles / 100); break; case 2: displayRefresh=89; break; default : displayRefresh=1; } // move to startCycle for (cycleNb = 0; cycleNb < startCycle; cycleNb++) { // synd rand & dict int dictSize, blockSize, blockStart; char* dict; char* block; blockSize = FUZ_rand(&randState) % FUZ_MAX_BLOCK_SIZE; blockStart = FUZ_rand(&randState) % (COMPRESSIBLE_NOISE_LENGTH - blockSize); dictSize = FUZ_rand(&randState) % FUZ_MAX_DICT_SIZE; if (dictSize > blockStart) dictSize = blockStart; block = ((char*)CNBuffer) + blockStart; dict = block - dictSize; LZ4_loadDict(&LZ4dict, dict, dictSize); LZ4_compress_continue(&LZ4dict, block, compressedBuffer, blockSize); LZ4_loadDict(&LZ4dict, dict, dictSize); LZ4_compress_continue(&LZ4dict, block, compressedBuffer, blockSize); LZ4_loadDict(&LZ4dict, dict, dictSize); LZ4_compress_continue(&LZ4dict, block, compressedBuffer, blockSize); } // Test loop for (cycleNb = startCycle; cycleNb < nbCycles; cycleNb++) { int testNb = 0; char* dict; char* block; int dictSize, blockSize, blockStart, compressedSize, HCcompressedSize; int blockContinueCompressedSize; if ((cycleNb%displayRefresh) == 0) { printf("\r%7i /%7i - ", cycleNb, nbCycles); fflush(stdout); } // Select block to test blockSize = FUZ_rand(&randState) % FUZ_MAX_BLOCK_SIZE; blockStart = FUZ_rand(&randState) % (COMPRESSIBLE_NOISE_LENGTH - blockSize); dictSize = FUZ_rand(&randState) % FUZ_MAX_DICT_SIZE; if (dictSize > blockStart) dictSize = blockStart; block = ((char*)CNBuffer) + blockStart; dict = block - dictSize; /* Compression tests */ // Test compression HC FUZ_DISPLAYTEST; ret = LZ4_compressHC(block, compressedBuffer, blockSize); FUZ_CHECKTEST(ret==0, "LZ4_compressHC() failed"); HCcompressedSize = ret; // Test compression HC using external state FUZ_DISPLAYTEST; ret = LZ4_compressHC_withStateHC(stateLZ4HC, block, compressedBuffer, blockSize); FUZ_CHECKTEST(ret==0, "LZ4_compressHC_withStateHC() failed"); // Test compression using external state FUZ_DISPLAYTEST; ret = LZ4_compress_withState(stateLZ4, block, compressedBuffer, blockSize); FUZ_CHECKTEST(ret==0, "LZ4_compress_withState() failed"); // Test compression FUZ_DISPLAYTEST; ret = LZ4_compress(block, compressedBuffer, blockSize); FUZ_CHECKTEST(ret==0, "LZ4_compress() failed"); compressedSize = ret; /* Decompression tests */ crcOrig = XXH32(block, blockSize, 0); // Test decoding with output size being exactly what's necessary => must work FUZ_DISPLAYTEST; ret = LZ4_decompress_fast(compressedBuffer, decodedBuffer, blockSize); FUZ_CHECKTEST(ret<0, "LZ4_decompress_fast failed despite correct space"); FUZ_CHECKTEST(ret!=compressedSize, "LZ4_decompress_fast failed : did not fully read compressed data"); crcCheck = XXH32(decodedBuffer, blockSize, 0); FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast corrupted decoded data"); // Test decoding with one byte missing => must fail FUZ_DISPLAYTEST; decodedBuffer[blockSize-1] = 0; ret = LZ4_decompress_fast(compressedBuffer, decodedBuffer, blockSize-1); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast should have failed, due to Output Size being too small"); FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_fast overrun specified output buffer"); // Test decoding with one byte too much => must fail FUZ_DISPLAYTEST; ret = LZ4_decompress_fast(compressedBuffer, decodedBuffer, blockSize+1); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast should have failed, due to Output Size being too large"); // Test decoding with output size exactly what's necessary => must work FUZ_DISPLAYTEST; decodedBuffer[blockSize] = 0; ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize); FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe failed despite sufficient space"); FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe did not regenerate original data"); FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe overrun specified output buffer size"); crcCheck = XXH32(decodedBuffer, blockSize, 0); FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe corrupted decoded data"); // Test decoding with more than enough output size => must work FUZ_DISPLAYTEST; decodedBuffer[blockSize] = 0; decodedBuffer[blockSize+1] = 0; ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize+1); FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe failed despite amply sufficient space"); FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe did not regenerate original data"); //FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe wrote more than (unknown) target size"); // well, is that an issue ? FUZ_CHECKTEST(decodedBuffer[blockSize+1], "LZ4_decompress_safe overrun specified output buffer size"); crcCheck = XXH32(decodedBuffer, blockSize, 0); FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe corrupted decoded data"); // Test decoding with output size being one byte too short => must fail FUZ_DISPLAYTEST; decodedBuffer[blockSize-1] = 0; ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize-1); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to Output Size being one byte too short"); FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_safe overrun specified output buffer size"); // Test decoding with output size being 10 bytes too short => must fail FUZ_DISPLAYTEST; if (blockSize>10) { decodedBuffer[blockSize-10] = 0; ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize-10); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to Output Size being 10 bytes too short"); FUZ_CHECKTEST(decodedBuffer[blockSize-10], "LZ4_decompress_safe overrun specified output buffer size"); } // Test decoding with input size being one byte too short => must fail FUZ_DISPLAYTEST; ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize-1, blockSize); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to input size being one byte too short (blockSize=%i, ret=%i, compressedSize=%i)", blockSize, ret, compressedSize); // Test decoding with input size being one byte too large => must fail FUZ_DISPLAYTEST; decodedBuffer[blockSize] = 0; ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize+1, blockSize); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to input size being too large"); FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe overrun specified output buffer size"); // Test partial decoding with target output size being max/2 => must work FUZ_DISPLAYTEST; ret = LZ4_decompress_safe_partial(compressedBuffer, decodedBuffer, compressedSize, blockSize/2, blockSize); FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe_partial failed despite sufficient space"); // Test partial decoding with target output size being just below max => must work FUZ_DISPLAYTEST; ret = LZ4_decompress_safe_partial(compressedBuffer, decodedBuffer, compressedSize, blockSize-3, blockSize); FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe_partial failed despite sufficient space"); /* Test Compression with limited output size */ // Test compression with output size being exactly what's necessary (should work) FUZ_DISPLAYTEST; ret = LZ4_compress_limitedOutput(block, compressedBuffer, blockSize, compressedSize); FUZ_CHECKTEST(ret==0, "LZ4_compress_limitedOutput() failed despite sufficient space"); // Test compression with output size being exactly what's necessary and external state (should work) FUZ_DISPLAYTEST; ret = LZ4_compress_limitedOutput_withState(stateLZ4, block, compressedBuffer, blockSize, compressedSize); FUZ_CHECKTEST(ret==0, "LZ4_compress_limitedOutput_withState() failed despite sufficient space"); // Test HC compression with output size being exactly what's necessary (should work) FUZ_DISPLAYTEST; ret = LZ4_compressHC_limitedOutput(block, compressedBuffer, blockSize, HCcompressedSize); FUZ_CHECKTEST(ret==0, "LZ4_compressHC_limitedOutput() failed despite sufficient space"); // Test HC compression with output size being exactly what's necessary (should work) FUZ_DISPLAYTEST; ret = LZ4_compressHC_limitedOutput_withStateHC(stateLZ4HC, block, compressedBuffer, blockSize, HCcompressedSize); FUZ_CHECKTEST(ret==0, "LZ4_compressHC_limitedOutput_withStateHC() failed despite sufficient space"); // Test compression with just one missing byte into output buffer => must fail FUZ_DISPLAYTEST; compressedBuffer[compressedSize-1] = 0; ret = LZ4_compress_limitedOutput(block, compressedBuffer, blockSize, compressedSize-1); FUZ_CHECKTEST(ret, "LZ4_compress_limitedOutput should have failed (output buffer too small by 1 byte)"); FUZ_CHECKTEST(compressedBuffer[compressedSize-1], "LZ4_compress_limitedOutput overran output buffer") // Test HC compression with just one missing byte into output buffer => must fail FUZ_DISPLAYTEST; compressedBuffer[compressedSize-1] = 0; ret = LZ4_compressHC_limitedOutput(block, compressedBuffer, blockSize, HCcompressedSize-1); FUZ_CHECKTEST(ret, "LZ4_compressHC_limitedOutput should have failed (output buffer too small by 1 byte)"); FUZ_CHECKTEST(compressedBuffer[compressedSize-1], "LZ4_compressHC_limitedOutput overran output buffer") /* Dictionary tests */ // Compress using dictionary FUZ_DISPLAYTEST; LZ4continue = LZ4_create (dict); LZ4_compress_continue (LZ4continue, dict, compressedBuffer, dictSize); // Just to fill hash tables blockContinueCompressedSize = LZ4_compress_continue (LZ4continue, block, compressedBuffer, blockSize); FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_continue failed"); LZ4_free (LZ4continue); // Decompress with dictionary as prefix FUZ_DISPLAYTEST; memcpy(decodedBuffer, dict, dictSize); ret = LZ4_decompress_fast_withPrefix64k(compressedBuffer, decodedBuffer+dictSize, blockSize); FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_decompress_fast_withPrefix64k did not read all compressed block input"); crcCheck = XXH32(decodedBuffer+dictSize, blockSize, 0); if (crcCheck!=crcOrig) { int i=0; while (block[i]==decodedBuffer[i]) i++; printf("Wrong Byte at position %i/%i\n", i, blockSize); } FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast_withPrefix64k corrupted decoded data (dict %i)", dictSize); FUZ_DISPLAYTEST; ret = LZ4_decompress_safe_withPrefix64k(compressedBuffer, decodedBuffer+dictSize, blockContinueCompressedSize, blockSize); FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe_withPrefix64k did not regenerate original data"); crcCheck = XXH32(decodedBuffer+dictSize, blockSize, 0); FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_withPrefix64k corrupted decoded data"); // Compress using External dictionary FUZ_DISPLAYTEST; dict -= 9; // Separation, so it is an ExtDict if (dict < (char*)CNBuffer) dict = (char*)CNBuffer; LZ4_loadDict(&LZ4dict, dict, dictSize); blockContinueCompressedSize = LZ4_compress_continue(&LZ4dict, block, compressedBuffer, blockSize); FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_continue failed"); FUZ_DISPLAYTEST; LZ4_loadDict(&LZ4dict, dict, dictSize); ret = LZ4_compress_limitedOutput_continue(&LZ4dict, block, compressedBuffer, blockSize, blockContinueCompressedSize-1); FUZ_CHECKTEST(ret>0, "LZ4_compress_limitedOutput_continue using ExtDict should fail : one missing byte for output buffer"); FUZ_DISPLAYTEST; LZ4_loadDict(&LZ4dict, dict, dictSize); ret = LZ4_compress_limitedOutput_continue(&LZ4dict, block, compressedBuffer, blockSize, blockContinueCompressedSize); FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_limitedOutput_compressed size is different (%i != %i)", ret, blockContinueCompressedSize); FUZ_CHECKTEST(ret<=0, "LZ4_compress_limitedOutput_continue should work : enough size available within output buffer"); // Decompress with dictionary as external FUZ_DISPLAYTEST; decodedBuffer[blockSize] = 0; ret = LZ4_decompress_fast_usingDict(compressedBuffer, decodedBuffer, blockSize, dict, dictSize); FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_decompress_fast_usingDict did not read all compressed block input"); FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_fast_usingDict overrun specified output buffer size") crcCheck = XXH32(decodedBuffer, blockSize, 0); if (crcCheck!=crcOrig) { int i=0; while (block[i]==decodedBuffer[i]) i++; printf("Wrong Byte at position %i/%i\n", i, blockSize); } FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast_usingDict corrupted decoded data (dict %i)", dictSize); FUZ_DISPLAYTEST; decodedBuffer[blockSize] = 0; ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize, dict, dictSize); FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe_usingDict did not regenerate original data"); FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe_usingDict overrun specified output buffer size") crcCheck = XXH32(decodedBuffer, blockSize, 0); FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_usingDict corrupted decoded data"); FUZ_DISPLAYTEST; decodedBuffer[blockSize-1] = 0; ret = LZ4_decompress_fast_usingDict(compressedBuffer, decodedBuffer, blockSize-1, dict, dictSize); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast_withDict should have failed : wrong original size (-1 byte)"); FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_fast_usingDict overrun specified output buffer size"); FUZ_DISPLAYTEST; decodedBuffer[blockSize-1] = 0; ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize-1, dict, dictSize); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe_usingDict should have failed : not enough output size (-1 byte)"); FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_safe_usingDict overrun specified output buffer size"); FUZ_DISPLAYTEST; if (blockSize > 10) { decodedBuffer[blockSize-10] = 0; ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize-10, dict, dictSize); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe_usingDict should have failed : output buffer too small (-10 byte)"); FUZ_CHECKTEST(decodedBuffer[blockSize-10], "LZ4_decompress_safe_usingDict overrun specified output buffer size (-10 byte) (blockSize=%i)", blockSize); } // Fill stats bytes += blockSize; cbytes += compressedSize; hcbytes += HCcompressedSize; ccbytes += blockContinueCompressedSize; } printf("\r%7i /%7i - ", cycleNb, nbCycles); printf("all tests completed successfully \n"); printf("compression ratio: %0.3f%%\n", (double)cbytes/bytes*100); printf("HC compression ratio: %0.3f%%\n", (double)hcbytes/bytes*100); printf("ratio with dict: %0.3f%%\n", (double)ccbytes/bytes*100); // unalloc if(!no_prompt) getchar(); free(CNBuffer); free(compressedBuffer); free(decodedBuffer); free(stateLZ4); free(stateLZ4HC); return 0; _output_error: if(!no_prompt) getchar(); free(CNBuffer); free(compressedBuffer); free(decodedBuffer); free(stateLZ4); free(stateLZ4HC); return 1; }
int FUZ_Issue134() { char* buffers[MAX_NB_BUFF_I134+1] = {0}; int i, nbBuff; printf("Overflow test issue 134 : "); // Only possible in 32-bits if (sizeof(void*)==8) { printf("64 bits mode : not applicable \n"); return 0; } printf(" "); for (nbBuff=0; nbBuff < MAX_NB_BUFF_I134; nbBuff++) { printf("\b\b\b\b%3i ", nbBuff); buffers[nbBuff] = (char*)malloc(BLOCKSIZE_I134); if (buffers[nbBuff]==NULL) { printf(" : unable to allocate more memory\n"); for (i=0 ; i<nbBuff; i++) free(buffers[i]); return 0; } if ((size_t)buffers[nbBuff] > 0) // (size_t) 0x80000000) { printf("Testing memory buffer address %X , ", (U32)(size_t)(buffers[nbBuff])); printf("Creating a payload designed to fail\n"); buffers[++nbBuff] = (char*)malloc(BLOCKSIZE_I134); if (buffers[nbBuff]==NULL) { printf("failed to test (no more memory)\n"); for (i=0 ; i<nbBuff; i++) free(buffers[i]); return 0; } { size_t sizeToGenerateOverflow = (size_t)(- ((size_t)buffers[nbBuff-1]) + 512); size_t nbOf255 = (sizeToGenerateOverflow / 255) + 1; char* input = buffers[nbBuff-1]; char* output = buffers[nbBuff]; int r; input[0] = 0xF0; // Literal length overflow input[1] = 0xFF; input[2] = 0xFF; input[3] = 0xFF; for(i = 3; (size_t)i <= nbOf255+4; i++) input[i] = 0xff; r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134); printf(" Literal overflow detected (return = %i < 0)\n",r); input[0] = 0x1F; // Match length overflow input[1] = 0x01; input[2] = 0x01; input[3] = 0x00; r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134); printf(" Match overflow detected (return = %i < 0)\n",r); if (nbBuff>=2) { output = buffers[nbBuff-2]; memset(input, 0, BLOCKSIZE_I134); input[0] = 0xF0; // Literal length overflow input[1] = 0xFF; input[2] = 0xFF; input[3] = 0xFF; r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134); printf(" Literal overflow detected (return = %i < 0)\n",r); input[0] = 0x1F; // Match length overflow input[1] = 0x01; input[2] = 0x01; input[3] = 0x00; r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134); printf(" Match overflow detected (return = %i < 0)\n",r); } } free (buffers[nbBuff]); nbBuff--; } } for (i=0 ; i<nbBuff; i++) free(buffers[i]); printf("\n"); return 0; }
static int readframe(Wal *pWal, u32 iRead, int nOut, u8 *pOut) { int result = 0; // db_thread * const thr = enif_tsd_get(g_tsd_thread); #if ATOMIC db_thread *thr = g_tsd_thread; #else db_thread* thr = enif_tsd_get(g_tsd_thread); #endif // #ifndef _WIN32 // if (pthread_equal(pthread_self(), pWal->rthreadId)) // #else // if (GetCurrentThreadId() == pWal->rthreadId) // #endif // thr = pWal->rthread; // else // thr = pWal->thread; DBG("Read frame"); // i64 term, evnum; if (thr->nResFrames == 0) { result = LZ4_decompress_safe((((char*)thr->resFrames[0].mv_data)+sizeof(u64)*2+1), (char*)pOut, thr->resFrames[0].mv_size-(sizeof(u64)*2+1), nOut); #ifdef _TESTDBG_ if (result > 0) { { i64 term, evnum; memcpy(&term, thr->resFrames[0].mv_data, sizeof(u64)); memcpy(&evnum, (u8*)thr->resFrames[0].mv_data+sizeof(u64), sizeof(u64)); DBG("Term=%lld, evnum=%lld, framesize=%d", term,evnum,(int)thr->resFrames[0].mv_size); } } #endif } else { u8 pagesBuf[PAGE_BUFF_SIZE]; int frags = thr->nResFrames; int pos = 0; while (frags >= 0) { // DBG("Read frame %d",pos); memcpy(pagesBuf + pos, ((char*)thr->resFrames[frags].mv_data)+sizeof(u64)*2+1, thr->resFrames[frags].mv_size-(sizeof(u64)*2+1)); pos += thr->resFrames[frags].mv_size-(sizeof(u64)*2+1); frags--; } thr->nResFrames = 0; result = LZ4_decompress_safe((char*)pagesBuf,(char*)pOut,pos,nOut); } return result; }
size_t cfs_decompress(void* dst, size_t dst_size, void const* src, size_t src_size) { return LZ4_decompress_safe(src, dst, src_size, dst_size); }
static ssize_t i_stream_lz4_read(struct istream_private *stream) { struct lz4_istream *zstream = (struct lz4_istream *)stream; const unsigned char *data; size_t size, max_size; int ret; if (!zstream->header_read) { if ((ret = i_stream_lz4_read_header(zstream)) <= 0) return ret; zstream->header_read = TRUE; } if (zstream->chunk_left == 0) { ret = i_stream_read_data(stream->parent, &data, &size, IOSTREAM_LZ4_CHUNK_PREFIX_LEN); if (ret < 0) { stream->istream.stream_errno = stream->parent->stream_errno; if (stream->istream.stream_errno == 0) { stream->istream.eof = TRUE; zstream->stream_size = stream->istream.v_offset + stream->pos - stream->skip; } return ret; } if (ret == 0 && !stream->istream.eof) return 0; zstream->chunk_size = zstream->chunk_left = ((uint32_t)data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; if (zstream->chunk_size == 0 || zstream->chunk_size > ISTREAM_LZ4_CHUNK_SIZE) { lz4_read_error(zstream, t_strdup_printf( "invalid lz4 chunk size: %u", zstream->chunk_size)); stream->istream.stream_errno = EINVAL; return -1; } i_stream_skip(stream->parent, IOSTREAM_LZ4_CHUNK_PREFIX_LEN); buffer_set_used_size(zstream->chunk_buf, 0); } /* read the whole compressed chunk into memory */ while (zstream->chunk_left > 0 && (ret = i_stream_read_data(zstream->istream.parent, &data, &size, 0)) > 0) { if (size > zstream->chunk_left) size = zstream->chunk_left; buffer_append(zstream->chunk_buf, data, size); i_stream_skip(zstream->istream.parent, size); zstream->chunk_left -= size; } if (zstream->chunk_left > 0) { if (ret == -1 && zstream->istream.parent->stream_errno == 0) { lz4_read_error(zstream, "truncated lz4 chunk"); stream->istream.stream_errno = EINVAL; return -1; } zstream->istream.istream.stream_errno = zstream->istream.parent->stream_errno; return ret; } /* if we already have max_buffer_size amount of data, fail here */ i_stream_compress(stream); if (stream->pos >= stream->max_buffer_size) return -2; /* allocate enough space for the old data and the new decompressed chunk. we don't know the original compressed size, so just allocate the max amount of memory. */ max_size = stream->pos + zstream->max_uncompressed_chunk_size; if (stream->buffer_size < max_size) { stream->w_buffer = i_realloc(stream->w_buffer, stream->buffer_size, max_size); stream->buffer_size = max_size; stream->buffer = stream->w_buffer; } ret = LZ4_decompress_safe(zstream->chunk_buf->data, (void *)(stream->w_buffer + stream->pos), zstream->chunk_buf->used, stream->buffer_size - stream->pos); i_assert(ret <= (int)zstream->max_uncompressed_chunk_size); if (ret < 0) { lz4_read_error(zstream, "corrupted lz4 chunk"); stream->istream.stream_errno = EINVAL; return -1; } i_assert(ret > 0); stream->pos += ret; i_assert(stream->pos <= stream->buffer_size); return ret; }
int FUZ_Issue134(void) { char* buffers[MAX_NB_BUFF_I134+1] = {0}; int i, nbBuff=0; int highAddress = 0; printf("Overflow tests : "); // Only possible in 32-bits if (sizeof(void*)==8) { printf("64 bits mode : no overflow \n"); fflush(stdout); return 0; } buffers[0] = (char*)malloc(BLOCKSIZE_I134); buffers[1] = (char*)malloc(BLOCKSIZE_I134); if ((!buffers[0]) || (!buffers[1])) { printf("not enough memory for tests \n"); return 0; } for (nbBuff=2; nbBuff < MAX_NB_BUFF_I134; nbBuff++) { printf("%3i \b\b\b\b", nbBuff); buffers[nbBuff] = (char*)malloc(BLOCKSIZE_I134); //printf("%08X ", (U32)(size_t)(buffers[nbBuff])); fflush(stdout); if (((size_t)buffers[nbBuff] > (size_t)0x80000000) && (!highAddress)) { printf("high address detected : "); fflush(stdout); highAddress=1; } if (buffers[nbBuff]==NULL) goto _endOfTests; { size_t sizeToGenerateOverflow = (size_t)(- ((size_t)buffers[nbBuff-1]) + 512); int nbOf255 = (int)((sizeToGenerateOverflow / 255) + 1); char* input = buffers[nbBuff-1]; char* output = buffers[nbBuff]; int r; input[0] = 0xF0; // Literal length overflow input[1] = 0xFF; input[2] = 0xFF; input[3] = 0xFF; for(i = 4; i <= nbOf255+4; i++) input[i] = 0xff; r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134); if (r>0) goto _overflowError; input[0] = 0x1F; // Match length overflow input[1] = 0x01; input[2] = 0x01; input[3] = 0x00; r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134); if (r>0) goto _overflowError; output = buffers[nbBuff-2]; // Reverse in/out pointer order input[0] = 0xF0; // Literal length overflow input[1] = 0xFF; input[2] = 0xFF; input[3] = 0xFF; r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134); if (r>0) goto _overflowError; input[0] = 0x1F; // Match length overflow input[1] = 0x01; input[2] = 0x01; input[3] = 0x00; r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134); if (r>0) goto _overflowError; } } nbBuff++; _endOfTests: for (i=0 ; i<nbBuff; i++) free(buffers[i]); if (!highAddress) printf("high address not possible \n"); else printf("all overflows correctly detected \n"); return 0; _overflowError: printf("Address space overflow error !! \n"); exit(1); }