123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- /*
- * Copyright (c) 2016-2021, 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.
- */
- /**
- * This fuzz target round trips the FSE normalized count with FSE_writeNCount()
- * and FSE_readNcount() to ensure that it can always round trip correctly.
- */
- #define FSE_STATIC_LINKING_ONLY
- #define ZSTD_STATIC_LINKING_ONLY
- #include <stddef.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "fuzz_helpers.h"
- #include "zstd_helpers.h"
- #include "fuzz_data_producer.h"
- #include "fse.h"
- int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
- {
- FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
- /* Pick a random tableLog and maxSymbolValue */
- unsigned const tableLog = FUZZ_dataProducer_uint32Range(producer, FSE_MIN_TABLELOG, FSE_MAX_TABLELOG);
- unsigned const maxSymbolValue = FUZZ_dataProducer_uint32Range(producer, 0, 255);
- unsigned remainingWeight = (1u << tableLog) - 1;
- size_t dataSize;
- BYTE data[512];
- short ncount[256];
- /* Randomly fill the normalized count */
- memset(ncount, 0, sizeof(ncount));
- {
- unsigned s;
- for (s = 0; s < maxSymbolValue && remainingWeight > 0; ++s) {
- short n = (short)FUZZ_dataProducer_int32Range(producer, -1, remainingWeight);
- ncount[s] = n;
- if (n < 0) {
- remainingWeight -= 1;
- } else {
- assert((unsigned)n <= remainingWeight);
- remainingWeight -= n;
- }
- }
- /* Ensure ncount[maxSymbolValue] != 0 and the sum is (1<<tableLog) */
- ncount[maxSymbolValue] = remainingWeight + 1;
- if (ncount[maxSymbolValue] == 1 && FUZZ_dataProducer_uint32Range(producer, 0, 1) == 1) {
- ncount[maxSymbolValue] = -1;
- }
- }
- /* Write the normalized count */
- {
- FUZZ_ASSERT(sizeof(data) >= FSE_NCountWriteBound(maxSymbolValue, tableLog));
- dataSize = FSE_writeNCount(data, sizeof(data), ncount, maxSymbolValue, tableLog);
- FUZZ_ZASSERT(dataSize);
- }
- /* Read & validate the normalized count */
- {
- short rtNcount[256];
- unsigned rtMaxSymbolValue = 255;
- unsigned rtTableLog;
- /* Copy into a buffer with a random amount of random data at the end */
- size_t const buffSize = (size_t)FUZZ_dataProducer_uint32Range(producer, dataSize, sizeof(data));
- BYTE* const buff = FUZZ_malloc(buffSize);
- size_t rtDataSize;
- memcpy(buff, data, dataSize);
- {
- size_t b;
- for (b = dataSize; b < buffSize; ++b) {
- buff[b] = (BYTE)FUZZ_dataProducer_uint32Range(producer, 0, 255);
- }
- }
- rtDataSize = FSE_readNCount(rtNcount, &rtMaxSymbolValue, &rtTableLog, buff, buffSize);
- FUZZ_ZASSERT(rtDataSize);
- FUZZ_ASSERT(rtDataSize == dataSize);
- FUZZ_ASSERT(rtMaxSymbolValue == maxSymbolValue);
- FUZZ_ASSERT(rtTableLog == tableLog);
- {
- unsigned s;
- for (s = 0; s <= maxSymbolValue; ++s) {
- FUZZ_ASSERT(ncount[s] == rtNcount[s]);
- }
- }
- free(buff);
- }
- FUZZ_dataProducer_free(producer);
- return 0;
- }
|