xref: /netbsd-src/external/bsd/zstd/dist/tests/fuzz/regression_driver.c (revision 3117ece4fc4a4ca4489ba793710b60b0d26bab6c)
1*3117ece4Schristos /*
2*3117ece4Schristos  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*3117ece4Schristos  * All rights reserved.
4*3117ece4Schristos  *
5*3117ece4Schristos  * This source code is licensed under both the BSD-style license (found in the
6*3117ece4Schristos  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*3117ece4Schristos  * in the COPYING file in the root directory of this source tree).
8*3117ece4Schristos  * You may select, at your option, one of the above-listed licenses.
9*3117ece4Schristos  */
10*3117ece4Schristos 
11*3117ece4Schristos #include "fuzz.h"
12*3117ece4Schristos #include "fuzz_helpers.h"
13*3117ece4Schristos #include "util.h"
14*3117ece4Schristos #include <stddef.h>
15*3117ece4Schristos #include <stdint.h>
16*3117ece4Schristos #include <stdio.h>
17*3117ece4Schristos #include <stdlib.h>
18*3117ece4Schristos 
19*3117ece4Schristos int main(int argc, char const **argv) {
20*3117ece4Schristos   size_t const kMaxFileSize = (size_t)1 << 27;
21*3117ece4Schristos   int const kFollowLinks = 1;
22*3117ece4Schristos   FileNamesTable* files;
23*3117ece4Schristos   const char** const fnTable = argv + 1;
24*3117ece4Schristos   uint8_t *buffer = NULL;
25*3117ece4Schristos   size_t bufferSize = 0;
26*3117ece4Schristos   unsigned i;
27*3117ece4Schristos   unsigned numFilesTested = 0;
28*3117ece4Schristos   int ret = 0;
29*3117ece4Schristos 
30*3117ece4Schristos   {
31*3117ece4Schristos     unsigned const numFiles = (unsigned)(argc - 1);
32*3117ece4Schristos #ifdef UTIL_HAS_CREATEFILELIST
33*3117ece4Schristos     files = UTIL_createExpandedFNT(fnTable, numFiles, kFollowLinks);
34*3117ece4Schristos #else
35*3117ece4Schristos     files = UTIL_createFNT_fromROTable(fnTable, numFiles);
36*3117ece4Schristos     assert(numFiles == files->tableSize);
37*3117ece4Schristos #endif
38*3117ece4Schristos   }
39*3117ece4Schristos   if (!files) {
40*3117ece4Schristos     fprintf(stderr, "ERROR: Failed to create file names table\n");
41*3117ece4Schristos     return 1;
42*3117ece4Schristos   }
43*3117ece4Schristos   if (files->tableSize == 0)
44*3117ece4Schristos     fprintf(stderr, "WARNING: No files passed to %s\n", argv[0]);
45*3117ece4Schristos   for (i = 0; i < files->tableSize; ++i) {
46*3117ece4Schristos     char const *fileName = files->fileNames[i];
47*3117ece4Schristos     size_t const fileSize = UTIL_getFileSize(fileName);
48*3117ece4Schristos     size_t readSize;
49*3117ece4Schristos     FILE *file;
50*3117ece4Schristos 
51*3117ece4Schristos     DEBUGLOG(3, "Running %s", fileName);
52*3117ece4Schristos 
53*3117ece4Schristos     /* Check that it is a regular file, and that the fileSize is valid.
54*3117ece4Schristos      * If it is not a regular file, then it may have been deleted since we
55*3117ece4Schristos      * constructed the list, so just skip it, but return an error exit code.
56*3117ece4Schristos      */
57*3117ece4Schristos     if (!UTIL_isRegularFile(fileName)) {
58*3117ece4Schristos       ret = 1;
59*3117ece4Schristos       continue;
60*3117ece4Schristos     }
61*3117ece4Schristos     FUZZ_ASSERT_MSG(fileSize <= kMaxFileSize, fileName);
62*3117ece4Schristos     /* Ensure we have a large enough buffer allocated */
63*3117ece4Schristos     if (fileSize > bufferSize) {
64*3117ece4Schristos       free(buffer);
65*3117ece4Schristos       buffer = (uint8_t *)malloc(fileSize);
66*3117ece4Schristos       FUZZ_ASSERT_MSG(buffer, fileName);
67*3117ece4Schristos       bufferSize = fileSize;
68*3117ece4Schristos     }
69*3117ece4Schristos     /* Open the file */
70*3117ece4Schristos     file = fopen(fileName, "rb");
71*3117ece4Schristos     FUZZ_ASSERT_MSG(file, fileName);
72*3117ece4Schristos     /* Read the file */
73*3117ece4Schristos     readSize = fread(buffer, 1, fileSize, file);
74*3117ece4Schristos     FUZZ_ASSERT_MSG(readSize == fileSize, fileName);
75*3117ece4Schristos     /* Close the file */
76*3117ece4Schristos     fclose(file);
77*3117ece4Schristos     /* Run the fuzz target */
78*3117ece4Schristos     LLVMFuzzerTestOneInput(buffer, fileSize);
79*3117ece4Schristos     ++numFilesTested;
80*3117ece4Schristos   }
81*3117ece4Schristos   fprintf(stderr, "Tested %u files: ", numFilesTested);
82*3117ece4Schristos   if (ret == 0) {
83*3117ece4Schristos     fprintf(stderr, "Success!\n");
84*3117ece4Schristos   } else {
85*3117ece4Schristos     fprintf(stderr, "Failure!\n");
86*3117ece4Schristos   }
87*3117ece4Schristos   free(buffer);
88*3117ece4Schristos   UTIL_freeFileNamesTable(files);
89*3117ece4Schristos   return ret;
90*3117ece4Schristos }
91