From a330a0c9072f029bc4d1b2e8832052c108695e98 Mon Sep 17 00:00:00 2001 From: Dimitrios Stoupis <dimitris.apple@gmail.com> Date: Thu, 22 Nov 2018 11:46:57 +0000 Subject: [PATCH] Implement the octect string manipulations in a more memory safe way --- inc/Message.hpp | 15 ++++++--------- src/Services/MemoryManagementService.cpp | 22 ++++------------------ test/Services/MemoryManagementService.cpp | 8 ++++---- 3 files changed, 14 insertions(+), 31 deletions(-) diff --git a/inc/Message.hpp b/inc/Message.hpp index d471cd36..a6ad919d 100644 --- a/inc/Message.hpp +++ b/inc/Message.hpp @@ -400,20 +400,17 @@ public: /** * Fetches a N-byte string from the current position in the message * + * @details In the current implementation we assume that a preallocated array of + * sufficient size is provided as the argument + * @todo Specify if the provided array size is too small or too large + * * PTC = 7, PFC = 0 */ - uint8_t *readOctetString(uint16_t *length) { + uint16_t readOctetString(uint8_t *byteString) { uint16_t size = readUint16(); // Get the data length from the message - uint8_t *byteString = nullptr; // Pointer to store the string - - byteString = static_cast<uint8_t *>(malloc(size)); - if (byteString == nullptr) { - return nullptr; - } readString(byteString, size); // Read the string data - *length = size; // Save the data length to the provided variable - return byteString; // Return the read string pointer + return size; // Return the read string pointer } /** diff --git a/src/Services/MemoryManagementService.cpp b/src/Services/MemoryManagementService.cpp index 26de5566..cd84b3dd 100644 --- a/src/Services/MemoryManagementService.cpp +++ b/src/Services/MemoryManagementService.cpp @@ -26,7 +26,7 @@ void MemoryManagementService::RawDataMemoryManagement::loadRawData(Message &requ assert(request.messageType == 2); // Variable declaration - uint16_t dataLength = 0; // Data length to load + uint8_t readData[ECSS_MAX_STRING_SIZE]; // Preallocate the array uint8_t memoryID = request.readEnum8(); // Read the memory ID from the request uint16_t iterationCount = request.readUint16(); // Get the iteration count @@ -34,7 +34,7 @@ void MemoryManagementService::RawDataMemoryManagement::loadRawData(Message &requ if (memoryID == MemoryManagementService::MemoryID::RAM) { for (std::size_t j = 0; j < iterationCount; j++) { uint64_t startAddress = request.readUint64(); // Start address of the memory - uint8_t *readData = request.readOctetString(&dataLength); + uint16_t dataLength = request.readOctetString(readData); // Data length to load // todo: Error logging has to be included, if memory allocation above fails // todo: Continue only if the checksum passes (when the checksum will be implemented) @@ -56,7 +56,7 @@ void MemoryManagementService::RawDataMemoryManagement::dumpRawData(Message &requ Message report = mainService.createTM(6); // Variable declaration - uint8_t *readData = nullptr, *tempMemory = nullptr;; // Pointer to store the read data + uint8_t readData[ECSS_MAX_STRING_SIZE]; // Preallocate the array uint8_t memoryID = request.readEnum8(); // Read the memory ID from the request // todo: Add checks depending on the memory type @@ -68,23 +68,10 @@ void MemoryManagementService::RawDataMemoryManagement::dumpRawData(Message &requ report.appendUint16(iterationCount); // Iteration count // Iterate N times, as specified in the command message - for (std::size_t j = 0, allocatedLength = 0; j < iterationCount; j++) { + for (std::size_t j = 0; j < iterationCount; j++) { uint64_t startAddress = request.readUint64(); // Data length to read uint16_t readLength = request.readUint16(); // Start address for the memory read - // Allocate more array space if needed - if (allocatedLength < readLength) { - // todo: In embedded implementation use the malloc, due to FreeRTOS constraints - tempMemory = static_cast<uint8_t *>(realloc(readData, readLength)); - if (tempMemory == nullptr) { - // todo: Add error logging and reporting - free(readData); - } else { - readData = tempMemory; - allocatedLength = readLength; - } - } - // Read memory data, an octet at a time for (std::size_t i = 0; i < readLength; i++) { readData[i] = *(reinterpret_cast<uint8_t *>(startAddress) + i); @@ -98,5 +85,4 @@ void MemoryManagementService::RawDataMemoryManagement::dumpRawData(Message &requ mainService.storeMessage(report); // Save the report message request.resetRead(); // Reset the reading count - free(readData); // Free the allocated memory } diff --git a/test/Services/MemoryManagementService.cpp b/test/Services/MemoryManagementService.cpp index 8fb43736..d59c8de2 100644 --- a/test/Services/MemoryManagementService.cpp +++ b/test/Services/MemoryManagementService.cpp @@ -32,7 +32,7 @@ TEST_CASE("TM[6,5]", "[service][st06]") { uint8_t testString_2[8] = "SecStrT"; uint8_t testString_3[2] = {5, 8}; - uint8_t *checkString = nullptr; + uint8_t checkString[ECSS_MAX_STRING_SIZE]; uint16_t readSize = 0; MemoryManagementService memMangService; @@ -58,7 +58,7 @@ TEST_CASE("TM[6,5]", "[service][st06]") { CHECK(response.readEnum8() == MemoryManagementService::MemoryID::RAM); CHECK(response.readUint16() == 3); CHECK(response.readUint64() == reinterpret_cast<uint64_t >(testString_1)); - checkString = response.readOctetString(&readSize); + readSize = response.readOctetString(checkString); CHECK(readSize == sizeof(testString_1)/ sizeof(testString_1[0])); CHECK(checkString[0] == 'F'); CHECK(checkString[1] == 'S'); @@ -68,7 +68,7 @@ TEST_CASE("TM[6,5]", "[service][st06]") { CHECK(checkString[5] == '\0'); CHECK(response.readUint64() == reinterpret_cast<uint64_t >(testString_2)); - checkString = response.readOctetString(&readSize); + readSize = response.readOctetString(checkString); CHECK(readSize == sizeof(testString_2)/ sizeof(testString_2[0])); CHECK(checkString[0] == 'S'); CHECK(checkString[1] == 'e'); @@ -80,7 +80,7 @@ TEST_CASE("TM[6,5]", "[service][st06]") { CHECK(checkString[7] == '\0'); CHECK(response.readUint64() == reinterpret_cast<uint64_t >(testString_3)); - checkString = response.readOctetString(&readSize); + readSize = response.readOctetString(checkString); CHECK(readSize == sizeof(testString_3)/ sizeof(testString_3[0])); CHECK(checkString[0] == 5); CHECK(checkString[1] == 8); -- GitLab