Skip to content

Commit

Permalink
Cope with invalid hash algorithms in RECORD
Browse files Browse the repository at this point in the history
- raise an InvalidRecordEntry
- catch such things during wheel validation and include them in the
  issues reported
  • Loading branch information
dimbleby committed Apr 8, 2023
1 parent f89b5d9 commit 5d00415
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/installer/records.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ def from_elements(cls, path: str, hash_: str, size: str) -> "RecordEntry":
if hash_:
try:
hash_value: Optional[Hash] = Hash.parse(hash_)
if hash_value.name not in hashlib.algorithms_available:
issues.append(f"invalid hash algorithm '{hash_value.name}'")
hash_value = None
except ValueError:
issues.append("`hash` does not follow the required format")
else:
Expand Down
12 changes: 10 additions & 2 deletions src/installer/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from typing import BinaryIO, ClassVar, Iterator, List, Optional, Tuple, Type, cast

from installer.exceptions import InstallerError
from installer.records import RecordEntry, parse_record_file
from installer.records import InvalidRecordEntry, RecordEntry, parse_record_file
from installer.utils import canonicalize_name, parse_wheel_filename

WheelContentElement = Tuple[Tuple[str, str, str], BinaryIO, bool]
Expand Down Expand Up @@ -271,7 +271,15 @@ def validate_record(self, *, validate_contents: bool = True) -> None:
)
continue

record = RecordEntry.from_elements(*record_args)
try:
record = RecordEntry.from_elements(*record_args)
except InvalidRecordEntry as e:
for issue in e.issues:
issues.append(
f"In {self._zipfile.filename}, entry in RECORD file for "
f"{item.filename} is invalid: {issue}"
)
continue

if item.filename == f"{self.dist_info_dir}/RECORD":
# Assert that RECORD doesn't have size and hash.
Expand Down
21 changes: 21 additions & 0 deletions tests/test_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,3 +325,24 @@ def test_rejects_record_validation_failed(self, fancy_wheel):
match="hash / size of (.+) didn't match RECORD",
):
source.validate_record()

def test_rejects_record_containing_unknown_hash(self, fancy_wheel):
with WheelFile.open(fancy_wheel) as source:
record_file_contents = source.read_dist_info("RECORD")

new_record_file_contents = record_file_contents.replace("sha256=", "sha=")
replace_file_in_zip(
fancy_wheel,
filename="fancy-1.0.0.dist-info/RECORD",
content=new_record_file_contents,
)

with WheelFile.open(fancy_wheel) as source:
with pytest.raises(
WheelFile.validation_error,
match=(
"In .+, entry in RECORD file for .+ is invalid: "
"invalid hash algorithm 'sha'"
),
):
source.validate_record(validate_contents=True)

0 comments on commit 5d00415

Please sign in to comment.