83 lines
2.8 KiB
C++
83 lines
2.8 KiB
C++
#include <catch2/catch_test_macros.hpp>
|
|
#include <chrono>
|
|
#include <cstdlib>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <nlohmann/json.hpp>
|
|
#include <string>
|
|
|
|
namespace {
|
|
|
|
struct TempDir {
|
|
std::filesystem::path path;
|
|
|
|
TempDir()
|
|
: path(std::filesystem::temp_directory_path() /
|
|
("fold-confirm-" +
|
|
std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()))) {
|
|
std::filesystem::create_directories(path);
|
|
}
|
|
|
|
~TempDir() { std::filesystem::remove_all(path); }
|
|
};
|
|
|
|
void writeFile(const std::filesystem::path& path, const std::string& content) {
|
|
std::ofstream(path) << content;
|
|
}
|
|
|
|
std::string locateFoldBinary() {
|
|
if (const char* env = std::getenv("FOLD_BINARY")) {
|
|
if (*env && std::filesystem::exists(env)) {
|
|
return std::filesystem::canonical(env).string();
|
|
}
|
|
}
|
|
auto cwd = std::filesystem::current_path();
|
|
for (const auto& rel : {"../../src/cli/fold", "../../../src/cli/fold", "../src/cli/fold"}) {
|
|
auto candidate = cwd / rel;
|
|
if (std::filesystem::exists(candidate)) {
|
|
return std::filesystem::canonical(candidate).string();
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
} // namespace
|
|
|
|
TEST_CASE("fold confirm confirms a null-deref finding", "[confirm][cli]") {
|
|
const std::string fold_bin = locateFoldBinary();
|
|
if (fold_bin.empty()) {
|
|
WARN("could not locate fold binary; skipping confirm CLI test");
|
|
return;
|
|
}
|
|
|
|
TempDir dir;
|
|
const auto source = dir.path / "main.cpp";
|
|
const auto db = dir.path / "compile_commands.json";
|
|
const auto out = dir.path / "confirm.json";
|
|
|
|
writeFile(source, "int f(bool cond) {\n"
|
|
" int* p = nullptr;\n"
|
|
" if (cond) return *p;\n"
|
|
" return 0;\n"
|
|
"}\n");
|
|
writeFile(db, nlohmann::json::array(
|
|
{{{"directory", dir.path.string()},
|
|
{"command", std::string("clang++ -std=c++20 -c ") + source.string()},
|
|
{"file", source.string()}}})
|
|
.dump(2));
|
|
|
|
const std::string cmd = "\"" + fold_bin + "\" confirm --rule null-deref --output \"" +
|
|
out.string() + "\" \"" + db.string() + "\"";
|
|
REQUIRE(std::system(cmd.c_str()) == 0);
|
|
|
|
std::ifstream in(out);
|
|
REQUIRE(in.good());
|
|
auto result = nlohmann::json::parse(in);
|
|
REQUIRE(result["summary"]["total"] == 1);
|
|
REQUIRE(result["summary"]["confirmed"] == 1);
|
|
REQUIRE(result["findings"].size() == 1);
|
|
REQUIRE(result["findings"][0]["detector"] == "null-deref");
|
|
REQUIRE(result["findings"][0]["status"] == "confirmed");
|
|
REQUIRE(result["findings"][0]["counterexample"]["variables"]["p"] == "0x0");
|
|
REQUIRE(result["findings"][0]["counterexample"]["path"].size() >= 1);
|
|
}
|