Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Tests/Fuzzing/cmGeneratorExpressionFuzzer.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 Generator Expression parser
6
 *
7
 * Generator expressions ($<...>) are evaluated at build-system generation
8
 * time. This fuzzer targets the lexer and static parsing utilities that don't
9
 * require full cmake context.
10
 *
11
 * Coverage targets:
12
 * - Generator expression lexer (cmGeneratorExpressionLexer)
13
 * - Static parsing/preprocessing functions
14
 * - Nested expression handling
15
 * - Expression validation
16
 */
17
18
#include <cstddef>
19
#include <cstdint>
20
#include <map>
21
#include <string>
22
#include <vector>
23
24
#include "cmGeneratorExpression.h"
25
#include "cmGeneratorExpressionLexer.h"
26
27
// Limit input size - genex can be exponential in nested cases
28
static constexpr size_t kMaxInputSize = 16 * 1024; // 16KB
29
30
extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
31
3.13k
{
32
3.13k
  if (size == 0 || size > kMaxInputSize) {
33
28
    return 0;
34
28
  }
35
36
3.10k
  std::string input(reinterpret_cast<char const*>(data), size);
37
38
  // Test the lexer directly
39
3.10k
  {
40
3.10k
    cmGeneratorExpressionLexer lexer;
41
3.10k
    auto tokens = lexer.Tokenize(input);
42
3.10k
    (void)tokens;
43
3.10k
  }
44
45
  // Test static utility functions that don't need cmake context
46
3.10k
  {
47
    // Find generator expressions
48
3.10k
    auto pos = cmGeneratorExpression::Find(input);
49
3.10k
    (void)pos;
50
51
    // Check if starts with genex
52
3.10k
    bool starts = cmGeneratorExpression::StartsWithGeneratorExpression(input);
53
3.10k
    (void)starts;
54
55
    // Validate as target name
56
3.10k
    bool valid = cmGeneratorExpression::IsValidTargetName(input);
57
3.10k
    (void)valid;
58
59
    // Strip empty list elements
60
3.10k
    std::string stripped =
61
3.10k
      cmGeneratorExpression::StripEmptyListElements(input);
62
3.10k
    (void)stripped;
63
64
    // Split expressions
65
3.10k
    std::vector<std::string> output;
66
3.10k
    cmGeneratorExpression::Split(input, output);
67
68
    // Preprocess with different contexts
69
3.10k
    std::string preprocessed1 = cmGeneratorExpression::Preprocess(
70
3.10k
      input, cmGeneratorExpression::StripAllGeneratorExpressions);
71
3.10k
    (void)preprocessed1;
72
73
3.10k
    std::string preprocessed2 = cmGeneratorExpression::Preprocess(
74
3.10k
      input, cmGeneratorExpression::BuildInterface);
75
3.10k
    (void)preprocessed2;
76
77
3.10k
    std::string preprocessed3 = cmGeneratorExpression::Preprocess(
78
3.10k
      input, cmGeneratorExpression::InstallInterface);
79
3.10k
    (void)preprocessed3;
80
81
    // Collect expressions
82
3.10k
    std::map<std::string, std::vector<std::string>> collected;
83
3.10k
    std::string collResult = cmGeneratorExpression::Collect(input, collected);
84
3.10k
    (void)collResult;
85
3.10k
  }
86
87
3.10k
  return 0;
88
3.13k
}