benchmark silo added
[c11concurrency-benchmarks.git] / silo / third-party / lz4 / fuzzer.c
diff --git a/silo/third-party/lz4/fuzzer.c b/silo/third-party/lz4/fuzzer.c
new file mode 100644 (file)
index 0000000..44ca885
--- /dev/null
@@ -0,0 +1,259 @@
+/*\r
+    fuzzer.c - Fuzzer test tool for LZ4\r
+    Copyright (C) Yann Collet - Andrew Mahone 2012-2013\r
+    Code started by Andrew Mahone, modified by Yann Collet\r
+    GPL v2 License\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License along\r
+    with this program; if not, write to the Free Software Foundation, Inc.,\r
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+\r
+    You can contact the author at :\r
+    - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html\r
+    - LZ4 source repository : http://code.google.com/p/lz4/\r
+*/\r
+\r
+//**************************************\r
+// Remove Visual warning messages\r
+//**************************************\r
+#define _CRT_SECURE_NO_WARNINGS  // fgets\r
+\r
+\r
+//**************************************\r
+// Includes\r
+//**************************************\r
+#include <stdlib.h>\r
+#include <stdio.h>      // fgets, sscanf\r
+#include <sys/timeb.h>  // timeb\r
+#include "lz4.h"\r
+#include "lz4hc.h"\r
+\r
+\r
+//**************************************\r
+// Constants\r
+//**************************************\r
+#define NB_ATTEMPTS (1<<17)\r
+#define LEN ((1<<15))\r
+#define SEQ_POW 2\r
+#define NUM_SEQ (1 << SEQ_POW)\r
+#define SEQ_MSK ((NUM_SEQ) - 1)\r
+#define MOD_SEQ(x) ((((x) >> 8) & 255) == 0)\r
+#define NEW_SEQ(x) ((((x) >> 10) %10) == 0)\r
+#define PAGE_SIZE 4096\r
+#define ROUND_PAGE(x) (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))\r
+#define PRIME1   2654435761U\r
+#define PRIME2   2246822519U\r
+#define PRIME3   3266489917U\r
+\r
+\r
+//*********************************************************\r
+//  Functions\r
+//*********************************************************\r
+static int FUZ_GetMilliStart()\r
+{\r
+   struct timeb tb;\r
+   int nCount;\r
+   ftime( &tb );\r
+   nCount = (int) (tb.millitm + (tb.time & 0xfffff) * 1000);\r
+   return nCount;\r
+}\r
+\r
+\r
+static int FUZ_GetMilliSpan( int nTimeStart )\r
+{\r
+   int nSpan = FUZ_GetMilliStart() - nTimeStart;\r
+   if ( nSpan < 0 )\r
+      nSpan += 0x100000 * 1000;\r
+   return nSpan;\r
+}\r
+\r
+\r
+unsigned int FUZ_rand(unsigned int* src)\r
+{\r
+    *src =  ((*src) * PRIME1) + PRIME2;\r
+    return *src;\r
+}\r
+\r
+\r
+int test_canary(unsigned char *buf)\r
+{\r
+    int i;\r
+    for (i = 0; i < 2048; i++)\r
+        if (buf[i] != buf[i + 2048])\r
+            return 0;\r
+    return 1;\r
+}\r
+\r
+\r
+int FUZ_SecurityTest()\r
+{\r
+  char* output;\r
+  char* input;\r
+  int i, r;\r
+\r
+  printf("Overflow test (issue 52)...");\r
+  input = (char*) malloc (20<<20);\r
+  output = (char*) malloc (20<<20);\r
+  input[0] = 0x0F;\r
+  input[1] = 0x00;\r
+  input[2] = 0x00;\r
+  for(i = 3; i < 16840000; i++)\r
+    input[i] = 0xff;\r
+  r = LZ4_decompress_fast(input, output, 20<<20);\r
+\r
+  free(input);\r
+  free(output);\r
+  printf(" Passed (return = %i < 0)\n",r);\r
+  return 0;\r
+}\r
+\r
+\r
+//int main(int argc, char *argv[]) {\r
+int main() {\r
+        unsigned long long bytes = 0;\r
+        unsigned long long cbytes = 0;\r
+        unsigned long long hcbytes = 0;\r
+        unsigned char buf[LEN];\r
+        unsigned char testOut[LEN+1];\r
+#       define FUZ_max   LZ4_COMPRESSBOUND(LEN)\r
+#       define FUZ_avail ROUND_PAGE(FUZ_max)\r
+        const int off_full = FUZ_avail - FUZ_max;\r
+        unsigned char cbuf[FUZ_avail + PAGE_SIZE];\r
+        unsigned int seed, randState, cur_seq=PRIME3, seeds[NUM_SEQ], timestamp=FUZ_GetMilliStart();\r
+        int i, j, k, ret, len, lenHC, attemptNb;\r
+        char userInput[30] = {0};\r
+#       define FUZ_CHECKTEST(cond, message) testNb++; if (cond) { printf("Test %i : %s : seed %u, cycle %u \n", testNb, message, seed, attemptNb); goto _output_error; }\r
+\r
+        printf("starting LZ4 fuzzer\n");\r
+        printf("Select an Initialisation number (default : random) : ");\r
+        fflush(stdout);\r
+        if ( fgets(userInput, sizeof userInput, stdin) )\r
+        {\r
+            if ( sscanf(userInput, "%d", &seed) == 1 ) {}\r
+            else seed = FUZ_GetMilliSpan(timestamp);\r
+        }\r
+        printf("Seed = %u\n", seed);\r
+        randState = seed;\r
+\r
+        FUZ_SecurityTest();\r
+\r
+        for (i = 0; i < 2048; i++)\r
+                cbuf[FUZ_avail + i] = cbuf[FUZ_avail + 2048 + i] = FUZ_rand(&randState) >> 16;\r
+\r
+        for (attemptNb = 0; attemptNb < NB_ATTEMPTS; attemptNb++) \r
+        {\r
+            int testNb = 0;\r
+\r
+            printf("\r%7i /%7i\r", attemptNb, NB_ATTEMPTS);\r
+            \r
+            for (j = 0; j < NUM_SEQ; j++) {\r
+                    seeds[j] = FUZ_rand(&randState) << 8;\r
+                    seeds[j] ^= (FUZ_rand(&randState) >> 8) & 65535;\r
+            }\r
+            for (j = 0; j < LEN; j++) {\r
+                    k = FUZ_rand(&randState);\r
+                    if (j == 0 || NEW_SEQ(k))\r
+                            cur_seq = seeds[(FUZ_rand(&randState) >> 16) & SEQ_MSK];\r
+                    if (MOD_SEQ(k)) {\r
+                            k = (FUZ_rand(&randState) >> 16) & SEQ_MSK;\r
+                            seeds[k] = FUZ_rand(&randState) << 8;\r
+                            seeds[k] ^= (FUZ_rand(&randState) >> 8) & 65535;\r
+                    }\r
+                    buf[j] = FUZ_rand(&cur_seq) >> 16;\r
+            }\r
+\r
+            // Test compression HC\r
+            ret = LZ4_compressHC_limitedOutput((const char*)buf, (char*)&cbuf[off_full], LEN, FUZ_max);\r
+            FUZ_CHECKTEST(ret==0, "HC compression failed despite sufficient space");\r
+            lenHC = ret;\r
+\r
+            // Test compression\r
+            ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[off_full], LEN, FUZ_max);\r
+            FUZ_CHECKTEST(ret==0, "compression failed despite sufficient space");\r
+            len = ret;\r
+\r
+            // Test decoding with output size being exactly what's necessary => must work\r
+            ret = LZ4_decompress_fast((char*)&cbuf[off_full], (char*)testOut, LEN);\r
+            FUZ_CHECKTEST(ret<0, "decompression failed despite correct space");\r
+\r
+            // Test decoding with one byte missing => must fail\r
+            ret = LZ4_decompress_fast((char*)&cbuf[off_full], (char*)testOut, LEN-1);\r
+            FUZ_CHECKTEST(ret>=0, "decompression should have failed, due to Output Size being too small");\r
+\r
+            // Test decoding with one byte too much => must fail\r
+            ret = LZ4_decompress_fast((char*)&cbuf[off_full], (char*)testOut, LEN+1);\r
+            FUZ_CHECKTEST(ret>=0, "decompression should have failed, due to Output Size being too large");\r
+\r
+            // Test decoding with enough output size => must work\r
+            ret = LZ4_decompress_safe((char*)&cbuf[off_full], (char*)testOut, len, LEN+1);\r
+            FUZ_CHECKTEST(ret<0, "decompression failed despite sufficient space");\r
+\r
+            // Test decoding with output size being exactly what's necessary => must work\r
+            ret = LZ4_decompress_safe((char*)&cbuf[off_full], (char*)testOut, len, LEN);\r
+            FUZ_CHECKTEST(ret<0, "decompression failed despite sufficient space");\r
+\r
+            // Test decoding with output size being one byte too short => must fail\r
+            ret = LZ4_decompress_safe((char*)&cbuf[off_full], (char*)testOut, len, LEN-1);\r
+            FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to Output Size being one byte too short");\r
+\r
+            // Test decoding with input size being one byte too short => must fail\r
+            ret = LZ4_decompress_safe((char*)&cbuf[off_full], (char*)testOut, len-1, LEN);\r
+            FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to input size being one byte too short");\r
+\r
+            // Test decoding with input size being one byte too large => must fail\r
+            ret = LZ4_decompress_safe((char*)&cbuf[off_full], (char*)testOut, len+1, LEN);\r
+            FUZ_CHECKTEST(ret>=0, "decompression should have failed, due to input size being too large");\r
+            //if (ret>=0) { printf("Test 10 : decompression should have failed, due to input size being too large : seed %u, len %d\n", seed, LEN); goto _output_error; }\r
+\r
+            // Test partial decoding with target output size being max/2 => must work\r
+            ret = LZ4_decompress_safe_partial((char*)&cbuf[off_full], (char*)testOut, len, LEN/2, LEN);\r
+            FUZ_CHECKTEST(ret<0, "partial decompression failed despite sufficient space");\r
+\r
+            // Test partial decoding with target output size being just below max => must work\r
+            ret = LZ4_decompress_safe_partial((char*)&cbuf[off_full], (char*)testOut, len, LEN-3, LEN);\r
+            FUZ_CHECKTEST(ret<0, "partial decompression failed despite sufficient space");\r
+\r
+            // Test compression with output size being exactly what's necessary (should work)\r
+            ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-len], LEN, len);\r
+            FUZ_CHECKTEST(!test_canary(&cbuf[FUZ_avail]), "compression overran output buffer");\r
+            FUZ_CHECKTEST(ret==0, "compression failed despite sufficient space");\r
+\r
+            // Test HC compression with output size being exactly what's necessary (should work)\r
+            ret = LZ4_compressHC_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-len], LEN, lenHC);\r
+            FUZ_CHECKTEST(ret==0, "HC compression failed despite sufficient space");\r
+\r
+            // Test compression with just one missing byte into output buffer => must fail\r
+            ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-(len-1)], LEN, len-1);\r
+            FUZ_CHECKTEST(ret, "compression overran output buffer");\r
+            FUZ_CHECKTEST(!test_canary(&cbuf[FUZ_avail]), "compression overran output buffer");\r
+\r
+            // Test HC compression with just one missing byte into output buffer => must fail\r
+            ret = LZ4_compressHC_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-(len-1)], LEN, lenHC-1);\r
+            FUZ_CHECKTEST(ret, "HC compression overran output buffer");\r
+\r
+            bytes += LEN;\r
+            cbytes += len;\r
+            hcbytes += lenHC;\r
+            FUZ_rand(&randState);\r
+        }\r
+\r
+        printf("all tests completed successfully \n");\r
+        printf("compression ratio: %0.3f%%\n", (double)cbytes/bytes*100);\r
+        printf("HC compression ratio: %0.3f%%\n", (double)hcbytes/bytes*100);\r
+        getchar();\r
+        return 0;\r
+\r
+_output_error:\r
+        getchar();\r
+        return 1;\r
+}\r