Skip to content

Commit da94ca7

Browse files
packchk: add validation for <csolution> element #2007 (#1182)
1 parent 17cd695 commit da94ca7

File tree

9 files changed

+219
-2
lines changed

9 files changed

+219
-2
lines changed

tools/packchk/include/CheckFiles.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ class CheckFiles {
5151
std::string GetFullFilename(const std::string& fileName);
5252
bool GatherIncPathVsAttrConfig(RteItem* item);
5353
bool CheckAttrConfigFiles();
54+
bool CheckCSolutionEntries(RteItem* item);
55+
bool CheckCsolutionLayer(RteItem* item);
56+
bool CheckCsolutionTemplate(RteItem* item);
57+
bool CheckForTag(RteItem* item, const std::list<std::string>& searchAttributes);
58+
5459

5560
private:
5661
std::string m_packagePath;

tools/packchk/src/CheckFiles.cpp

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ VISIT_RESULT CheckFilesVisitor::Visit(RteItem* item)
4545
m_checkFiles.CheckDeprecated(item);
4646
m_checkFiles.CheckDescription(item);
4747
m_checkFiles.GatherIncPathVsAttrConfig(item);
48+
m_checkFiles.CheckCSolutionEntries(item);
49+
4850

4951
return VISIT_RESULT::CONTINUE_VISIT;
5052
}
@@ -421,6 +423,11 @@ bool CheckFiles::CheckFileExists(const string& fileName, int lineNo, bool associ
421423

422424
string checkPath = GetFullFilename(fileName);
423425

426+
if(XmlValueAdjuster::IsAbsolute(fileName)) {
427+
LogMsg("M326", PATH(fileName), lineNo); // error : absolute paths are not permitted
428+
return false;
429+
}
430+
424431
bool ok = true;
425432
if(!RteFsUtils::Exists(checkPath)) {
426433
if(associated) {
@@ -533,7 +540,7 @@ bool CheckFiles::CheckCaseSense(const string& fileName, int lineNo)
533540
}
534541
else {
535542
string errMsg = string("file/folder \"") + seg + "\" not found";
536-
LogMsg("M103", VAL("REF", errMsg));
543+
LogMsg("M103", VAL("REF", errMsg), lineNo);
537544
return false;
538545
}
539546
}
@@ -899,7 +906,6 @@ bool CheckFiles::CheckFileExtension(RteItem* item)
899906
return ok;
900907
}
901908

902-
903909
bool CheckFiles::GatherIncPathVsAttrConfig(RteItem* item)
904910
{
905911
const auto file = dynamic_cast<RteFile*>(item);
@@ -952,3 +958,100 @@ bool CheckFiles::CheckAttrConfigFiles()
952958
return bOk;
953959
}
954960

