Skip to content

Commit

Permalink
Merge pull request pypa#8656 from chrahunt/gracefully-handle-bad-data…
Browse files Browse the repository at this point in the history
…-paths

Trace a better error message on installation failure due to invalid .data files in wheels
  • Loading branch information
pradyunsg committed Aug 4, 2020
1 parent 552b837 commit ed205bd
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 2 deletions.
2 changes: 2 additions & 0 deletions news/8654.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Trace a better error message on installation failure due to invalid ``.data``
files in wheels.
24 changes: 22 additions & 2 deletions src/pip/_internal/operations/install/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,8 +594,28 @@ def data_scheme_file_maker(zip_file, scheme):
def make_data_scheme_file(record_path):
# type: (RecordPath) -> File
normed_path = os.path.normpath(record_path)
_, scheme_key, dest_subpath = normed_path.split(os.path.sep, 2)
scheme_path = scheme_paths[scheme_key]
try:
_, scheme_key, dest_subpath = normed_path.split(os.path.sep, 2)
except ValueError:
message = (
"Unexpected file in {}: {!r}. .data directory contents"
" should be named like: '<scheme key>/<path>'."
).format(wheel_path, record_path)
raise InstallationError(message)

try:
scheme_path = scheme_paths[scheme_key]
except KeyError:
valid_scheme_keys = ", ".join(sorted(scheme_paths))
message = (
"Unknown scheme key used in {}: {} (for file {!r}). .data"
" directory contents should be in subdirectories named"
" with a valid scheme key ({})"
).format(
wheel_path, scheme_key, record_path, valid_scheme_keys
)
raise InstallationError(message)

dest_path = os.path.join(scheme_path, dest_subpath)
assert_no_path_traversal(scheme_path, dest_path)
return ZipBackedFile(record_path, dest_path, zip_file)
Expand Down
33 changes: 33 additions & 0 deletions tests/functional/test_install_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -681,3 +681,36 @@ def test_correct_package_name_while_creating_wheel_bug(script, package_name):
package = create_basic_wheel_for_package(script, package_name, '1.0')
wheel_name = os.path.basename(package)
assert wheel_name == 'simple_package-1.0-py2.py3-none-any.whl'


@pytest.mark.parametrize("name", ["purelib", "abc"])
def test_wheel_with_file_in_data_dir_has_reasonable_error(
script, tmpdir, name
):
"""Normally we expect entities in the .data directory to be in a
subdirectory, but if they are not then we should show a reasonable error
message that includes the path.
"""
wheel_path = make_wheel(
"simple", "0.1.0", extra_data_files={name: "hello world"}
).save_to_dir(tmpdir)

result = script.pip(
"install", "--no-index", str(wheel_path), expect_error=True
)
assert "simple-0.1.0.data/{}".format(name) in result.stderr


def test_wheel_with_unknown_subdir_in_data_dir_has_reasonable_error(
script, tmpdir
):
wheel_path = make_wheel(
"simple",
"0.1.0",
extra_data_files={"unknown/hello.txt": "hello world"}
).save_to_dir(tmpdir)

result = script.pip(
"install", "--no-index", str(wheel_path), expect_error=True
)
assert "simple-0.1.0.data/unknown/hello.txt" in result.stderr

0 comments on commit ed205bd

Please sign in to comment.