Skip to content

Commit f941ec9

Browse files
committed
add tests for cwe tags
1 parent 2d15a78 commit f941ec9

1 file changed

Lines changed: 98 additions & 2 deletions

File tree

test/testsarif.cpp

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ int main() {
7979
TEST_CASE(sarifSecuritySeverity);
8080
TEST_CASE(sarifLocationInfo);
8181
TEST_CASE(sarifGenericDescriptions);
82+
TEST_CASE(sarifCweTags);
8283
}
8384

8485
// Helper to run cppcheck and capture SARIF output
@@ -323,15 +324,21 @@ int main() {
323324
{
324325
const picojson::array& tags = props.at("tags").get<picojson::array>();
325326
bool hasSecurityTag = false;
327+
bool hasCweTag = false;
326328
for (const auto& tag : tags)
327329
{
328-
if (tag.get<std::string>() == "security")
330+
const std::string tagStr = tag.get<std::string>();
331+
if (tagStr == "security")
329332
{
330333
hasSecurityTag = true;
331-
break;
334+
}
335+
else if (tagStr.find("external/cwe/cwe-") == 0)
336+
{
337+
hasCweTag = true;
332338
}
333339
}
334340
ASSERT_EQUALS(true, hasSecurityTag);
341+
ASSERT_EQUALS(true, hasCweTag);
335342
}
336343
}
337344
}
@@ -425,6 +432,95 @@ int main() {
425432
ASSERT_EQUALS(std::string::npos, fullText.find("''"));
426433
}
427434
}
435+
436+
void sarifCweTags()
437+
{
438+
const std::string sarif = runCppcheckSarif(testCode);
439+
440+
picojson::value json;
441+
picojson::parse(json, sarif);
442+
const picojson::object& root = json.get<picojson::object>();
443+
const picojson::array& runs = root.at("runs").get<picojson::array>();
444+
const picojson::object& run = runs[0].get<picojson::object>();
445+
const picojson::object& tool = run.at("tool").get<picojson::object>();
446+
const picojson::object& driver = tool.at("driver").get<picojson::object>();
447+
const picojson::array& rules = driver.at("rules").get<picojson::array>();
448+
449+
// Check that security-related rules have CWE tags
450+
bool foundNullPointerWithCwe = false;
451+
bool foundArrayBoundsWithCwe = false;
452+
bool foundMemleakWithCwe = false;
453+
bool foundDoubleFreeWithCwe = false;
454+
455+
for (const auto& rule : rules)
456+
{
457+
const picojson::object& r = rule.get<picojson::object>();
458+
const std::string ruleId = r.at("id").get<std::string>();
459+
460+
// Only check security-related rules that should have CWE tags
461+
if (ruleId == "nullPointer" || ruleId == "arrayIndexOutOfBounds" || ruleId == "doubleFree" ||
462+
ruleId == "memleak")
463+
{
464+
const picojson::object& props = r.at("properties").get<picojson::object>();
465+
466+
// Verify this rule has security-severity (prerequisite for CWE tags)
467+
if (props.find("security-severity") != props.end())
468+
{
469+
// Should have tags array
470+
ASSERT(props.find("tags") != props.end());
471+
const picojson::array& tags = props.at("tags").get<picojson::array>();
472+
473+
bool hasSecurityTag = false;
474+
bool hasCweTag = false;
475+
std::string cweTag;
476+
477+
for (const auto& tag : tags)
478+
{
479+
const std::string tagStr = tag.get<std::string>();
480+
if (tagStr == "security")
481+
{
482+
hasSecurityTag = true;
483+
}
484+
else if (tagStr.find("external/cwe/cwe-") == 0)
485+
{
486+
hasCweTag = true;
487+
cweTag = tagStr;
488+
489+
// Validate CWE tag format: external/cwe/cwe-<number>
490+
ASSERT_EQUALS(0, tagStr.find("external/cwe/cwe-"));
491+
std::string cweNumber = tagStr.substr(17); // After "external/cwe/cwe-"
492+
ASSERT(cweNumber.length() > 0);
493+
494+
// Verify it's a valid number
495+
for (char c : cweNumber)
496+
{
497+
ASSERT(c >= '0' && c <= '9');
498+
}
499+
500+
// Track specific CWE mappings we expect
501+
if (ruleId == "nullPointer" && cweNumber == "476")
502+
foundNullPointerWithCwe = true;
503+
else if (ruleId == "arrayIndexOutOfBounds" && cweNumber == "788")
504+
foundArrayBoundsWithCwe = true;
505+
else if (ruleId == "memleak" && cweNumber == "401")
506+
foundMemleakWithCwe = true;
507+
else if (ruleId == "doubleFree" && cweNumber == "415")
508+
foundDoubleFreeWithCwe = true;
509+
}
510+
}
511+
512+
ASSERT_EQUALS(true, hasSecurityTag);
513+
ASSERT_EQUALS(true, hasCweTag);
514+
}
515+
}
516+
}
517+
518+
// Verify we found at least some of the expected CWE mappings
519+
// Note: Not all may be present depending on what the test code triggers
520+
bool foundAnyCweMapping =
521+
foundNullPointerWithCwe || foundArrayBoundsWithCwe || foundMemleakWithCwe || foundDoubleFreeWithCwe;
522+
ASSERT_EQUALS(true, foundAnyCweMapping);
523+
}
428524
};
429525

430526
REGISTER_TEST(TestSarif)

0 commit comments

Comments
 (0)