/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 | } |