git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / tests / fuzz / fse_read_ncount.c
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  * All rights reserved.
4  *
5  * This source code is licensed under both the BSD-style license (found in the
6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7  * in the COPYING file in the root directory of this source tree).
8  * You may select, at your option, one of the above-listed licenses.
9  */
10
11 /**
12  * This fuzz target round trips the FSE normalized count with FSE_writeNCount()
13  * and FSE_readNcount() to ensure that it can always round trip correctly.
14  */
15
16 #define FSE_STATIC_LINKING_ONLY
17 #define ZSTD_STATIC_LINKING_ONLY
18
19 #include <stddef.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include "fuzz_helpers.h"
24 #include "zstd_helpers.h"
25 #include "fuzz_data_producer.h"
26 #include "fse.h"
27
28 int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
29 {
30     FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
31
32     /* Pick a random tableLog and maxSymbolValue */
33     unsigned const tableLog = FUZZ_dataProducer_uint32Range(producer, FSE_MIN_TABLELOG, FSE_MAX_TABLELOG);
34     unsigned const maxSymbolValue = FUZZ_dataProducer_uint32Range(producer, 0, 255);
35
36     unsigned remainingWeight = (1u << tableLog) - 1;
37     size_t dataSize;
38     BYTE data[512];
39     short ncount[256];
40
41     /* Randomly fill the normalized count */
42     memset(ncount, 0, sizeof(ncount));
43     {
44         unsigned s;
45         for (s = 0; s < maxSymbolValue && remainingWeight > 0; ++s) {
46             short n = (short)FUZZ_dataProducer_int32Range(producer, -1, remainingWeight);
47             ncount[s] = n;
48             if (n < 0) {
49                 remainingWeight -= 1;
50             } else {
51                 assert((unsigned)n <= remainingWeight);
52                 remainingWeight -= n;
53             }
54         }
55         /* Ensure ncount[maxSymbolValue] != 0 and the sum is (1<<tableLog) */
56         ncount[maxSymbolValue] = remainingWeight + 1;
57         if (ncount[maxSymbolValue] == 1 && FUZZ_dataProducer_uint32Range(producer, 0, 1) == 1) {
58             ncount[maxSymbolValue] = -1;
59         }
60     }
61     /* Write the normalized count */
62     {
63         FUZZ_ASSERT(sizeof(data) >= FSE_NCountWriteBound(maxSymbolValue, tableLog));
64         dataSize = FSE_writeNCount(data, sizeof(data), ncount, maxSymbolValue, tableLog);
65         FUZZ_ZASSERT(dataSize);
66     }
67     /* Read & validate the normalized count */
68     {
69         short rtNcount[256];
70         unsigned rtMaxSymbolValue = 255;
71         unsigned rtTableLog;
72         /* Copy into a buffer with a random amount of random data at the end */
73         size_t const buffSize = (size_t)FUZZ_dataProducer_uint32Range(producer, dataSize, sizeof(data));
74         BYTE* const buff = FUZZ_malloc(buffSize);
75         size_t rtDataSize;
76         memcpy(buff, data, dataSize); 
77         {
78             size_t b;
79             for (b = dataSize; b < buffSize; ++b) {
80                 buff[b] = (BYTE)FUZZ_dataProducer_uint32Range(producer, 0, 255);
81             }
82         }
83
84         rtDataSize = FSE_readNCount(rtNcount, &rtMaxSymbolValue, &rtTableLog, buff, buffSize);
85         FUZZ_ZASSERT(rtDataSize);
86         FUZZ_ASSERT(rtDataSize == dataSize);
87         FUZZ_ASSERT(rtMaxSymbolValue == maxSymbolValue);
88         FUZZ_ASSERT(rtTableLog == tableLog);
89         {
90             unsigned s;
91             for (s = 0; s <= maxSymbolValue; ++s) {
92                 FUZZ_ASSERT(ncount[s] == rtNcount[s]);
93             }
94         }
95         free(buff);
96     }
97
98     FUZZ_dataProducer_free(producer);
99     return 0;
100 }