From 9ea69dfbb753900473d7ba97a9d73c32b94853f9 Mon Sep 17 00:00:00 2001 From: Ykidia Date: Mon, 12 Jan 2026 16:55:12 +0300 Subject: [PATCH] Fix uniformByte() acts not exactly as when counting bytes if array is empty --- UEFITool/ffsfinder.cpp | 4 ++-- common/ffsparser.cpp | 12 ++++-------- common/nvramparser.cpp | 12 ++++++------ common/utility.cpp | 10 +++++++++- common/utility.h | 5 ++++- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/UEFITool/ffsfinder.cpp b/UEFITool/ffsfinder.cpp index 93385a094..58adfc2d9 100644 --- a/UEFITool/ffsfinder.cpp +++ b/UEFITool/ffsfinder.cpp @@ -37,7 +37,7 @@ USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray & return U_INVALID_PARAMETER; // Check for "all substrings" pattern - if (uniformByte(hexPattern) == '.') + if (isUniformByte(hexPattern, '.')) return U_SUCCESS; USTATUS ret = U_ITEM_NOT_FOUND; @@ -166,7 +166,7 @@ USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray & hexPattern.append(list.at(3)).append(list.at(4)); // Check for "all substrings" pattern - if (uniformByte(hexPattern) == '.') + if (isUniformByte(hexPattern, '.')) return U_SUCCESS; #if QT_VERSION_MAJOR >= 6 diff --git a/common/ffsparser.cpp b/common/ffsparser.cpp index ab6155033..46a6dd289 100644 --- a/common/ffsparser.cpp +++ b/common/ffsparser.cpp @@ -1156,7 +1156,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index) info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); // Check that remaining unparsed bytes are actually empty - if (uniformByte(freeSpace) == emptyByte) { // Free space + if (isUniformByte(freeSpace, emptyByte)) { // Free space // Add tree item model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); } @@ -1932,7 +1932,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index, const bool probe) // Check that we are at the empty space UByteArray header = volumeBody.mid(fileOffset, (int)std::min(sizeof(EFI_FFS_FILE_HEADER), (size_t)volumeBodySize - fileOffset)); - if (uniformByte(header) == emptyByte) { // Empty space + if (isUniformByte(header, emptyByte)) { // Empty space // Check volume usedSpace entry to be valid if (usedSpace > 0 && usedSpace == fileOffset + volumeHeaderSize) { if (model->hasEmptyParsingData(index) == false) { @@ -1946,7 +1946,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index, const bool probe) // Check free space to be actually free UByteArray freeSpace = volumeBody.mid(fileOffset); - if (uniformByte(freeSpace) != emptyByte) { + if (!isUniformByte(freeSpace, emptyByte)) { // Search for the first non-empty byte UINT32 i; UINT32 size = (UINT32)freeSpace.size(); @@ -2395,10 +2395,6 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index) UByteArray body = model->body(index); - // Zero-body pad file is fine - if (body.isEmpty()) - return U_SUCCESS; - // Check if all bytes of the file are empty // Obtain required information from parent file UINT8 emptyByte = 0xFF; @@ -2410,7 +2406,7 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index) } // Check if the whole padding file is empty - if (uniformByte(body) == emptyByte) + if (isUniformByte(body, emptyByte)) return U_SUCCESS; // Search for the first non-empty byte diff --git a/common/nvramparser.cpp b/common/nvramparser.cpp index 0d044208f..0801b624d 100644 --- a/common/nvramparser.cpp +++ b/common/nvramparser.cpp @@ -89,7 +89,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index, const bool probe) // Get info UString info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); - if (uniformByte(padding) == emptyByte) { // Free space + if (isUniformByte(padding, emptyByte)) { // Free space if (probe && nvar.size() == padding.size()) return U_STORES_NOT_FOUND; // Add tree item @@ -427,7 +427,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32 info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); // Check that remaining unparsed bytes are actually empty - if (uniformByte(freeSpace) == emptyByte) { // Free space + if (isUniformByte(freeSpace, emptyByte)) { // Free space // Add tree item model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); } @@ -630,7 +630,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32 info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); // Check that remaining unparsed bytes are actually empty - if (uniformByte(freeSpace) == emptyByte) { // Free space + if (isUniformByte(freeSpace, emptyByte)) { // Free space // Add tree item model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); } @@ -956,7 +956,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32 info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); // Check that remaining unparsed bytes are actually zeroes - if (uniformByte(freeSpace.left(freeSpace.size() - 4)) == 0) { // Free space, 4 last bytes are always CRC32 + if (isUniformByte(freeSpace.left(freeSpace.size() - 4), 0)) { // Free space, 4 last bytes are always CRC32 // Add tree item model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); } @@ -1126,7 +1126,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32 info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); // Check that remaining unparsed bytes are actually empty - if (uniformByte(freeSpace) == emptyByte) { // Free space + if (isUniformByte(freeSpace, emptyByte)) { // Free space // Add tree item model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); } @@ -1531,7 +1531,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32 UString info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); // Check that remaining unparsed bytes are actually empty - if (uniformByte(outerPadding) == emptyByte) { + if (isUniformByte(outerPadding, emptyByte)) { // Add tree item model->addItem(localOffset + previousStoreEndOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); } diff --git a/common/utility.cpp b/common/utility.cpp index e16aabe1a..13cf0ebf0 100755 --- a/common/utility.cpp +++ b/common/utility.cpp @@ -430,14 +430,22 @@ UINT32 calculateChecksum32(const UINT32* buffer, UINT32 bufferSize) } // Returns 0x00..0xFF if an array is filled by a single repeated value, and 0xFFFFFFFF if not -UINT32 uniformByte(const UByteArray& a) +UINT32 uniformByte(const UByteArray& a, const UINT32 rcIfEmpty) { + if (a.isEmpty()) + return rcIfEmpty; size_t s = a.size(); if ((s == 1) || (s > 1 && memcmp(a.constData(), a.constData() + 1, s - 1) == 0)) return (UINT8)a.at(0); return UINT32_MAX; } +// Returns true if an array is filled by a specified single repeated value or an array is empty +UINT32 isUniformByte(const UByteArray& a, const UINT8 value) +{ + return uniformByte(a, value) == value; +} + // Get padding type for a given padding UINT8 getPaddingType(const UByteArray & padding) { diff --git a/common/utility.h b/common/utility.h index fafbf2737..ca72f629a 100755 --- a/common/utility.h +++ b/common/utility.h @@ -65,7 +65,10 @@ UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize); UINT32 calculateChecksum32(const UINT32* buffer, UINT32 bufferSize); // Returns 0x00..0xFF if an array is filled by a single repeated value, and 0xFFFFFFFF if not -UINT32 uniformByte(const UByteArray& a); +UINT32 uniformByte(const UByteArray& a, const UINT32 rcIfEmpty = UINT32_MAX); + +// Returns true if an array is filled by a specified single repeated value or an array is empty +UINT32 isUniformByte(const UByteArray& a, const UINT8 value); // Returns padding type from it's contents UINT8 getPaddingType(const UByteArray & padding);