Skip to content

Commit 732d85f

Browse files
committed
Replace counting bytes by memcmp
1 parent 152bfb1 commit 732d85f

File tree

6 files changed

+50
-52
lines changed

6 files changed

+50
-52
lines changed

common/ffsparser.cpp

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -709,15 +709,11 @@ USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset
709709
bool versionFound = true;
710710
bool emptyRegion = false;
711711
// Check for empty region
712-
if (me.size() == me.count('\xFF')) {
712+
auto c = checkSingleByte(me);
713+
if (c <= UINT8_MAX) {
713714
// Further parsing not needed
714715
emptyRegion = true;
715-
info += ("\nState: empty (FFh)");
716-
}
717-
else if (me.size() == me.count('\x00')) {
718-
// Further parsing not needed
719-
emptyRegion = true;
720-
info += ("\nState: empty (00h)");
716+
info += usprintf("\nState: empty (%02Xh)", (UINT8)c);
721717
}
722718
else {
723719
// Search for new signature
@@ -778,17 +774,13 @@ USTATUS FfsParser::parsePdrRegion(const UByteArray & pdr, const UINT32 localOffs
778774

779775
// Check for empty region
780776
bool emptyRegion = false;
781-
if (pdr.size() == pdr.count('\xFF')) {
782-
// Further parsing not needed
783-
emptyRegion = true;
784-
info += ("\nState: empty (FFh)");
785-
}
786-
else if (pdr.size() == pdr.count('\x00')) {
777+
auto c = checkSingleByte(pdr);
778+
if (c <= UINT8_MAX) {
787779
// Further parsing not needed
788780
emptyRegion = true;
789-
info += ("\nState: empty (00h)");
781+
info += usprintf("\nState: empty (%02Xh)", (UINT8)c);
790782
}
791-
783+
792784
// Add tree item
793785
index = model->addItem(localOffset, Types::Region, Subtypes::PdrRegion, name, UString(), info, UByteArray(), pdr, UByteArray(), Fixed, parent);
794786

@@ -814,15 +806,11 @@ USTATUS FfsParser::parseDevExp1Region(const UByteArray & devExp1, const UINT32 l
814806

815807
// Check for empty region
816808
bool emptyRegion = false;
817-
if (devExp1.size() == devExp1.count('\xFF')) {
809+
auto c = checkSingleByte(devExp1);
810+
if (c <= UINT8_MAX) {
818811
// Further parsing not needed
819812
emptyRegion = true;
820-
info += ("\nState: empty (FFh)");
821-
}
822-
else if (devExp1.size() == devExp1.count('\x00')) {
823-
// Further parsing not needed
824-
emptyRegion = true;
825-
info += ("\nState: empty (00h)");
813+
info += usprintf("\nState: empty (%02Xh)", (UINT8)c);
826814
}
827815

828816
// Add tree item
@@ -846,17 +834,13 @@ USTATUS FfsParser::parseGenericRegion(const UINT8 subtype, const UByteArray & re
846834

847835
// Check for empty region
848836
bool emptyRegion = false;
849-
if (region.size() == region.count('\xFF')) {
850-
// Further parsing not needed
851-
emptyRegion = true;
852-
info += ("\nState: empty (FFh)");
853-
}
854-
else if (region.size() == region.count('\x00')) {
837+
auto c = checkSingleByte(region);
838+
if (c <= UINT8_MAX) {
855839
// Further parsing not needed
856840
emptyRegion = true;
857-
info += ("\nState: empty (00h)");
841+
info += usprintf("\nState: empty (%02Xh)", (UINT8)c);
858842
}
859-
843+
860844
// Add tree item
861845
index = model->addItem(localOffset, Types::Region, subtype, name, UString(), info, UByteArray(), region, UByteArray(), Fixed, parent);
862846

@@ -1166,7 +1150,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
11661150
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
11671151

11681152
// Check that remaining unparsed bytes are actually empty
1169-
if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space
1153+
if (checkSingleByte(freeSpace) == emptyByte) { // Free space
11701154
// Add tree item
11711155
model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
11721156
}
@@ -1972,7 +1956,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
19721956

19731957
// Check that we are at the empty space
19741958
UByteArray header = volumeBody.mid(fileOffset, (int)std::min(sizeof(EFI_FFS_FILE_HEADER), (size_t)volumeBodySize - fileOffset));
1975-
if (header.count(emptyByte) == header.size()) { //Empty space
1959+
if (checkSingleByte(header) == emptyByte) { // Empty space
19761960
// Check volume usedSpace entry to be valid
19771961
if (usedSpace > 0 && usedSpace == fileOffset + volumeHeaderSize) {
19781962
if (model->hasEmptyParsingData(index) == false) {
@@ -1986,7 +1970,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
19861970

19871971
// Check free space to be actually free
19881972
UByteArray freeSpace = volumeBody.mid(fileOffset);
1989-
if (freeSpace.count(emptyByte) != freeSpace.size()) {
1973+
if (checkSingleByte(freeSpace) != emptyByte) {
19901974
// Search for the first non-empty byte
19911975
UINT32 i;
19921976
UINT32 size = (UINT32)freeSpace.size();
@@ -2440,7 +2424,7 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index)
24402424
}
24412425

24422426
// Check if the while padding file is empty
2443-
if (body.size() == body.count(emptyByte))
2427+
if (checkSingleByte(body) == emptyByte)
24442428
return U_SUCCESS;
24452429

24462430
// Search for the first non-empty byte
@@ -4501,7 +4485,8 @@ USTATUS FfsParser::parseMicrocodeVolumeBody(const UModelIndex & index)
45014485
UByteArray ucode = model->body(index).mid(offset);
45024486

45034487
// Check for empty area
4504-
if (ucode.size() == ucode.count('\xFF') || ucode.size() == ucode.count('\x00')) {
4488+
auto c = checkSingleByte(ucode);
4489+
if (c == 0 || c == 0xFF) {
45054490
result = U_INVALID_MICROCODE;
45064491
}
45074492
else {

common/fitparser.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -709,8 +709,8 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
709709
else {
710710
// Add postIbbHash protected range
711711
UByteArray postIbbHash(ibbs_body->post_ibb_hash()->hash().data(), ibbs_body->post_ibb_hash()->len_hash());
712-
if (postIbbHash.count('\x00') != postIbbHash.size()
713-
&& postIbbHash.count('\xFF') != postIbbHash.size()) {
712+
auto c = checkSingleByte(postIbbHash);
713+
if (c != 0 && c != 0xFF) {
714714
PROTECTED_RANGE range = {};
715715
range.Type = PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB;
716716
range.AlgorithmId = ibbs_body->post_ibb_hash()->hash_algorithm_id();
@@ -990,8 +990,8 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
990990
else {
991991
// Add postIbbHash protected range
992992
UByteArray postIbbHash(ibbs_body->post_ibb_digest()->hash().data(), ibbs_body->post_ibb_digest()->len_hash());
993-
if (postIbbHash.count('\x00') != postIbbHash.size()
994-
&& postIbbHash.count('\xFF') != postIbbHash.size()) {
993+
auto c = checkSingleByte(postIbbHash);
994+
if (c != 0 && c != 0xFF) {
995995
PROTECTED_RANGE range = {};
996996
range.Type = PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB;
997997
range.AlgorithmId = ibbs_body->post_ibb_digest()->hash_algorithm_id();
@@ -1021,8 +1021,8 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
10211021

10221022
// Add ObbHash protected range
10231023
UByteArray obbHash(ibbs_body->obb_digest()->hash().data(), ibbs_body->obb_digest()->len_hash());
1024-
if (obbHash.count('\x00') != obbHash.size()
1025-
&& obbHash.count('\xFF') != obbHash.size()) {
1024+
auto c = checkSingleByte(obbHash);
1025+
if (c != 0 && c != 0xFF) {
10261026
PROTECTED_RANGE range = {};
10271027
range.Type = PROTECTED_RANGE_INTEL_BOOT_GUARD_OBB;
10281028
range.AlgorithmId = ibbs_body->obb_digest()->hash_algorithm_id();

common/nvramparser.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
8989
// Get info
9090
UString info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size());
9191

92-
if ((UINT32)padding.count(emptyByte) == unparsedSize) { // Free space
92+
if (checkSingleByte(padding) == emptyByte) { // Free space
9393
// Add tree item
9494
model->addItem(localOffset + entry->offset(), Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
9595
}
@@ -422,7 +422,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
422422
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
423423

424424
// Check that remaining unparsed bytes are actually empty
425-
if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space
425+
if (checkSingleByte(freeSpace) == emptyByte) { // Free space
426426
// Add tree item
427427
model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
428428
}
@@ -625,7 +625,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
625625
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
626626

627627
// Check that remaining unparsed bytes are actually empty
628-
if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space
628+
if (checkSingleByte(freeSpace) == emptyByte) { // Free space
629629
// Add tree item
630630
model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
631631
}
@@ -951,7 +951,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
951951
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
952952

953953
// Check that remaining unparsed bytes are actually zeroes
954-
if (freeSpace.count('\x00') == freeSpace.size() - 4) { // Free space, 4 last bytes are always CRC32
954+
if (checkSingleByte(freeSpace.left(freeSpace.size() - 4)) == 0) { // Free space, 4 last bytes are always CRC32
955955
// Add tree item
956956
model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
957957
}
@@ -1121,7 +1121,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
11211121
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
11221122

11231123
// Check that remaining unparsed bytes are actually empty
1124-
if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space
1124+
if (checkSingleByte(freeSpace) == emptyByte) { // Free space
11251125
// Add tree item
11261126
model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
11271127
}
@@ -1526,7 +1526,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
15261526
UString info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size());
15271527

15281528
// Check that remaining unparsed bytes are actually empty
1529-
if (outerPadding.count(emptyByte) == outerPadding.size()) {
1529+
if (checkSingleByte(outerPadding) == emptyByte) {
15301530
// Add tree item
15311531
model->addItem(localOffset + previousStoreEndOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index);
15321532
}

common/ubytearray.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ class UByteArray
4646
uint32_t toUInt(bool* ok = NULL, const uint8_t base = 10) { return (uint32_t)strtoul(d.c_str(), NULL, base); }
4747

4848
int32_t size() const { return (int32_t)d.size(); }
49-
int32_t count(char ch) const { return (int32_t)std::count(d.begin(), d.end(), ch); }
5049
char at(uint32_t i) const { return d.at(i); }
5150
char operator[](uint32_t i) const { return d[i]; }
5251
char& operator[](uint32_t i) { return d[i]; }

common/utility.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -429,13 +429,24 @@ UINT32 calculateChecksum32(const UINT32* buffer, UINT32 bufferSize)
429429
return (UINT32)(0x100000000ULL - counter);
430430
}
431431

432+
// Check if an array is filled in by a single repeated value
433+
UINT32 checkSingleByte(const UByteArray& a)
434+
{
435+
size_t s = a.size();
436+
if ((s == 1) || (s > 1 && memcmp(a.constData(), a.constData() + 1, s - 1) == 0))
437+
return (UINT8)a.at(0);
438+
return UINT32_MAX;
439+
}
440+
432441
// Get padding type for a given padding
433442
UINT8 getPaddingType(const UByteArray & padding)
434443
{
435-
if (padding.count('\x00') == padding.size())
436-
return Subtypes::ZeroPadding;
437-
if (padding.count('\xFF') == padding.size())
438-
return Subtypes::OnePadding;
444+
switch (checkSingleByte(padding)) {
445+
case 0:
446+
return Subtypes::ZeroPadding;
447+
case 0xFF:
448+
return Subtypes::OnePadding;
449+
}
439450
return Subtypes::DataPadding;
440451
}
441452

common/utility.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize);
5959
// 32bit checksum calculation routine
6060
UINT32 calculateChecksum32(const UINT32* buffer, UINT32 bufferSize);
6161

62+
// Check if an array is filled in by a single repeated value
63+
UINT32 checkSingleByte(const UByteArray& a);
64+
6265
// Returns padding type from it's contents
6366
UINT8 getPaddingType(const UByteArray & padding);
6467

0 commit comments

Comments
 (0)