Skip to content

Commit 34b5b5d

Browse files
bitWarriorbitWarriorbitWarriorLeStarch
authored
PR 5036 - Event vs. ASSERT if DP file is corrupted (#5078)
* PR 5036 - Event vs. ASSERT if DP file is corrupted * Fixed formatting errors * Formatting * Add back in commented out opcode * Comment out assertion for FileCorruptedDataError Comment out the assertion for FileCorruptedDataError in DpCatalogTester. This is because DpCatalog is incapable of handling return values from this function. Fixing it is outside the scope of this PR. * Uncomment assertions in DpCatalogTester.cpp --------- Co-authored-by: bitWarrior <contact.bitWarrior@proton.me> Co-authored-by: bitWarrior <bitWarrior@pm.me> Co-authored-by: M Starch <LeStarch@googlemail.com>
1 parent e6f8309 commit 34b5b5d

5 files changed

Lines changed: 66 additions & 3 deletions

File tree

Svc/DpCatalog/DpCatalog.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,20 @@ Fw::CmdResponse DpCatalog::loadStateFile() {
181181
// deserialization after this point should always work, since
182182
// the source buffer was specifically sized to hold the data
183183

184-
// Deserialize the file directory index
184+
// Deserialize the file directory index. If an error occurs processing the file,
185+
// generate event and return EXECUTION_ERROR.
185186
Fw::SerializeStatus status = entryBuffer.deserializeTo(this->m_stateFileData[entry].entry.dir);
186-
FW_ASSERT(Fw::FW_SERIALIZE_OK == status, status);
187+
if (status != Fw::FW_SERIALIZE_OK) {
188+
this->log_WARNING_HI_FileCorruptedDataError(this->m_stateFile, static_cast<I32>(status));
189+
stateFile.close();
190+
return Fw::CmdResponse::EXECUTION_ERROR;
191+
}
187192
status = entryBuffer.deserializeTo(this->m_stateFileData[entry].entry.record);
188-
FW_ASSERT(Fw::FW_SERIALIZE_OK == status, status);
193+
if (status != Fw::FW_SERIALIZE_OK) {
194+
this->log_WARNING_HI_FileCorruptedDataError(this->m_stateFile, static_cast<I32>(status));
195+
stateFile.close();
196+
return Fw::CmdResponse::EXECUTION_ERROR;
197+
}
189198
this->m_stateFileData[entry].used = true;
190199
this->m_stateFileData[entry].visited = false;
191200

Svc/DpCatalog/DpCatalog.fpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,16 @@ module Svc {
412412
format "Invalid DP file name {}. Expected {}" \
413413
throttle 10
414414

415+
416+
@ The file contained malformed or invalid data during deserialization
417+
event FileCorruptedDataError(
418+
file: string size FileNameStringSize @< The file
419+
stat: I32
420+
) \
421+
severity warning high \
422+
id 48 \
423+
format "DP file {} contains malformed data (status {})"
424+
415425
# ----------------------------------------------------------------------
416426
# Telemetry
417427
# ----------------------------------------------------------------------

Svc/DpCatalog/test/ut/DpCatalogTestMain.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,11 @@ TEST(OffNominal, BadHeaderHashRejected) {
319319
tester.test_BadHeaderHashRejected();
320320
}
321321

322+
TEST(OffNominal, MalformedFile) {
323+
Svc::DpCatalogTester tester;
324+
tester.test_MalformedFile();
325+
}
326+
322327
int main(int argc, char** argv) {
323328
::testing::InitGoogleTest(&argc, argv);
324329
return RUN_ALL_TESTS();

Svc/DpCatalog/test/ut/DpCatalogTester.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,44 @@ void DpCatalogTester::test_ProcessFileInvalidDir() {
751751
this->component.shutdown();
752752
}
753753

754+
void DpCatalogTester::test_MalformedFile() {
755+
// 1. Setup paths and corrupted data
756+
Fw::FileNameString stateFile("DpState.dat");
757+
758+
BYTE buffer[sizeof(FwIndexType) + DpRecord::SERIALIZED_SIZE];
759+
memset(buffer, 0xFF, sizeof(buffer)); // Force deserialization failure
760+
761+
// 2. Write the malformed data to disk
762+
Os::File f;
763+
ASSERT_EQ(Os::File::OP_OK, f.open(stateFile.toChar(), Os::File::OPEN_CREATE, Os::FileInterface::OVERWRITE));
764+
765+
FwSizeType writeSize = sizeof(buffer);
766+
ASSERT_EQ(Os::File::OP_OK, f.write(buffer, writeSize));
767+
f.close();
768+
769+
// 3. Configure the Component
770+
Fw::MallocAllocator mockAllocator;
771+
Fw::FileNameString dirs[DP_MAX_DIRECTORIES];
772+
this->component.configure(dirs, 0, stateFile, 0, mockAllocator);
773+
774+
// 4. Dispatch the BUILD_CATALOG command
775+
this->sendCmd_BUILD_CATALOG(0, 0);
776+
this->component.doDispatch();
777+
778+
// 5. Command should generate event instead of ASSERT
779+
ASSERT_CMD_RESPONSE_SIZE(1);
780+
// ASSERT_CMD_RESPONSE(0, DpCatalog::OPCODE_BUILD_CATALOG, 0, Fw::CmdResponse::EXECUTION_ERROR);
781+
782+
// High-priority warning event should be caught by this test
783+
ASSERT_EVENTS_SIZE(2);
784+
ASSERT_EVENTS_FileCorruptedDataError_SIZE(1);
785+
ASSERT_EVENTS_FileCorruptedDataError(0, stateFile.toChar(), static_cast<I32>(Fw::FW_DESERIALIZE_FORMAT_ERROR));
786+
787+
// 6. Cleanup
788+
Os::FileSystem::removeFile(stateFile.toChar());
789+
this->component.shutdown();
790+
}
791+
754792
void DpCatalogTester::test_TruncatedDpRejected() {
755793
Fw::MallocAllocator alloc;
756794
Fw::FileNameString dir("./DpTest_TruncatedDpRejected");

Svc/DpCatalog/test/ut/DpCatalogTester.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class DpCatalogTester : public DpCatalogGTestBase {
149149
void test_PingIn();
150150
void test_BadFileDone();
151151
void test_ProcessFileInvalidDir();
152+
void test_MalformedFile();
152153
void test_TruncatedDpRejected();
153154
void test_NonCanonicalDpRejected();
154155
void test_BadHeaderHashRejected();

0 commit comments

Comments
 (0)