diff --git a/firmware/console/binary/FragmentEntry.cpp b/firmware/console/binary/FragmentEntry.cpp index 0887adda35..0dc4e3c8af 100644 --- a/firmware/console/binary/FragmentEntry.cpp +++ b/firmware/console/binary/FragmentEntry.cpp @@ -11,11 +11,13 @@ /** * copy dataLength of fragmented outputs starting at dataOffset into destination starting at zero */ -void copyRange(uint8_t *destination, FragmentEntry *fragments, size_t dataOffset, size_t dataLength) { +void copyRange(uint8_t *destination, + FragmentEntry *fragments, int fragmentsCount, + size_t dataOffset, size_t dataLength) { int fragmentIndex = 0; // scroll to starting fragment - while (dataOffset > fragments[fragmentIndex].size) { + while (dataOffset > fragments[fragmentIndex].size && fragmentIndex <= fragmentsCount) { dataOffset -= fragments[fragmentIndex].size; fragmentIndex ++; } @@ -23,9 +25,16 @@ void copyRange(uint8_t *destination, FragmentEntry *fragments, size_t dataOffset int destinationIndex = 0; while (dataLength > 0) { + if (fragmentIndex > fragmentsCount) { + // somehow we are past the end of fragments - fill with zeros + memset(destination + destinationIndex, 0, dataLength); + return; + } + int copyNowSize = minI(dataLength, fragments[fragmentIndex].size - dataOffset); const uint8_t *fromBase = fragments[fragmentIndex].data; if (fromBase == nullptr) { + // we have no buffer for this fragment - fill with zeroes memset(destination + destinationIndex, 0, copyNowSize); } else { memcpy(destination + destinationIndex, fromBase + dataOffset, copyNowSize); diff --git a/firmware/console/binary/FragmentEntry.h b/firmware/console/binary/FragmentEntry.h index 97fd4aaae6..cd11671b00 100644 --- a/firmware/console/binary/FragmentEntry.h +++ b/firmware/console/binary/FragmentEntry.h @@ -24,4 +24,6 @@ struct FragmentEntry { } }; -void copyRange(uint8_t *destination, FragmentEntry *fragments, size_t dataOffset, size_t dataLength); +void copyRange(uint8_t *destination, + FragmentEntry *fragments, int fragmentsCount, + size_t dataOffset, size_t dataLength); diff --git a/unit_tests/tests/test_scattered_outputs.cpp b/unit_tests/tests/test_scattered_outputs.cpp index 43d5a75c79..e7a74ca75b 100644 --- a/unit_tests/tests/test_scattered_outputs.cpp +++ b/unit_tests/tests/test_scattered_outputs.cpp @@ -11,22 +11,30 @@ static FragmentEntry fragments[] = { }; TEST(outputs, fragments) { + ASSERT_EQ(3, efi::size(fragments)); + uint8_t buffer[120]; { uint8_t expected[] = {9, 10, 11, 12, 13}; - copyRange(buffer, fragments, 8, 5); + copyRange(buffer, fragments, efi::size(fragments), 8, 5); EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected))); } { uint8_t expected[] = {13, 14, 15}; - copyRange(buffer, fragments, 12, 3); + copyRange(buffer, fragments, efi::size(fragments), 12, 3); EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected))); } { uint8_t expected[] = {15, 0, 0}; - copyRange(buffer, fragments, 14, 3); + copyRange(buffer, fragments, efi::size(fragments), 14, 3); + EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected))); + } + + { + uint8_t expected[] = {0, 0, 0}; + copyRange(buffer, fragments, efi::size(fragments), 114, 3); EXPECT_TRUE( 0 == std::memcmp(buffer, expected, sizeof(expected))); } }