]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/zstd/tests/fuzz/dictionary_round_trip.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / zstd / tests / fuzz / dictionary_round_trip.c
index e28c65c98f06d94d8889bd8e1a4e1ba3c9c97c29..7b7771e48e23e19cf71bf684cefe9b58a977e62a 100644 (file)
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2016-present, Facebook, Inc.
+ * Copyright (c) 2016-2020, Facebook, Inc.
  * All rights reserved.
  *
  * This source code is licensed under both the BSD-style license (found in the
  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
  * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
  */
 
 /**
 #include <string.h>
 #include "fuzz_helpers.h"
 #include "zstd_helpers.h"
-
-static const int kMaxClevel = 19;
+#include "fuzz_data_producer.h"
 
 static ZSTD_CCtx *cctx = NULL;
 static ZSTD_DCtx *dctx = NULL;
-static uint32_t seed;
 
 static size_t roundTripTest(void *result, size_t resultCapacity,
                             void *compressed, size_t compressedCapacity,
-                            const void *src, size_t srcSize)
+                            const void *src, size_t srcSize,
+                            FUZZ_dataProducer_t *producer)
 {
     ZSTD_dictContentType_e dictContentType = ZSTD_dct_auto;
-    FUZZ_dict_t dict = FUZZ_train(src, srcSize, &seed);
+    FUZZ_dict_t dict = FUZZ_train(src, srcSize, producer);
+    int const refPrefix = FUZZ_dataProducer_uint32Range(producer, 0, 1) != 0;
     size_t cSize;
-    if ((FUZZ_rand(&seed) & 15) == 0) {
-        int const cLevel = FUZZ_rand(&seed) % kMaxClevel;
+    if (FUZZ_dataProducer_uint32Range(producer, 0, 15) == 0) {
+        int const cLevel = FUZZ_dataProducer_int32Range(producer, kMinClevel, kMaxClevel);
 
         cSize = ZSTD_compress_usingDict(cctx,
                 compressed, compressedCapacity,
@@ -42,21 +43,31 @@ static size_t roundTripTest(void *result, size_t resultCapacity,
                 dict.buff, dict.size,
                 cLevel);
     } else {
-        dictContentType = FUZZ_rand32(&seed, 0, 2);
-        FUZZ_setRandomParameters(cctx, srcSize, &seed);
+        dictContentType = FUZZ_dataProducer_uint32Range(producer, 0, 2);
+        FUZZ_setRandomParameters(cctx, srcSize, producer);
         /* Disable checksum so we can use sizes smaller than compress bound. */
         FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 0));
-        FUZZ_ZASSERT(ZSTD_CCtx_loadDictionary_advanced(
+        if (refPrefix)
+            FUZZ_ZASSERT(ZSTD_CCtx_refPrefix_advanced(
+                cctx, dict.buff, dict.size,
+                dictContentType));
+        else 
+            FUZZ_ZASSERT(ZSTD_CCtx_loadDictionary_advanced(
                 cctx, dict.buff, dict.size,
-                (ZSTD_dictLoadMethod_e)FUZZ_rand32(&seed, 0, 1),
+                (ZSTD_dictLoadMethod_e)FUZZ_dataProducer_uint32Range(producer, 0, 1),
                 dictContentType));
         cSize = ZSTD_compress2(cctx, compressed, compressedCapacity, src, srcSize);
     }
     FUZZ_ZASSERT(cSize);
-    FUZZ_ZASSERT(ZSTD_DCtx_loadDictionary_advanced(
-        dctx, dict.buff, dict.size,
-        (ZSTD_dictLoadMethod_e)FUZZ_rand32(&seed, 0, 1),
-        dictContentType));
+    if (refPrefix)
+        FUZZ_ZASSERT(ZSTD_DCtx_refPrefix_advanced(
+            dctx, dict.buff, dict.size,
+            dictContentType));
+    else
+        FUZZ_ZASSERT(ZSTD_DCtx_loadDictionary_advanced(
+            dctx, dict.buff, dict.size,
+            (ZSTD_dictLoadMethod_e)FUZZ_dataProducer_uint32Range(producer, 0, 1),
+            dictContentType));
     {
         size_t const ret = ZSTD_decompressDCtx(
                 dctx, result, resultCapacity, compressed, cSize);
@@ -67,18 +78,21 @@ static size_t roundTripTest(void *result, size_t resultCapacity,
 
 int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
 {
+    /* Give a random portion of src data to the producer, to use for
+    parameter generation. The rest will be used for (de)compression */
+    FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
+    size = FUZZ_dataProducer_reserveDataPrefix(producer);
+
     size_t const rBufSize = size;
-    void* rBuf = malloc(rBufSize);
+    void* rBuf = FUZZ_malloc(rBufSize);
     size_t cBufSize = ZSTD_compressBound(size);
-    void* cBuf;
-
-    seed = FUZZ_seed(&src, &size);
+    void *cBuf;
     /* Half of the time fuzz with a 1 byte smaller output size.
      * This will still succeed because we force the checksum to be disabled,
      * giving us 4 bytes of overhead.
      */
-    cBufSize -= FUZZ_rand32(&seed, 0, 1);
-    cBuf = malloc(cBufSize);
+    cBufSize -= FUZZ_dataProducer_uint32Range(producer, 0, 1);
+    cBuf = FUZZ_malloc(cBufSize);
 
     if (!cctx) {
         cctx = ZSTD_createCCtx();
@@ -91,13 +105,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
 
     {
         size_t const result =
-            roundTripTest(rBuf, rBufSize, cBuf, cBufSize, src, size);
+            roundTripTest(rBuf, rBufSize, cBuf, cBufSize, src, size, producer);
         FUZZ_ZASSERT(result);
         FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
-        FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
+        FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, rBuf, size), "Corruption!");
     }
     free(rBuf);
     free(cBuf);
+    FUZZ_dataProducer_free(producer);
 #ifndef STATEFUL_FUZZING
     ZSTD_freeCCtx(cctx); cctx = NULL;
     ZSTD_freeDCtx(dctx); dctx = NULL;