Skip to content

Commit

Permalink
Support unpacking wheels that contain files with commas in their names (
Browse files Browse the repository at this point in the history
#427)

The csv module is now being used to read RECORD.

Co-authored-by: Alex Grönholm <alex.gronholm@nextday.fi>
  • Loading branch information
hoodmane and agronholm committed Dec 22, 2021
1 parent 0acd203 commit 5846dac
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 18 deletions.
46 changes: 29 additions & 17 deletions src/wheel/wheelfile.py
Expand Up @@ -5,6 +5,7 @@
import os.path
import re
import stat
import sys
import time
from collections import OrderedDict
from distutils import log as logger
Expand All @@ -13,6 +14,16 @@
from wheel.cli import WheelError
from wheel.util import urlsafe_b64decode, as_unicode, native, urlsafe_b64encode, as_bytes, StringIO

if sys.version_info >= (3,):
from io import TextIOWrapper

def read_csv(fp):
return csv.reader(TextIOWrapper(fp, newline='', encoding='utf-8'))
else:
def read_csv(fp):
for line in csv.reader(fp):
yield [column.decode('utf-8') for column in line]

# Non-greedy matching of an optional build number may be too clever (more
# invalid wheel filenames will match). Separate regex for .dist-info?
WHEEL_INFO_RE = re.compile(
Expand Down Expand Up @@ -60,23 +71,24 @@ def __init__(self, file, mode='r', compression=ZIP_DEFLATED):
raise WheelError('Missing {} file'.format(self.record_path))

with record:
for line in record:
line = line.decode('utf-8')
path, hash_sum, size = line.rsplit(u',', 2)
if hash_sum:
algorithm, hash_sum = hash_sum.split(u'=')
try:
hashlib.new(algorithm)
except ValueError:
raise WheelError('Unsupported hash algorithm: {}'.format(algorithm))

if algorithm.lower() in {'md5', 'sha1'}:
raise WheelError(
'Weak hash algorithm ({}) is not permitted by PEP 427'
.format(algorithm))

self._file_hashes[path] = (
algorithm, urlsafe_b64decode(hash_sum.encode('ascii')))
for line in read_csv(record):
path, hash_sum, size = line
if not hash_sum:
continue

algorithm, hash_sum = hash_sum.split(u'=')
try:
hashlib.new(algorithm)
except ValueError:
raise WheelError('Unsupported hash algorithm: {}'.format(algorithm))

if algorithm.lower() in {'md5', 'sha1'}:
raise WheelError(
'Weak hash algorithm ({}) is not permitted by PEP 427'
.format(algorithm))

self._file_hashes[path] = (
algorithm, urlsafe_b64decode(hash_sum.encode('ascii')))

def open(self, name_or_info, mode="r", pwd=None):
def _update_crc(newdata, eof=None):
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Expand Up @@ -12,7 +12,7 @@
@pytest.fixture(scope='session')
def wheels_and_eggs(tmpdir_factory):
"""Build wheels and eggs from test distributions."""
test_distributions = "complex-dist", "simple.dist", "headers.dist"
test_distributions = "complex-dist", "simple.dist", "headers.dist", "commasinfilenames.dist"
if sys.version_info >= (3, 6):
# Only Python 3.6+ can handle packaging unicode file names reliably
# across different platforms
Expand Down
Empty file.
Empty file.
Empty file.
12 changes: 12 additions & 0 deletions tests/testdata/commasinfilenames.dist/setup.py
@@ -0,0 +1,12 @@
from setuptools import setup

setup(
name='testrepo',
version='0.1',
packages=["mypackage"],
description='A test package with commas in file names',
include_package_data=True,
package_data={
"mypackage.data": ["*"]
},
)
Empty file.

0 comments on commit 5846dac

Please sign in to comment.