Coverage Report

Created: 2026-09-14 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Tests/Fuzzing/cmFortranParserFuzzer.cxx
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
4
/*
5
 * Fuzzer for CMake's Fortran dependency scanner
6
 *
7
 * CMake runs a flex lexer and a bison parser over Fortran sources to discover
8
 * module dependencies: MODULE, SUBMODULE, USE and INCLUDE statements, plus the
9
 * preprocessor directives that guard them. This fuzzer drives that scanner.
10
 */
11
12
#include <cstddef>
13
#include <cstdint>
14
#include <cstdio>
15
#include <set>
16
#include <string>
17
#include <vector>
18
19
#include <unistd.h>
20
21
#include "cmFortranParser.h"
22
#include "cmSystemTools.h"
23
24
static constexpr size_t kMaxInputSize = 256 * 1024;
25
static std::string g_testDir;
26
27
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
28
10
{
29
10
  (void)argc;
30
10
  (void)argv;
31
32
10
  char tmpl[] = "/tmp/cmake_fuzz_fortran_XXXXXX";
33
10
  char* dir = mkdtemp(tmpl);
34
10
  if (dir) {
35
10
    g_testDir = dir;
36
10
  } else {
37
0
    g_testDir = "/tmp/cmake_fuzz_fortran";
38
0
    cmSystemTools::MakeDirectory(g_testDir);
39
0
  }
40
41
10
  return 0;
42
10
}
43
44
extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
45
3.62k
{
46
3.62k
  if (size == 0 || size > kMaxInputSize) {
47
6
    return 0;
48
6
  }
49
50
3.61k
  std::string const source = g_testDir + "/test.f90";
51
3.61k
  {
52
3.61k
    FILE* fp = fopen(source.c_str(), "wb");
53
3.61k
    if (!fp) {
54
0
      return 0;
55
0
    }
56
3.61k
    fwrite(data, 1, size, fp);
57
3.61k
    fclose(fp);
58
3.61k
  }
59
60
0
  cmFortranCompiler compiler;
61
3.61k
  compiler.Id = "GNU";
62
3.61k
  compiler.SModSep = "@";
63
3.61k
  compiler.SModExt = ".smod";
64
65
3.61k
  cmFortranSourceInfo info;
66
3.61k
  info.Source = source;
67
68
3.61k
  std::vector<std::string> const includes;
69
3.61k
  std::set<std::string> const defines;
70
71
3.61k
  cmFortranParser parser(compiler, includes, defines, info);
72
3.61k
  if (cmFortranParser_FilePush(&parser, source.c_str())) {
73
3.61k
    cmFortran_yyparse(parser.Scanner);
74
3.61k
  }
75
76
3.61k
  unlink(source.c_str());
77
78
3.61k
  return 0;
79
3.61k
}