From 8a7fe7b9424484258c32c803340d717c8406cb9c Mon Sep 17 00:00:00 2001 From: Miklos Marton Date: Wed, 8 Jan 2025 22:04:02 +0100 Subject: [PATCH] iop parsing: make the PictureObject data size check less restricitve The standard says: "If the data are longer than expected after all of the rows and columns of pixels have been defined, then the VT shall ignore all extra data bytes." So the parsed raw data size does not need to be equal to the image dimension it could be bigger. I also came across an implement (Kverneland Andex1304) which contains a PictureGraphics with 0x0 actual size and 0 raw data size. Later it also contained it later with correct dimensions, but the parser bailed out on the first zero size. --- .../isobus_virtual_terminal_working_set_base.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/isobus/src/isobus_virtual_terminal_working_set_base.cpp b/isobus/src/isobus_virtual_terminal_working_set_base.cpp index dab35057..e964dbea 100644 --- a/isobus/src/isobus_virtual_terminal_working_set_base.cpp +++ b/isobus/src/isobus_virtual_terminal_working_set_base.cpp @@ -2210,12 +2210,14 @@ namespace isobus { if (iopLength >= tempObject->get_number_of_bytes_in_raw_data()) { + std::uint32_t dataCounter = 0; switch (tempObject->get_format()) { case PictureGraphic::Format::EightBitColour: { tempObject->set_raw_data(iopData, tempObject->get_number_of_bytes_in_raw_data()); iopData += tempObject->get_number_of_bytes_in_raw_data(); + dataCounter += tempObject->get_number_of_bytes_in_raw_data(); iopLength -= tempObject->get_number_of_bytes_in_raw_data(); } break; @@ -2244,6 +2246,7 @@ namespace isobus lineAmountLeft = tempObject->get_actual_width(); } iopData++; + dataCounter++; iopLength--; } } @@ -2271,11 +2274,18 @@ namespace isobus lineAmountLeft = tempObject->get_actual_width(); } iopData++; + dataCounter++; iopLength--; } } break; } + + if (dataCounter < tempObject->get_number_of_bytes_in_raw_data()) + { + iopData += (tempObject->get_number_of_bytes_in_raw_data() - dataCounter); + iopLength += (tempObject->get_number_of_bytes_in_raw_data() - dataCounter); + } } else { @@ -2294,9 +2304,7 @@ namespace isobus CANStackLogger::warn("[WS]: Skipped parsing macro reference in picture graphic object (todo)"); } - if ((0 != tempObject->get_actual_width()) && - (0 != tempObject->get_actual_height()) && - (tempObject->get_raw_data().size() == (tempObject->get_actual_width() * tempObject->get_actual_height()))) + if (tempObject->get_raw_data().size() <= (tempObject->get_actual_width() * tempObject->get_actual_height())) { retVal = true; }