Skip to content

Commit 3ea1e5c

Browse files
author
nao0105aaa
authored
Merge branch 'python:3.10' into 3.10
2 parents 623a6eb + 1df5d00 commit 3ea1e5c

35 files changed

+1735
-343
lines changed

Doc/library/os.path.rst

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,26 @@ the :mod:`glob` module.)
352352
links encountered in the path (if they are supported by the operating
353353
system).
354354

355-
If a path doesn't exist or a symlink loop is encountered, and *strict* is
356-
``True``, :exc:`OSError` is raised. If *strict* is ``False``, the path is
357-
resolved as far as possible and any remainder is appended without checking
358-
whether it exists.
355+
By default, the path is evaluated up to the first component that does not
356+
exist, is a symlink loop, or whose evaluation raises :exc:`OSError`.
357+
All such components are appended unchanged to the existing part of the path.
358+
359+
Some errors that are handled this way include "access denied", "not a
360+
directory", or "bad argument to internal function". Thus, the
361+
resulting path may be missing or inaccessible, may still contain
362+
links or loops, and may traverse non-directories.
363+
364+
This behavior can be modified by keyword arguments:
365+
366+
If *strict* is ``True``, the first error encountered when evaluating the path is
367+
re-raised.
368+
In particular, :exc:`FileNotFoundError` is raised if *path* does not exist,
369+
or another :exc:`OSError` if it is otherwise inaccessible.
370+
371+
If *strict* is :py:data:`os.path.ALLOW_MISSING`, errors other than
372+
:exc:`FileNotFoundError` are re-raised (as with ``strict=True``).
373+
Thus, the returned path will not contain any symbolic links, but the named
374+
file and some of its parent directories may be missing.
359375

360376
.. note::
361377
This function emulates the operating system's procedure for making a path
@@ -374,6 +390,15 @@ the :mod:`glob` module.)
374390
.. versionchanged:: 3.10
375391
The *strict* parameter was added.
376392

393+
.. versionchanged:: 3.10.18
394+
The :py:data:`~os.path.ALLOW_MISSING` value for the *strict* parameter
395+
was added.
396+
397+
.. data:: ALLOW_MISSING
398+
399+
Special value used for the *strict* argument in :func:`realpath`.
400+
401+
.. versionadded:: 3.10.18
377402

378403
.. function:: relpath(path, start=os.curdir)
379404

Doc/library/tarfile.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,15 @@ The :mod:`tarfile` module defines the following exceptions:
237237
Raised to refuse extracting a symbolic link pointing outside the destination
238238
directory.
239239

240+
.. exception:: LinkFallbackError
241+
242+
Raised to refuse emulating a link (hard or symbolic) by extracting another
243+
archive member, when that member would be rejected by the filter location.
244+
The exception that was raised to reject the replacement member is available
245+
as :attr:`!BaseException.__context__`.
246+
247+
.. versionadded:: 3.10.18
248+
240249

241250
The following constants are available at the module level:
242251

@@ -954,6 +963,12 @@ reused in custom filters:
954963
Implements the ``'data'`` filter.
955964
In addition to what ``tar_filter`` does:
956965

966+
- Normalize link targets (:attr:`TarInfo.linkname`) using
967+
:func:`os.path.normpath`.
968+
Note that this removes internal ``..`` components, which may change the
969+
meaning of the link if the path in :attr:`!TarInfo.linkname` traverses
970+
symbolic links.
971+
957972
- :ref:`Refuse <tarfile-extraction-refuse>` to extract links (hard or soft)
958973
that link to absolute paths, or ones that link outside the destination.
959974

@@ -982,6 +997,10 @@ reused in custom filters:
982997

983998
Return the modified ``TarInfo`` member.
984999

1000+
.. versionchanged:: 3.10.18
1001+
1002+
Link targets are now normalized.
1003+
9851004

9861005
.. _tarfile-extraction-refuse:
9871006

@@ -1008,6 +1027,7 @@ Here is an incomplete list of things to consider:
10081027
* Extract to a :func:`new temporary directory <tempfile.mkdtemp>`
10091028
to prevent e.g. exploiting pre-existing links, and to make it easier to
10101029
clean up after a failed extraction.
1030+
* Disallow symbolic links if you do not need the functionality.
10111031
* When working with untrusted data, use external (e.g. OS-level) limits on
10121032
disk, memory and CPU usage.
10131033
* Check filenames against an allow-list of characters

