summaryrefslogtreecommitdiffstats
path: root/tests/fasttest.c
diff options
context:
space:
mode:
authorNick Terrell <terrelln@fb.com>2016-11-05 02:59:50 (GMT)
committerNick Terrell <terrelln@fb.com>2016-11-05 03:01:23 (GMT)
commit920bf21714f99cc20d3b8bcc28060136a390354a (patch)
tree6057917cbd5ac8599b22736ef2db83ad48ec9654 /tests/fasttest.c
parent8195ba8f7bbf0153a1dc01d2ada8823a29462afa (diff)
downloadlz4-920bf21714f99cc20d3b8bcc28060136a390354a.zip
lz4-920bf21714f99cc20d3b8bcc28060136a390354a.tar.gz
lz4-920bf21714f99cc20d3b8bcc28060136a390354a.tar.bz2
Fix LZ4_decompress_fast_continue() bug
It specified the external dictionary location incorrectly. Add tests that expose this bug with both normal compilation and ASAN.
Diffstat (limited to 'tests/fasttest.c')
-rw-r--r--tests/fasttest.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/tests/fasttest.c b/tests/fasttest.c
new file mode 100644
index 0000000..a405542
--- /dev/null
+++ b/tests/fasttest.c
@@ -0,0 +1,138 @@
+/**************************************
+ * Compiler Options
+ **************************************/
+#ifdef _MSC_VER /* Visual Studio */
+# define _CRT_SECURE_NO_WARNINGS // for MSVC
+# define snprintf sprintf_s
+#endif
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wmissing-braces" /* GCC bug 53119 : doesn't accept { 0 } as initializer (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119) */
+#endif
+
+
+/**************************************
+ * Includes
+ **************************************/
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "lz4.h"
+
+
+/* Returns non-zero on failure. */
+int test_compress(const char *input, int inSize, char *output, int outSize)
+{
+ LZ4_stream_t lz4Stream_body = { 0 };
+ LZ4_stream_t* lz4Stream = &lz4Stream_body;
+
+ int inOffset = 0;
+ int outOffset = 0;
+
+ if (inSize & 3) return -1;
+
+ while (inOffset < inSize) {
+ const int length = inSize >> 2;
+ if (inSize > 1024) return -2;
+ if (outSize - (outOffset + 8) < LZ4_compressBound(length)) return -3;
+ {
+ const int outBytes = LZ4_compress_continue(
+ lz4Stream, input + inOffset, output + outOffset + 8, length);
+ if(outBytes <= 0) return -4;
+ memcpy(output + outOffset, &length, 4); /* input length */
+ memcpy(output + outOffset + 4, &outBytes, 4); /* output length */
+ inOffset += length;
+ outOffset += outBytes + 8;
+ }
+ }
+ if (outOffset + 8 > outSize) return -5;
+ memset(output + outOffset, 0, 4);
+ memset(output + outOffset + 4, 0, 4);
+ return 0;
+}
+
+void swap(void **a, void **b) {
+ void *tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+/* Returns non-zero on failure. Not a safe function. */
+int test_decompress(const char *uncompressed, const char *compressed)
+{
+ char outBufferA[1024];
+ char spacing; /* So prefixEnd != dest */
+ char outBufferB[1024];
+ char *output = outBufferA;
+ char *lastOutput = outBufferB;
+ LZ4_streamDecode_t lz4StreamDecode_body = { 0 };
+ LZ4_streamDecode_t* lz4StreamDecode = &lz4StreamDecode_body;
+ int offset = 0;
+ int unOffset = 0;
+ int lastBytes = 0;
+
+ (void)spacing;
+
+ for(;;) {
+ int32_t bytes;
+ int32_t unBytes;
+ /* Read uncompressed size and compressed size */
+ memcpy(&unBytes, compressed + offset, 4);
+ memcpy(&bytes, compressed + offset + 4, 4);
+ offset += 8;
+ /* Check if we reached end of stream or error */
+ if(bytes == 0 && unBytes == 0) return 0;
+ if(bytes <= 0 || unBytes <= 0 || unBytes > 1024) return 1;
+
+ /* Put the last output in the dictionary */
+ LZ4_setStreamDecode(lz4StreamDecode, lastOutput, lastBytes);
+ /* Decompress */
+ bytes = LZ4_decompress_fast_continue(
+ lz4StreamDecode, compressed + offset, output, unBytes);
+ if(bytes <= 0) return 2;
+ /* Check result */
+ {
+ int r = memcmp(uncompressed + unOffset, output, unBytes);
+ if (r) return 3;
+ }
+ swap((void**)&output, (void**)&lastOutput);
+ offset += bytes;
+ unOffset += unBytes;
+ lastBytes = unBytes;
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ char input[] =
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello!"
+ "Hello Hello Hello Hello Hello Hello Hello Hello";
+ char output[LZ4_COMPRESSBOUND(4096)];
+ int r;
+
+ (void)argc;
+ (void)argv;
+
+ if ((r = test_compress(input, sizeof(input), output, sizeof(output)))) {
+ return r;
+ }
+ if ((r = test_decompress(input, output))) {
+ return r;
+ }
+ return 0;
+}