Skip to content

Commit 773e47e

Browse files
authored
Merge branch '3.7' into tarfile-3.7
2 parents 64d1a92 + 1ce801b commit 773e47e

11 files changed

+73
-4
lines changed

.github/workflows/build.yml

+22-1
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,31 @@ jobs:
125125
runs-on: macos-latest
126126
needs: check_source
127127
if: needs.check_source.outputs.run_tests == 'true'
128+
env:
129+
HOMEBREW_NO_ANALYTICS: 1
130+
HOMEBREW_NO_AUTO_UPDATE: 1
131+
HOMEBREW_NO_INSTALL_CLEANUP: 1
128132
steps:
129133
- uses: actions/checkout@v2
130134
- name: Configure CPython
131-
run: SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-dev
135+
run: |
136+
brew install pkg-config [email protected] xz gdbm tcl-tk
137+
brew install zlib bzip2 ncurses readline sqlite
138+
SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk \
139+
CC=clang \
140+
CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include \
141+
-I$(brew --prefix zlib)/include -I$(brew --prefix bzip2)/include \
142+
-I$(brew --prefix ncurses)/include -I$(brew --prefix readline)/include \
143+
-I$(brew --prefix sqlite)/include" \
144+
LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib \
145+
-L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib \
146+
-L$(brew --prefix ncurses)/lib -L$(brew --prefix readline)/lib \
147+
-L$(brew --prefix sqlite)/lib" \
148+
./configure --prefix=/opt/python-dev \
149+
--with-pydebug \
150+
--with-openssl="$(brew --prefix [email protected])" \
151+
--with-tcltk-libs="$(pkg-config --libs tk)" \
152+
--with-tcltk-includes="$(pkg-config --cflags tk)"
132153
- name: Build CPython
133154
run: make -j4
134155
- name: Display build info

Lib/ensurepip/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
__all__ = ["version", "bootstrap"]
1010
_PACKAGE_NAMES = ('setuptools', 'pip')
1111
_SETUPTOOLS_VERSION = "47.1.0"
12-
_PIP_VERSION = "22.0.4"
12+
_PIP_VERSION = "23.0.1"
1313
_PROJECTS = [
1414
("setuptools", _SETUPTOOLS_VERSION, "py3"),
1515
("pip", _PIP_VERSION, "py3"),
Binary file not shown.
Binary file not shown.

Lib/http/server.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@ def list_directory(self, path):
777777
displaypath = urllib.parse.unquote(self.path,
778778
errors='surrogatepass')
779779
except UnicodeDecodeError:
780-
displaypath = urllib.parse.unquote(path)
780+
displaypath = urllib.parse.unquote(self.path)
781781
displaypath = html.escape(displaypath, quote=False)
782782
enc = sys.getfilesystemencoding()
783783
title = 'Directory listing for %s' % displaypath

Lib/test/test_httpservers.py

+8
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,14 @@ def test_undecodable_filename(self):
413413
self.check_status_and_reason(response, HTTPStatus.OK,
414414
data=support.TESTFN_UNDECODABLE)
415415

416+
def test_undecodable_parameter(self):
417+
# sanity check using a valid parameter
418+
response = self.request(self.base_url + '/?x=123').read()
419+
self.assertRegex(response, f'listing for {self.base_url}/\?x=123'.encode('latin1'))
420+
# now the bogus encoding
421+
response = self.request(self.base_url + '/?x=%bb').read()
422+
self.assertRegex(response, f'listing for {self.base_url}/\?x=\xef\xbf\xbd'.encode('latin1'))
423+
416424
def test_get_dir_redirect_location_domain_injection_bug(self):
417425
"""Ensure //evil.co/..%2f../../X does not put //evil.co/ in Location.
418426

Lib/test/test_uu.py

+28
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,34 @@ def test_newlines_escaped(self):
145145
uu.encode(inp, out, filename)
146146
self.assertIn(safefilename, out.getvalue())
147147

148+
def test_no_directory_traversal(self):
149+
relative_bad = b"""\
150+
begin 644 ../../../../../../../../tmp/test1
151+
$86)C"@``
152+
`
153+
end
154+
"""
155+
with self.assertRaisesRegex(uu.Error, 'directory'):
156+
uu.decode(io.BytesIO(relative_bad))
157+
if os.altsep:
158+
relative_bad_bs = relative_bad.replace(b'/', b'\\')
159+
with self.assertRaisesRegex(uu.Error, 'directory'):
160+
uu.decode(io.BytesIO(relative_bad_bs))
161+
162+
absolute_bad = b"""\
163+
begin 644 /tmp/test2
164+
$86)C"@``
165+
`
166+
end
167+
"""
168+
with self.assertRaisesRegex(uu.Error, 'directory'):
169+
uu.decode(io.BytesIO(absolute_bad))
170+
if os.altsep:
171+
absolute_bad_bs = absolute_bad.replace(b'/', b'\\')
172+
with self.assertRaisesRegex(uu.Error, 'directory'):
173+
uu.decode(io.BytesIO(absolute_bad_bs))
174+
175+
148176
class UUStdIOTest(unittest.TestCase):
149177

150178
def setUp(self):

Lib/uu.py

100755100644
+8-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,14 @@ def decode(in_file, out_file=None, mode=None, quiet=False):
130130
# If the filename isn't ASCII, what's up with that?!?
131131
out_file = hdrfields[2].rstrip(b' \t\r\n\f').decode("ascii")
132132
if os.path.exists(out_file):
133-
raise Error('Cannot overwrite existing file: %s' % out_file)
133+
raise Error(f'Cannot overwrite existing file: {out_file}')
134+
if (out_file.startswith(os.sep) or
135+
f'..{os.sep}' in out_file or (
136+
os.altsep and
137+
(out_file.startswith(os.altsep) or
138+
f'..{os.altsep}' in out_file))
139+
):
140+
raise Error(f'Refusing to write to {out_file} due to directory traversal')
134141
if mode is None:
135142
mode = int(hdrfields[1], 8)
136143
#
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade pip wheel bundled with ensurepip (pip 23.0.1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Do not expose the local on-disk location in directory indexes
2+
produced by :class:`http.client.SimpleHTTPRequestHandler`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed a security in flaw in :func:`uu.decode` that could allow for
2+
directory traversal based on the input if no ``out_file`` was specified.

0 commit comments

Comments
 (0)