Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BaseTools/OverrideValidation: Sort files prior to hashing. #1145

Open
wants to merge 3 commits into
base: dev/202405
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 62 additions & 6 deletions BaseTools/Plugin/OverrideValidation/OverrideValidation.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import sys
from datetime import datetime, timezone, timedelta
from io import StringIO
import pathlib

#
# for now i want to keep this file as both a command line tool and a plugin for the Uefi Build system.
Expand Down Expand Up @@ -457,12 +458,13 @@ def override_hash_compare(self, thebuilder, version, hash, fullpath):
# Error out the unknown version
if (version == OVERRIDE_FORMAT_VERSION_1[0]):
hash_val = ModuleHashCal(fullpath)
if (hash_val != hash):
hash_val2 = ModuleHash2Cal(fullpath)
if (hash_val != hash and hash_val2 != hash):
result = self.OverrideResult.OR_FILE_CHANGE
else:
# Should not happen
result = self.OverrideResult.OR_VER_UNRECOG
return {'result':result, 'hash_val':hash_val}
return {'result':result, 'hash_val':hash_val2}
# END: override_hash_compare(self, thebuilder, version, hash, fullpath)

# Print the log after override validation is complete
Expand Down Expand Up @@ -613,6 +615,59 @@ def ModuleHashCal(path):
result = hash_obj.hexdigest()
return result

def ModuleHash2Cal(path):

apop5 marked this conversation as resolved.
Show resolved Hide resolved
sourcefileList = []
binaryfileList = []
hash_obj = hashlib.md5()

# Find the specific line of Sources section
folderpath = os.path.dirname(path)

if os.path.isdir(path):
# Collect all files in this folder to the list
for subdir, _, files in os.walk(path):
for file in files:
sourcefileList.append(os.path.join(subdir, file))
else:
sourcefileList.append(path)

if path.lower().endswith(".inf") and os.path.isfile(path):

# Use InfParser to parse sources section
ip = InfParser()
ip.ParseFile(path)

# Add all referenced source files in addition to our inf file list
for source in ip.Sources:
sourcefileList.append(os.path.normpath(os.path.join(folderpath, source)))

# Add all referenced binary files to our binary file list
for binary in ip.Binaries:
binaryfileList.append(os.path.normpath(os.path.join(folderpath, binary)))

# Convert to '/' path separator prior to sorting to avoid ordering mismatches
sourcefileList = [pathlib.Path(sfile).as_posix() for sfile in sourcefileList]
binaryfileList = [pathlib.Path(sfile).as_posix() for bfile in binaryfileList]

sourcefileList.sort()
binaryfileList.sort()

for sfile in sourcefileList:
# print('Calculated: %s' %(sfile)) #Debug only
apop5 marked this conversation as resolved.
Show resolved Hide resolved
with open(os.path.normpath(sfile), 'rb') as entry:
# replace \r\n with \n to take care of line terminators
hash_obj.update(entry.read().replace(b'\r\n', b'\n'))

for bfile in binaryfileList:
# print('Calculated: %s' %(bfile)) #Debug only
apop5 marked this conversation as resolved.
Show resolved Hide resolved
with open(os.path.normpath(bfile), 'rb') as entry:
hash_obj.update(entry.read())

result = hash_obj.hexdigest()
return result


def ModuleGitPatch(path, git_hash):
''' return a git patch of the given file since the hash '''
GitOutput = io.StringIO()
Expand Down Expand Up @@ -767,15 +822,16 @@ def path_parse():
abs_path = pathtool.GetAbsolutePathOnThisSystemFromEdk2RelativePath(rel_path)
if abs_path is not None:
mod_hash = ModuleHashCal(abs_path)
mod_hash2 = ModuleHash2Cal(abs_path)
# only update the line if the hash has changed - this ensures the timestamp tracks actual changes rather than last time it was run.
if (mod_hash != match.group(4)):
if (mod_hash != match.group(4) and mod_hash2 != match.group(4)):
VERSION_INDEX = Paths.Version - 1

if VERSION_INDEX == 0:
line = '#%s : %08d | %s | %s | %s\n' % (match.group(1), OVERRIDE_FORMAT_VERSION_1[0], rel_path, mod_hash, datetime.now(timezone.utc).strftime(TIMESTAMP_FORMAT))
line = '#%s : %08d | %s | %s | %s\n' % (match.group(1), OVERRIDE_FORMAT_VERSION_1[0], rel_path, mod_hash2, datetime.now(timezone.utc).strftime(TIMESTAMP_FORMAT))
apop5 marked this conversation as resolved.
Show resolved Hide resolved
elif VERSION_INDEX == 1:
git_hash = ModuleGitHash(abs_path)
line = '#%s : %08d | %s | %s | %s | %s\n' % (match.group(1), OVERRIDE_FORMAT_VERSION_2[0], rel_path, mod_hash, datetime.now(timezone.utc).strftime(TIMESTAMP_FORMAT), git_hash)
line = '#%s : %08d | %s | %s | %s | %s\n' % (match.group(1), OVERRIDE_FORMAT_VERSION_2[0], rel_path, mod_hash2, datetime.now(timezone.utc).strftime(TIMESTAMP_FORMAT), git_hash)
apop5 marked this conversation as resolved.
Show resolved Hide resolved
print("Updating:\n" + line)
else:
print(f"Warning: Could not resolve relative path {rel_path}. Override line not updated.\n")
Expand Down Expand Up @@ -825,7 +881,7 @@ def path_parse():
sys.exit(1)

rel_path = rel_path.replace('\\', '/')
mod_hash = ModuleHashCal(Paths.TargetPath)
mod_hash = ModuleHash2Cal(Paths.TargetPath)

VERSION_INDEX = Paths.Version - 1

Expand Down
Loading