mirror of
https://github.com/Kitware/CMake.git
synced 2026-06-24 08:47:59 +00:00
Tests/Fuzzing: Add cmGeneratorExpressionFuzzer
Fuzz the CMake generator expression parser and evaluator. Tests $<...> expression syntax and evaluation.
This commit is contained in:
committed by
Brad King
parent
90f9fa5fb5
commit
915524aaa6
@@ -58,3 +58,6 @@ add_fuzzer(cmListFileLexerFuzzer cmListFileLexerFuzzer.cxx)
|
||||
|
||||
# CMakeLists.txt parser fuzzer
|
||||
add_fuzzer(cmListFileParserFuzzer cmListFileParserFuzzer.cxx)
|
||||
|
||||
# Generator expression fuzzer
|
||||
add_fuzzer(cmGeneratorExpressionFuzzer cmGeneratorExpressionFuzzer.cxx)
|
||||
|
||||
84
Tests/Fuzzing/cmGeneratorExpression.dict
Normal file
84
Tests/Fuzzing/cmGeneratorExpression.dict
Normal file
@@ -0,0 +1,84 @@
|
||||
# CMake Generator Expression Dictionary
|
||||
|
||||
# Basic syntax
|
||||
"$<"
|
||||
">"
|
||||
":"
|
||||
","
|
||||
|
||||
# Boolean expressions
|
||||
"$<BOOL:"
|
||||
"$<AND:"
|
||||
"$<OR:"
|
||||
"$<NOT:"
|
||||
"$<IF:"
|
||||
"$<0:"
|
||||
"$<1:"
|
||||
|
||||
# String operations
|
||||
"$<STREQUAL:"
|
||||
"$<EQUAL:"
|
||||
"$<IN_LIST:"
|
||||
"$<LOWER_CASE:"
|
||||
"$<UPPER_CASE:"
|
||||
"$<MAKE_C_IDENTIFIER:"
|
||||
"$<JOIN:"
|
||||
"$<REMOVE_DUPLICATES:"
|
||||
"$<FILTER:"
|
||||
"$<GENEX_EVAL:"
|
||||
|
||||
# Version comparisons
|
||||
"$<VERSION_LESS:"
|
||||
"$<VERSION_GREATER:"
|
||||
"$<VERSION_EQUAL:"
|
||||
"$<VERSION_LESS_EQUAL:"
|
||||
"$<VERSION_GREATER_EQUAL:"
|
||||
|
||||
# Target operations
|
||||
"$<TARGET_FILE:"
|
||||
"$<TARGET_FILE_NAME:"
|
||||
"$<TARGET_FILE_DIR:"
|
||||
"$<TARGET_FILE_BASE_NAME:"
|
||||
"$<TARGET_LINKER_FILE:"
|
||||
"$<TARGET_SONAME_FILE:"
|
||||
"$<TARGET_PDB_FILE:"
|
||||
"$<TARGET_PROPERTY:"
|
||||
"$<TARGET_OBJECTS:"
|
||||
"$<TARGET_BUNDLE_DIR:"
|
||||
"$<TARGET_BUNDLE_CONTENT_DIR:"
|
||||
"$<TARGET_EXISTS:"
|
||||
"$<TARGET_NAME_IF_EXISTS:"
|
||||
"$<TARGET_POLICY:"
|
||||
|
||||
# Config/Platform
|
||||
"$<CONFIG:"
|
||||
"$<PLATFORM_ID:"
|
||||
"$<COMPILE_LANGUAGE:"
|
||||
"$<LINK_LANGUAGE:"
|
||||
"$<COMPILE_LANG_AND_ID:"
|
||||
"$<LINK_LANG_AND_ID:"
|
||||
"$<C_COMPILER_ID:"
|
||||
"$<CXX_COMPILER_ID:"
|
||||
"$<CUDA_COMPILER_ID:"
|
||||
|
||||
# Interface expressions
|
||||
"$<BUILD_INTERFACE:"
|
||||
"$<INSTALL_INTERFACE:"
|
||||
"$<INSTALL_PREFIX>"
|
||||
|
||||
# Output expressions
|
||||
"$<TARGET_NAME:"
|
||||
"$<LINK_ONLY:"
|
||||
"$<COMPILE_ONLY:"
|
||||
|
||||
# Special
|
||||
"$<ANGLE-R>"
|
||||
"$<COMMA>"
|
||||
"$<SEMICOLON>"
|
||||
|
||||
# Nesting patterns
|
||||
"$<$<"
|
||||
">>"
|
||||
"::"
|
||||
",,"
|
||||
"$<IF:$<"
|
||||
88
Tests/Fuzzing/cmGeneratorExpressionFuzzer.cxx
Normal file
88
Tests/Fuzzing/cmGeneratorExpressionFuzzer.cxx
Normal file
@@ -0,0 +1,88 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file LICENSE.rst or https://cmake.org/licensing for details. */
|
||||
|
||||
/*
|
||||
* Fuzzer for CMake's Generator Expression parser
|
||||
*
|
||||
* Generator expressions ($<...>) are evaluated at build-system generation
|
||||
* time. This fuzzer targets the lexer and static parsing utilities that don't
|
||||
* require full cmake context.
|
||||
*
|
||||
* Coverage targets:
|
||||
* - Generator expression lexer (cmGeneratorExpressionLexer)
|
||||
* - Static parsing/preprocessing functions
|
||||
* - Nested expression handling
|
||||
* - Expression validation
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorExpressionLexer.h"
|
||||
|
||||
// Limit input size - genex can be exponential in nested cases
|
||||
static constexpr size_t kMaxInputSize = 16 * 1024; // 16KB
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
|
||||
{
|
||||
if (size == 0 || size > kMaxInputSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string input(reinterpret_cast<char const*>(data), size);
|
||||
|
||||
// Test the lexer directly
|
||||
{
|
||||
cmGeneratorExpressionLexer lexer;
|
||||
auto tokens = lexer.Tokenize(input);
|
||||
(void)tokens;
|
||||
}
|
||||
|
||||
// Test static utility functions that don't need cmake context
|
||||
{
|
||||
// Find generator expressions
|
||||
auto pos = cmGeneratorExpression::Find(input);
|
||||
(void)pos;
|
||||
|
||||
// Check if starts with genex
|
||||
bool starts = cmGeneratorExpression::StartsWithGeneratorExpression(input);
|
||||
(void)starts;
|
||||
|
||||
// Validate as target name
|
||||
bool valid = cmGeneratorExpression::IsValidTargetName(input);
|
||||
(void)valid;
|
||||
|
||||
// Strip empty list elements
|
||||
std::string stripped =
|
||||
cmGeneratorExpression::StripEmptyListElements(input);
|
||||
(void)stripped;
|
||||
|
||||
// Split expressions
|
||||
std::vector<std::string> output;
|
||||
cmGeneratorExpression::Split(input, output);
|
||||
|
||||
// Preprocess with different contexts
|
||||
std::string preprocessed1 = cmGeneratorExpression::Preprocess(
|
||||
input, cmGeneratorExpression::StripAllGeneratorExpressions);
|
||||
(void)preprocessed1;
|
||||
|
||||
std::string preprocessed2 = cmGeneratorExpression::Preprocess(
|
||||
input, cmGeneratorExpression::BuildInterface);
|
||||
(void)preprocessed2;
|
||||
|
||||
std::string preprocessed3 = cmGeneratorExpression::Preprocess(
|
||||
input, cmGeneratorExpression::InstallInterface);
|
||||
(void)preprocessed3;
|
||||
|
||||
// Collect expressions
|
||||
std::map<std::string, std::vector<std::string>> collected;
|
||||
std::string collResult = cmGeneratorExpression::Collect(input, collected);
|
||||
(void)collResult;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user