mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
Tests/Fuzzing: Add cmListFileLexerFuzzer
Fuzz the CMake listfile lexer (cmListFileLexer) with generated inputs. Tests tokenization of CMakeLists.txt files.
This commit is contained in:
committed by
Brad King
parent
8535a7963c
commit
fa5c85d552
@@ -52,3 +52,6 @@ endmacro()
|
||||
add_fuzzer(xml_parser_fuzzer xml_parser_fuzzer.cc)
|
||||
|
||||
message(STATUS "Fuzzing targets enabled with engine: ${FUZZING_ENGINE}")
|
||||
|
||||
# CMakeLists.txt lexer fuzzer
|
||||
add_fuzzer(cmListFileLexerFuzzer cmListFileLexerFuzzer.cxx)
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
# CMake ListFile Lexer Dictionary
|
||||
# Keywords and syntax for CMakeLists.txt files
|
||||
|
||||
# Common commands
|
||||
"cmake_minimum_required"
|
||||
"project"
|
||||
"add_executable"
|
||||
"add_library"
|
||||
"target_link_libraries"
|
||||
"target_include_directories"
|
||||
"target_compile_definitions"
|
||||
"target_compile_options"
|
||||
"set"
|
||||
"unset"
|
||||
"if"
|
||||
"elseif"
|
||||
"else"
|
||||
"endif"
|
||||
"foreach"
|
||||
"endforeach"
|
||||
"while"
|
||||
"endwhile"
|
||||
"function"
|
||||
"endfunction"
|
||||
"macro"
|
||||
"endmacro"
|
||||
"return"
|
||||
"include"
|
||||
"find_package"
|
||||
"find_library"
|
||||
"find_path"
|
||||
"find_program"
|
||||
"file"
|
||||
"message"
|
||||
"option"
|
||||
"configure_file"
|
||||
"install"
|
||||
"add_custom_command"
|
||||
"add_custom_target"
|
||||
"add_subdirectory"
|
||||
"list"
|
||||
"string"
|
||||
"math"
|
||||
"get_property"
|
||||
"set_property"
|
||||
"get_target_property"
|
||||
"set_target_properties"
|
||||
"add_definitions"
|
||||
"add_dependencies"
|
||||
|
||||
# Syntax elements
|
||||
"("
|
||||
")"
|
||||
"\""
|
||||
"[["
|
||||
"]]"
|
||||
"[=["
|
||||
"]=]"
|
||||
"[==["
|
||||
"]==]"
|
||||
"#"
|
||||
"#[["
|
||||
"#]]"
|
||||
"\x0a"
|
||||
"\x0d\x0a"
|
||||
" "
|
||||
"\x09"
|
||||
"$"
|
||||
"{"
|
||||
"}"
|
||||
"<"
|
||||
">"
|
||||
";"
|
||||
":"
|
||||
"@"
|
||||
"\\"
|
||||
|
||||
# Variables
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${PROJECT_NAME}"
|
||||
"${PROJECT_SOURCE_DIR}"
|
||||
"${PROJECT_BINARY_DIR}"
|
||||
"$ENV{}"
|
||||
"$CACHE{}"
|
||||
|
||||
# Generator expressions
|
||||
"$<"
|
||||
">:"
|
||||
"$<TARGET_FILE:"
|
||||
"$<TARGET_PROPERTY:"
|
||||
"$<BUILD_INTERFACE:"
|
||||
"$<INSTALL_INTERFACE:"
|
||||
"$<BOOL:"
|
||||
"$<AND:"
|
||||
"$<OR:"
|
||||
"$<NOT:"
|
||||
"$<IF:"
|
||||
"$<STREQUAL:"
|
||||
"$<VERSION_LESS:"
|
||||
"$<CONFIG:"
|
||||
|
||||
# BOMs
|
||||
"\xef\xbb\xbf"
|
||||
"\xff\xfe"
|
||||
"\xfe\xff"
|
||||
@@ -0,0 +1,62 @@
|
||||
/* 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 ListFile lexer (CMakeLists.txt parser)
|
||||
*
|
||||
* This fuzzer targets cmListFileLexer which tokenizes CMakeLists.txt files.
|
||||
* It's a critical attack surface as malicious CMakeLists.txt files could be
|
||||
* encountered when building untrusted projects.
|
||||
*
|
||||
* Coverage targets:
|
||||
* - Token parsing (identifiers, strings, brackets, comments)
|
||||
* - BOM handling (UTF-8, UTF-16, UTF-32)
|
||||
* - Bracket argument/comment parsing
|
||||
* - Error recovery for malformed input
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "cmListFileLexer.h"
|
||||
|
||||
// Limit input size to avoid timeouts on complex inputs
|
||||
static constexpr size_t kMaxInputSize = 64 * 1024; // 64KB
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
|
||||
{
|
||||
// Skip overly large inputs
|
||||
if (size == 0 || size > kMaxInputSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmListFileLexer* lexer = cmListFileLexer_New();
|
||||
if (!lexer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse from string (not file) for efficiency
|
||||
if (cmListFileLexer_SetString(lexer, reinterpret_cast<char const*>(data),
|
||||
size)) {
|
||||
// Consume all tokens until EOF or error
|
||||
cmListFileLexer_Token* token;
|
||||
while ((token = cmListFileLexer_Scan(lexer)) != nullptr) {
|
||||
// Access token fields to ensure they're valid
|
||||
(void)token->type;
|
||||
(void)token->text;
|
||||
(void)token->length;
|
||||
(void)token->line;
|
||||
(void)token->column;
|
||||
|
||||
// Get type as string for additional coverage
|
||||
(void)cmListFileLexer_GetTypeAsString(lexer, token->type);
|
||||
}
|
||||
|
||||
// Exercise position tracking
|
||||
(void)cmListFileLexer_GetCurrentLine(lexer);
|
||||
(void)cmListFileLexer_GetCurrentColumn(lexer);
|
||||
}
|
||||
|
||||
cmListFileLexer_Delete(lexer);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user