961+
bool CheckFiles::CheckCSolutionEntries(RteItem* item)
962+
{
963+
if(item->GetTag() != "csolution") {
964+
return true;
965+
}
966+
967+
bool bOk = true;
968+
const auto lineNo = item->GetLineNumber();
969+
970+
const auto& children = item->GetChildren();
971+
if(children.empty()) {
972+
LogMsg("M100", lineNo); // No entries for %TAG% found
973+
return false;
974+
}
975+
976+
for(const auto& child : children) {
977+
const auto& tag = child->GetTag();
978+
if(tag == "clayer") {
979+
CheckCsolutionLayer(child);
980+
}
981+
else if(tag == "template") {
982+
CheckCsolutionTemplate(child);
983+
}
984+
}
985+
986+
return bOk;
987+
}
988+
989+
bool CheckFiles::CheckForTag(RteItem* item, const list<string>& searchAttributes)
990+
{
991+
const auto lineNo = item->GetLineNumber();
992+
const auto& tag = item->GetTag();
993+
bool bOk = true;
994+
995+
for(const auto& searchAttr : searchAttributes) {
996+
if(item->GetAttribute(searchAttr) == "") {
997+
LogMsg("M601", TAG(searchAttr), TAG2(tag), lineNo); // '%TAG%' missing on '%TAG2%'
998+
bOk = false;
999+
}
1000+
}
1001+
1002+
return bOk;
1003+
}
1004+
1005+
bool CheckFiles::CheckCsolutionLayer(RteItem* item)
1006+
{
1007+
CheckForTag(item, list<string>({"type", "path", "file"}));
1008+
1009+
const auto lineNo = item->GetLineNumber();
1010+
const auto& path = item->GetAttribute("path");
1011+
const auto& file = item->GetAttribute("file");
1012+
1013+
if(!path.empty() && !file.empty()) {
1014+
const auto fileName = path + "/" + file;
1015+
CheckForSpaces(fileName, lineNo);
1016+
if(CheckFileExists(fileName, lineNo)) {
1017+
CheckCaseSense(fileName, lineNo);
1018+
CheckFileIsInPack(fileName, lineNo);
1019+
}
1020+
}
1021+
1022+
1023+
return true;
1024+
}
1025+
1026+
bool CheckFiles::CheckCsolutionTemplate(RteItem* item)
1027+
{
1028+
CheckForTag(item, list<string>({"name", "path", "file"}));
1029+
1030+
const auto lineNo = item->GetLineNumber();
1031+
const auto& tag = item->GetTag();
1032+
const auto& children = item->GetChildren();
1033+
const auto& path = item->GetAttribute("path");
1034+
const auto& file = item->GetAttribute("file");
1035+
1036+
if(!path.empty() && !file.empty()) {
1037+
const auto fileName = path + "/" + file;
1038+
CheckForSpaces(fileName, lineNo);
1039+
if(CheckFileExists(fileName, lineNo)) {
1040+
CheckCaseSense(fileName, lineNo);
1041+
CheckFileIsInPack(fileName, lineNo);
1042+
}
1043+
}
1044+
1045+
bool bFound = false;
1046+
for(const auto child : children) {
1047+
if(child->GetTag() == "description") {
1048+
bFound = true;
1049+
}
1050+
}
1051+
1052+
if(!bFound) {
1053+
LogMsg("M601", TAG("description"), TAG2(tag), lineNo); // '%TAG%' missing on '%TAG2%'
1054+
}
1055+
1056+
return bFound;
1057+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//header 1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// tests1.c
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
License
2+
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<package schemaVersion="1.4" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="PACK.xsd">
4+
<vendor>TestVendor</vendor>
5+
<url>https://www.testurl.com/pack/</url>
6+
<name>CsolutionTag</name>
7+
<description>CsolutionTag</description>
8+
<license>License.txt</license>
9+
10+
<releases>
11+
<release version="0.0.1" date="2025-03-05">>
12+
Initial release of CsolutionTag.
13+
</release>
14+
</releases>
15+
16+
<keywords>
17+
<keyword>TestInvalidPack</keyword>
18+
</keywords>
19+
20+
<conditions>
21+
<condition id="Test_Condition">
22+
<description>Test Device</description>
23+
<require Dvendor="ARM:82"/>
24+
</condition>
25+
</conditions>
26+
27+
<components>
28+
<component Cclass="TestClass" Cgroup="TestGlobal" Cversion="1.0.0" condition="Test_Condition">
29+
<description>TestGlobal</description>
30+
<files>
31+
<file category="source" name="Files/test1.c"/>
32+
<file category="TestGlobal" name="Files/header1.h"/>
33+
</files>
34+
</component>
35+
</components>
36+
37+
<csolution>
38+
<clayer type="Board" path="boards/myboard/cmsis/layers/baremetal" file="Board.clayer.yml" copy-to="Board/myboard" condition="Test_Condition"/>
39+
<clayer copy-to="Board/myboard" condition="Not_Exist"/>
40+
<clayer type="Board" path="boards/myboard/cmsis/layers/baremetal" file="NotExist.clayer.yml" copy-to="Board/myboard" condition="Test_Condition"/>
41+
<clayer type="Board" path="/boards/myboard/cmsis/layers/baremetal" file="Board.clayer.yml" copy-to="Board/myboard" condition="Test_Condition"/>
42+
43+
<template name="Simple Device project" path="boards/myboard/cmsis/templates/Device/Simple" file="Simple.csolution.yml" condition="Test_Condition">
44+
<description>Single-core project with no TrustZone </description>
45+
</template>
46+
<template condition="Not_Exist">
47+
</template>
48+
<template name="Simple Device project" path="boards/myboard/cmsis/templates/Device/Simple" file="NotExist.csolution.yml" condition="Test_Condition">
49+
<description>Single-core project with no TrustZone </description>
50+
</template>
51+
<template name="Simple Device project" path="/boards/myboard/cmsis/templates/Device/Simple" file="Simple.csolution.yml" condition="Test_Condition">
52+
<description>Single-core project with no TrustZone </description>
53+
</template>
54+
</csolution>
55+
56+
</package>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//yaml file
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//yaml file

tools/packchk/test/integtests/src/PackChkIntegTests.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,53 @@ TEST_F(PackChkIntegTests, CheckConcurrentComponentFiles) {
11551155
}
11561156
}
11571157

1158+
TEST_F(PackChkIntegTests, CheckCsolutionTag) {
1159+
const char* argv[3];
1160+
1161+
string pdscFile = PackChkIntegTestEnv::localtestdata_dir +
1162+
"/CsolutionTag/TestVendor.CsolutionTag.pdsc";
1163+
ASSERT_TRUE(RteFsUtils::Exists(pdscFile));
1164+
1165+
argv[0] = (char*)"";
1166+
argv[1] = (char*)pdscFile.c_str();
1167+
argv[2] = (char*)"--disable-validation";
1168+
1169+
PackChk packChk;
1170+
EXPECT_EQ(1, packChk.Check(3, argv, nullptr));
1171+
1172+
auto errMsgs = ErrLog::Get()->GetLogMessages();
1173+
int M110_foundCnt = 0;
1174+
int M500_foundCnt = 0;
1175+
int M601_foundCnt = 0;
1176+
int M323_foundCnt = 0;
1177+
int M326_foundCnt = 0;
1178+
int M332_foundCnt = 0;
1179+
1180+
for (const string& msg : errMsgs) {
1181+
if (msg.find("M110", 0) != string::npos) {
1182+
M110_foundCnt++;
1183+
}
1184+
if (msg.find("M500", 0) != string::npos) {
1185+
M500_foundCnt++;
1186+
}
1187+
if (msg.find("M601", 0) != string::npos) {
1188+
M601_foundCnt++;
1189+
}
1190+
if (msg.find("M323", 0) != string::npos) {
1191+
M323_foundCnt++;
1192+
}
1193+
if (msg.find("M326", 0) != string::npos) {
1194+
M326_foundCnt++;
1195+
}
1196+
if (msg.find("M332", 0) != string::npos) {
1197+
M332_foundCnt++;
1198+
}
1199+
}
1200+
1201+
if(M110_foundCnt != 1 || M500_foundCnt != 2 || M601_foundCnt != 7 || M323_foundCnt != 2 || M326_foundCnt != 2 || M332_foundCnt != 2 ) {
1202+
FAIL() << "error: Missing messages testing <csolution> tag";
1203+
}
1204+
}
11581205

11591206
TEST_F(PackChkIntegTests, CheckConditionComponentDependency_Pos) {
11601207
const char* argv[7];

0 commit comments

Comments
 (0)