Doc/whatsnew/3.10.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,3 +2394,37 @@ email
23942394
check if the *strict* paramater is available.
23952395
(Contributed by Thomas Dwyer and Victor Stinner for :gh:`102988` to improve
23962396
the CVE-2023-27043 fix.)
2397+
2398+
2399+
Notable changes in 3.10.18
2400+
==========================
2401+
2402+
os.path
2403+
-------
2404+
2405+
* The *strict* parameter to :func:`os.path.realpath` accepts a new value,
2406+
:data:`os.path.ALLOW_MISSING`.
2407+
If used, errors other than :exc:`FileNotFoundError` will be re-raised;
2408+
the resulting path can be missing but it will be free of symlinks.
2409+
(Contributed by Petr Viktorin for CVE 2025-4517.)
2410+
2411+
tarfile
2412+
-------
2413+
2414+
* :func:`~tarfile.data_filter` now normalizes symbolic link targets in order to
2415+
avoid path traversal attacks.
2416+
(Contributed by Petr Viktorin in :gh:`127987` and CVE 2025-4138.)
2417+
* :func:`~tarfile.TarFile.extractall` now skips fixing up directory attributes
2418+
when a directory was removed or replaced by another kind of file.
2419+
(Contributed by Petr Viktorin in :gh:`127987` and CVE 2024-12718.)
2420+
* :func:`~tarfile.TarFile.extract` and :func:`~tarfile.TarFile.extractall`
2421+
now (re-)apply the extraction filter when substituting a link (hard or
2422+
symbolic) with a copy of another archive member, and when fixing up
2423+
directory attributes.
2424+
The former raises a new exception, :exc:`~tarfile.LinkFallbackError`.
2425+
(Contributed by Petr Viktorin for CVE 2025-4330 and CVE 2024-12718.)
2426+
* :func:`~tarfile.TarFile.extract` and :func:`~tarfile.TarFile.extractall`
2427+
no longer extract rejected members when
2428+
:func:`~tarfile.TarFile.errorlevel` is zero.
2429+
(Contributed by Matt Prodani and Petr Viktorin in :gh:`112887`
2430+
and CVE 2025-4435.)

Include/cpython/bytesobject.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ PyAPI_FUNC(PyObject*) _PyBytes_FromHex(
2525
int use_bytearray);
2626

2727
/* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */
28+
PyAPI_FUNC(PyObject*) _PyBytes_DecodeEscape2(const char *, Py_ssize_t,
29+
const char *,
30+
int *, const char **);
31+
// Export for binary compatibility.
2832
PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t,
2933
const char *, const char **);
3034

Include/cpython/unicodeobject.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,19 @@ PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeStateful(
844844

845845
/* Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape
846846
chars. */
847+
PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal2(
848+
const char *string, /* Unicode-Escape encoded string */
849+
Py_ssize_t length, /* size of string */
850+
const char *errors, /* error handling */
851+
Py_ssize_t *consumed, /* bytes consumed */
852+
int *first_invalid_escape_char, /* on return, if not -1, contain the first
853+
invalid escaped char (<= 0xff) or invalid
854+
octal escape (> 0xff) in string. */
855+
const char **first_invalid_escape_ptr); /* on return, if not NULL, may
856+
point to the first invalid escaped
857+
char in string.
858+
May be NULL if errors is not NULL. */
859+
// Export for binary compatibility.
847860
PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal(
848861
const char *string, /* Unicode-Escape encoded string */
849862
Py_ssize_t length, /* size of string */

Include/patchlevel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
/*--start constants--*/
1919
#define PY_MAJOR_VERSION 3
2020
#define PY_MINOR_VERSION 10
21-
#define PY_MICRO_VERSION 17
21+
#define PY_MICRO_VERSION 18
2222
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL
2323
#define PY_RELEASE_SERIAL 0
2424

2525
/* Version as a string */
26-
#define PY_VERSION "3.10.17+"
26+
#define PY_VERSION "3.10.18+"
2727
/*--end constants--*/
2828

2929
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.

Lib/ensurepip/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
__all__ = ["version", "bootstrap"]
1313
_PACKAGE_NAMES = ('setuptools', 'pip')
14-
_SETUPTOOLS_VERSION = "65.5.0"
14+
_SETUPTOOLS_VERSION = "79.0.1"
1515
_PIP_VERSION = "23.0.1"
1616
_PROJECTS = [
1717
("setuptools", _SETUPTOOLS_VERSION, "py3"),
-1.18 MB
Binary file not shown.
1.2 MB
Binary file not shown.

Lib/genericpath.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
1010
'getsize', 'isdir', 'isfile', 'samefile', 'sameopenfile',
11-
'samestat']
11+
'samestat', 'ALLOW_MISSING']
1212

1313

1414
# Does a path exist?
@@ -153,3 +153,12 @@ def _check_arg_types(funcname, *args):
153153
f'os.PathLike object, not {s.__class__.__name__!r}') from None
154154
if hasstr and hasbytes:
155155
raise TypeError("Can't mix strings and bytes in path components") from None
156+
157+
# A singleton with a true boolean value.
158+
@object.__new__
159+
class ALLOW_MISSING:
160+
"""Special value for use in realpath()."""
161+
def __repr__(self):
162+
return 'os.path.ALLOW_MISSING'
163+
def __reduce__(self):
164+
return self.__class__.__name__

0 commit comments

Comments
 (0)