Coverage Report

Created: 2026-10-28 06:38

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
12
{
29
12
  (void)argc;
30
12
  (void)argv;
31
32
12
  char tmpl[] = "/tmp/cmake_fuzz_fortran_XXXXXX";
33
12
  char* dir = mkdtemp(tmpl);
34
12
  if (dir) {
35
12
    g_testDir = dir;
36
12
  } else {
37
0
    g_testDir = "/tmp/cmake_fuzz_fortran";
38
0
    cmSystemTools::MakeDirectory(g_testDir);
39
0
  }
40
41
12
  return 0;
42
12
}
43
44
extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
45
4.42k
{
46
4.42k
  if (size == 0 || size > kMaxInputSize) {
47
5
    return 0;
48
5
  }
49
50
4.41k
  std::string const source = g_testDir + "/test.f90";
51
4.41k
  {
52
4.41k
    FILE* fp = fopen(source.c_str(), "wb");
53
4.41k
    if (!fp) {
54
0
      return 0;
55
0
    }
56
4.41k
    fwrite(data, 1, size, fp);
57
4.41k
    fclose(fp);
58
4.41k
  }
59
60
0
  cmFortranCompiler compiler;
61
4.41k
  compiler.Id = "GNU";
62
4.41k
  compiler.SModSep = "@";
63
4.41k
  compiler.SModExt = ".smod";
64
65
4.41k
  cmFortranSourceInfo info;
66
4.41k
  info.Source = source;
67
68
4.41k
  std::vector<std::string> const includes;
69
4.41k
  std::set<std::string> const defines;
70
71
4.41k
  cmFortranParser parser(compiler, includes, defines, info);
72
4.41k
  if (cmFortranParser_FilePush(&parser, source.c_str())) {
73
4.41k
    cmFortran_yyparse(parser.Scanner);
74
4.41k
  }
75
76
4.41k
  unlink(source.c_str());
77
78
4.41k
  return 0;
79
4.41k
}