From c968aeaf73d4b1767e6886200baca31c3341a3f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 16 Feb 2022 08:34:33 +0100 Subject: [PATCH] Import project: do not crash when importing compile database generated by IAR workbench --- lib/importproject.cpp | 19 +++++++++++++------ test/testimportproject.cpp | 21 ++++++++++++++++----- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 5760e4654..02e13c24c 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -409,28 +409,35 @@ bool ImportProject::importCompileCommands(std::istream &istr) const std::string directory = dirpath; - std::ostringstream comm; - if (obj.find("arguments") != obj.end()) { + std::string command; + if (obj.count("arguments")) { if (obj["arguments"].is()) { for (const picojson::value& arg : obj["arguments"].get()) { if (arg.is()) { - comm << arg.get() << " "; + command += arg.get() + " "; } } } else { printError("'arguments' field in compilation database entry is not a JSON array"); return false; } - } else if (obj.find("command") != obj.end()) { + } else if (obj.count("command")) { if (obj["command"].is()) { - comm << obj["command"].get(); + command = obj["command"].get(); + } else { + printError("'command' field in compilation database entry is not a string"); + return false; } } else { printError("no 'arguments' or 'command' field found in compilation database entry"); return false; } - const std::string command = comm.str(); + if (!obj.count("file") || !obj["file"].is()) { + printError("skip compilation database entry because it does not have a proper 'file' field"); + continue; + } + const std::string file = Path::fromNativeSeparators(obj["file"].get()); // Accept file? diff --git a/test/testimportproject.cpp b/test/testimportproject.cpp index 8046f296a..d216a2f61 100644 --- a/test/testimportproject.cpp +++ b/test/testimportproject.cpp @@ -57,6 +57,7 @@ private: TEST_CASE(importCompileCommands6); // Windows/CMake/Ninja generated comile_commands.json with spaces TEST_CASE(importCompileCommands7); // linux: "/home/danielm/cppcheck 2" TEST_CASE(importCompileCommands8); // Windows: "C:\Users\danielm\cppcheck" + TEST_CASE(importCompileCommands9); TEST_CASE(importCompileCommandsArgumentsSection); // Handle arguments section TEST_CASE(importCompileCommandsNoCommandSection); // gracefully handles malformed json TEST_CASE(importCppcheckGuiProject); @@ -242,12 +243,22 @@ private: }])"; std::istringstream istr(json); TestImporter importer; + importer.importCompileCommands(istr); // Do not crash + } + + void importCompileCommands9() const { + // IAR output (https://sourceforge.net/p/cppcheck/discussion/general/thread/608af51e0a/) + const char json[] = + R"([{ + "arguments" : [ + "powershell.exe -WindowStyle Hidden -NoProfile -ExecutionPolicy Bypass -File d:\\Projekte\\xyz\\firmware\\app\\xyz-lib\\build.ps1 -IAR -COMPILER_PATH \"c:\\Program Files (x86)\\IAR Systems\\Embedded Workbench 9.0\" -CONTROLLER CC1310F128 -LIB LIB_PERMANENT -COMPILER_DEFINES \"CC1310_HFXO_FREQ=24000000 DEBUG\"" + ], + "directory" : "d:\\Projekte\\xyz\\firmware\\app", + "type" : "PRE" + }])"; + std::istringstream istr(json); + TestImporter importer; importer.importCompileCommands(istr); - ASSERT_EQUALS(1, importer.fileSettings.size()); - ASSERT_EQUALS("FILESDIR=\"C:\\Program Files\\Cppcheck\"", importer.fileSettings.begin()->defines); - ASSERT_EQUALS(2, importer.fileSettings.begin()->includePaths.size()); - ASSERT_EQUALS("C:/Users/danielm/cppcheck/build/lib/", importer.fileSettings.begin()->includePaths.front()); - ASSERT_EQUALS("C:/Users/danielm/cppcheck/lib/", importer.fileSettings.begin()->includePaths.back()); } void importCompileCommandsArgumentsSection() const {