mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
OSS-Fuzz: Add new fuzzer targets pkg Config Resolver
Signed-off-by: Arthur Chan <arthur.chan@adalogics.com>
This commit is contained in:
@@ -67,6 +67,7 @@ add_fuzzer(cmExprParserFuzzer cmExprParserFuzzer.cxx)
|
|||||||
|
|
||||||
# pkg-config parser fuzzer
|
# pkg-config parser fuzzer
|
||||||
add_fuzzer(cmPkgConfigParserFuzzer cmPkgConfigParserFuzzer.cxx)
|
add_fuzzer(cmPkgConfigParserFuzzer cmPkgConfigParserFuzzer.cxx)
|
||||||
|
add_fuzzer(cmPkgConfigResolverFuzzer cmPkgConfigResolverFuzzer.cxx)
|
||||||
|
|
||||||
# JSON parser fuzzer
|
# JSON parser fuzzer
|
||||||
add_fuzzer(cmJSONParserFuzzer cmJSONParserFuzzer.cxx)
|
add_fuzzer(cmJSONParserFuzzer cmJSONParserFuzzer.cxx)
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# pkg-config File Dictionary
|
||||||
|
|
||||||
|
# Key-value separators
|
||||||
|
"="
|
||||||
|
":"
|
||||||
|
|
||||||
|
# Variable reference
|
||||||
|
"${"
|
||||||
|
"}"
|
||||||
|
|
||||||
|
# Common keywords
|
||||||
|
"Name"
|
||||||
|
"Description"
|
||||||
|
"Version"
|
||||||
|
"Requires"
|
||||||
|
"Requires.private"
|
||||||
|
"Conflicts"
|
||||||
|
"Libs"
|
||||||
|
"Libs.private"
|
||||||
|
"Cflags"
|
||||||
|
"URL"
|
||||||
|
|
||||||
|
# Common variables
|
||||||
|
"prefix"
|
||||||
|
"exec_prefix"
|
||||||
|
"libdir"
|
||||||
|
"includedir"
|
||||||
|
"datarootdir"
|
||||||
|
"datadir"
|
||||||
|
"sysconfdir"
|
||||||
|
"sharedstatedir"
|
||||||
|
"localstatedir"
|
||||||
|
|
||||||
|
# Common values
|
||||||
|
"/usr"
|
||||||
|
"/usr/local"
|
||||||
|
"/usr/lib"
|
||||||
|
"/usr/include"
|
||||||
|
"-I"
|
||||||
|
"-L"
|
||||||
|
"-l"
|
||||||
|
"-D"
|
||||||
|
"-pthread"
|
||||||
|
|
||||||
|
# Whitespace
|
||||||
|
" "
|
||||||
|
"\x09"
|
||||||
|
"\x0a"
|
||||||
|
"\x0d\x0a"
|
||||||
|
|
||||||
|
# Comments
|
||||||
|
"#"
|
||||||
|
|
||||||
|
# Version operators
|
||||||
|
">="
|
||||||
|
"<="
|
||||||
|
">"
|
||||||
|
"<"
|
||||||
|
"!="
|
||||||
|
|
||||||
|
# Escapes
|
||||||
|
"\\"
|
||||||
|
"\\$"
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/* 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 pkg-config resolver.
|
||||||
|
*
|
||||||
|
* cmPkgConfigParserFuzzer already covers the .pc tokeniser, but it stops at
|
||||||
|
* the raw key/value pairs. Everything downstream of that is untested because
|
||||||
|
* the resolver is what drives its variable-interpolation entry points.
|
||||||
|
*
|
||||||
|
* The resolver is where the interesting work happens: recursive ${var}
|
||||||
|
* expansion, -I/-L/-l fragment splitting, sysroot re-rooting, and parsing
|
||||||
|
* "Requires:" dependency specs with version operators. .pc files come from
|
||||||
|
* whatever is on PKG_CONFIG_PATH, so a hostile or corrupt package drop is a
|
||||||
|
* realistic source of malformed input.
|
||||||
|
*
|
||||||
|
* All three strictness levels run on every input. Strictness is not chosen by
|
||||||
|
* the input -- Strict and Permissive reject files that BestEffort accepts, so
|
||||||
|
* running all three is what reaches the accept/reject paths in
|
||||||
|
* HasRequiredFields() and HasStrictConflicts().
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cm/optional>
|
||||||
|
|
||||||
|
#include "cmPkgConfigParser.h"
|
||||||
|
#include "cmPkgConfigResolver.h"
|
||||||
|
|
||||||
|
static constexpr size_t kMaxInputSize = 64 * 1024;
|
||||||
|
|
||||||
|
static cmPkgConfigParser ParseInput(uint8_t const* data, size_t size)
|
||||||
|
{
|
||||||
|
// cmPkgConfigParser::Parse takes a non-const buffer (may modify in place)
|
||||||
|
std::vector<char> buffer(data, data + size);
|
||||||
|
|
||||||
|
cmPkgConfigParser parser;
|
||||||
|
parser.Parse(buffer.data(), buffer.size());
|
||||||
|
parser.Finish();
|
||||||
|
parser.ParseComplete();
|
||||||
|
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Consume(cmPkgConfigResolver const& resolver)
|
||||||
|
{
|
||||||
|
(void)resolver.Name();
|
||||||
|
(void)resolver.Description();
|
||||||
|
(void)resolver.Version();
|
||||||
|
|
||||||
|
// Dependency specs: version operators and the spec grammar.
|
||||||
|
for (auto const& spec : resolver.Requires(false)) {
|
||||||
|
(void)cmPkgConfigResolver::VersionReqString(spec);
|
||||||
|
(void)cmPkgConfigResolver::CheckVersion(spec, "1.2.3");
|
||||||
|
}
|
||||||
|
(void)resolver.Requires(true);
|
||||||
|
(void)resolver.Conflicts();
|
||||||
|
(void)resolver.Provides();
|
||||||
|
|
||||||
|
// Fragment splitting and sysroot re-rooting, public and private.
|
||||||
|
(void)resolver.Cflags(false);
|
||||||
|
(void)resolver.Cflags(true);
|
||||||
|
(void)resolver.Libs(false);
|
||||||
|
(void)resolver.Libs(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0 || size > kMaxInputSize) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmPkgConfigEnv env;
|
||||||
|
env.SysrootDir = std::string("/fuzz/sysroot");
|
||||||
|
env.TopBuildDir = std::string("/fuzz/build");
|
||||||
|
env.LibDirs = std::vector<std::string>{ "/usr/lib", "/fuzz/lib" };
|
||||||
|
env.SysCflags = std::vector<std::string>{ "/usr/include" };
|
||||||
|
env.SysLibs = std::vector<std::string>{ "/usr/lib" };
|
||||||
|
|
||||||
|
std::string const pcFileDir = "/fuzz/pkgconfig";
|
||||||
|
|
||||||
|
cmPkgConfigParser const parsed = ParseInput(data, size);
|
||||||
|
|
||||||
|
if (auto strict =
|
||||||
|
cmPkgConfigResolver::ResolveStrict(parsed, env, pcFileDir)) {
|
||||||
|
Consume(*strict);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto permissive =
|
||||||
|
cmPkgConfigResolver::ResolvePermissive(parsed, env, pcFileDir)) {
|
||||||
|
Consume(*permissive);
|
||||||
|
}
|
||||||
|
|
||||||
|
Consume(cmPkgConfigResolver::ResolveBestEffort(parsed, env, pcFileDir));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user