Skip to content

Commit d87ff50

Browse files
generatedunixname1734921407115435meta-codesync[bot]
authored andcommitted
Import CPython 3.14.5+ stable branch (2026-05-11)
Summary: Imported python/cpython `3.14.5+` from upstream rev [`74cca9a`](https://www.github.com/python/cpython/commit/74cca9a92fb7d653e404843a56b8bdc7b0afdbbf) (committed 2026-05-11 09:57:50+00:00). # Commit Info Base: (`3.14.5rc1+`) - [`9d5857c`](https://www.github.com/python/cpython/commit/9d5857cfa363f67f1319c8bbb7626207f6896a52) (commit date: 2026-05-10 04:10:20+00:00) Imported: (`3.14.5+`) - [`74cca9a`](https://www.github.com/python/cpython/commit/74cca9a92fb7d653e404843a56b8bdc7b0afdbbf) (commit date: 2026-05-11 09:57:50+00:00) # Noteworthy file changes - Low-signal files (3 added, 13 removed) (NEWS.d, docs, .github) Complete list of added/removed files: https://www.internalfb.com/intern/everpaste/?color=0&handle=GNmifSPA55KZQc4PAIHSyzTV12Fabr0LAAAz Reviewed By: itamaro Differential Revision: D104683745 fbshipit-source-id: 018b0d9f06350a3dea56aa87d948942ee10aa507
1 parent 4507093 commit d87ff50

24 files changed

Lines changed: 281 additions & 65 deletions

Include/patchlevel.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
#define PY_MAJOR_VERSION 3
2121
#define PY_MINOR_VERSION 14
2222
#define PY_MICRO_VERSION 5
23-
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA
24-
#define PY_RELEASE_SERIAL 1
23+
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL
24+
#define PY_RELEASE_SERIAL 0
2525

2626
/* Version as a string */
27-
#define PY_VERSION "3.14.5rc1+meta"
27+
#define PY_VERSION "3.14.5+meta"
2828
/*--end constants--*/
2929

3030

Lib/pydoc_data/module_docs.py

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/pydoc_data/topics.py

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/tarfile.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -830,16 +830,22 @@ def _get_filtered_attrs(member, dest_path, for_data=True):
830830
if member.islnk() or member.issym():
831831
if os.path.isabs(member.linkname):
832832
raise AbsoluteLinkError(member)
833+
# A link member that resolves to the destination directory itself
834+
# would replace it with a (sym)link, redirecting the destination
835+
# for all subsequent members.
836+
if target_path == dest_path:
837+
raise OutsideDestinationError(member, target_path)
833838
normalized = os.path.normpath(member.linkname)
834839
if normalized != member.linkname:
835840
new_attrs['linkname'] = normalized
836841
if member.issym():
837-
target_path = os.path.join(dest_path,
838-
os.path.dirname(name),
839-
member.linkname)
842+
# The symlink is created at `name` with trailing separators
843+
# stripped, so its target is relative to the directory
844+
# containing that path.
845+
link_dir = os.path.dirname(name.rstrip('/' + os.sep))
846+
target_path = os.path.join(dest_path, link_dir, normalized)
840847
else:
841-
target_path = os.path.join(dest_path,
842-
member.linkname)
848+
target_path = os.path.join(dest_path, normalized)
843849
target_path = os.path.realpath(target_path,
844850
strict=os.path.ALLOW_MISSING)
845851
if os.path.commonpath([target_path, dest_path]) != dest_path:

Lib/test/test_pyexpat.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,20 @@ def test_change_size_2(self):
672672
parser.Parse(xml2, True)
673673
self.assertEqual(self.n, 4)
674674

675+
@support.requires_resource('cpu')
676+
@support.requires_resource('walltime')
677+
@support.bigmemtest(size=2**31, memuse=4, dry_run=False)
678+
def test_large_character_data_does_not_crash(self):
679+
# See https://github.com/python/cpython/issues/148441
680+
parser = expat.ParserCreate()
681+
parser.buffer_text = True
682+
parser.buffer_size = 2**31 - 1 # INT_MAX
683+
N = 2049 * (1 << 20) - 3 # Character data greater than INT_MAX
684+
self.assertGreater(N, parser.buffer_size)
685+
parser.CharacterDataHandler = lambda text: None
686+
xml_data = b"<r>" + b"A" * N + b"</r>"
687+
self.assertEqual(parser.Parse(xml_data, True), 1)
688+
675689
class ElementDeclHandlerTest(unittest.TestCase):
676690
def test_trigger_leak(self):
677691
# Unfixed, this test would leak the memory of the so-called

Lib/test/test_tarfile.py

Lines changed: 117 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3682,6 +3682,39 @@ class TestExtractionFilters(unittest.TestCase):
36823682
# The destination for the extraction, within `outerdir`
36833683
destdir = outerdir / 'dest'
36843684

3685+
@classmethod
3686+
def setUpClass(cls):
3687+
# Posix and Windows have different pathname resolution:
3688+
# either symlink or a '..' component resolve first.
3689+
# Let's see which we are on.
3690+
if os_helper.can_symlink():
3691+
testpath = os.path.join(TEMPDIR, 'resolution_test')
3692+
os.mkdir(testpath)
3693+
3694+
# testpath/current links to `.` which is all of:
3695+
# - `testpath`
3696+
# - `testpath/current`
3697+
# - `testpath/current/current`
3698+
# - etc.
3699+
os.symlink('.', os.path.join(testpath, 'current'))
3700+
3701+
# we'll test where `testpath/current/../file` ends up
3702+
with open(os.path.join(testpath, 'current', '..', 'file'), 'w'):
3703+
pass
3704+
3705+
if os.path.exists(os.path.join(testpath, 'file')):
3706+
# Windows collapses 'current\..' to '.' first, leaving
3707+
# 'testpath\file'
3708+
cls.dotdot_resolves_early = True
3709+
elif os.path.exists(os.path.join(testpath, '..', 'file')):
3710+
# Posix resolves 'current' to '.' first, leaving
3711+
# 'testpath/../file'
3712+
cls.dotdot_resolves_early = False
3713+
else:
3714+
raise AssertionError('Could not determine link resolution')
3715+
else:
3716+
cls.dotdot_resolves_early = False
3717+
36853718
@contextmanager
36863719
def check_context(self, tar, filter, *, check_flag=True):
36873720
"""Extracts `tar` to `self.destdir` and allows checking the result
@@ -3853,10 +3886,19 @@ def test_parent_symlink(self):
38533886
+ "which is outside the destination")
38543887

38553888
with self.check_context(arc.open(), 'data'):
3856-
self.expect_exception(
3857-
tarfile.LinkOutsideDestinationError,
3858-
"""'parent' would link to ['"].*outerdir['"], """
3859-
+ "which is outside the destination")
3889+
if self.dotdot_resolves_early:
3890+
# 'current/../..' normalises to '..', which is rejected.
3891+
self.expect_exception(
3892+
tarfile.LinkOutsideDestinationError,
3893+
"""'parent' would link to ['"].*outerdir['"], """
3894+
+ "which is outside the destination")
3895+
else:
3896+
# 'current/..' normalises to '.'; the rewritten link is
3897+
# created and 'parent/evil' lands harmlessly inside the
3898+
# destination.
3899+
self.expect_file('current', symlink_to='.')
3900+
self.expect_file('parent', symlink_to='.')
3901+
self.expect_file('evil')
38603902

38613903
else:
38623904
# No symlink support. The symlinks are ignored.
@@ -3946,35 +3988,6 @@ def test_parent_symlink2(self):
39463988
# Test interplaying symlinks
39473989
# Inspired by 'dirsymlink2b' in jwilk/traversal-archives
39483990

3949-
# Posix and Windows have different pathname resolution:
3950-
# either symlink or a '..' component resolve first.
3951-
# Let's see which we are on.
3952-
if os_helper.can_symlink():
3953-
testpath = os.path.join(TEMPDIR, 'resolution_test')
3954-
os.mkdir(testpath)
3955-
3956-
# testpath/current links to `.` which is all of:
3957-
# - `testpath`
3958-
# - `testpath/current`
3959-
# - `testpath/current/current`
3960-
# - etc.
3961-
os.symlink('.', os.path.join(testpath, 'current'))
3962-
3963-
# we'll test where `testpath/current/../file` ends up
3964-
with open(os.path.join(testpath, 'current', '..', 'file'), 'w'):
3965-
pass
3966-
3967-
if os.path.exists(os.path.join(testpath, 'file')):
3968-
# Windows collapses 'current\..' to '.' first, leaving
3969-
# 'testpath\file'
3970-
dotdot_resolves_early = True
3971-
elif os.path.exists(os.path.join(testpath, '..', 'file')):
3972-
# Posix resolves 'current' to '.' first, leaving
3973-
# 'testpath/../file'
3974-
dotdot_resolves_early = False
3975-
else:
3976-
raise AssertionError('Could not determine link resolution')
3977-
39783991
with ArchiveMaker() as arc:
39793992

39803993
# `current` links to `.` which is both the destination directory
@@ -4010,7 +4023,7 @@ def test_parent_symlink2(self):
40104023

40114024
with self.check_context(arc.open(), 'data'):
40124025
if os_helper.can_symlink():
4013-
if dotdot_resolves_early:
4026+
if self.dotdot_resolves_early:
40144027
# Fail when extracting a file outside destination
40154028
self.expect_exception(
40164029
tarfile.OutsideDestinationError,
@@ -4130,6 +4143,76 @@ def test_sly_relative2(self):
41304143
+ """['"].*moo['"], which is outside the """
41314144
+ "destination")
41324145

4146+
@symlink_test
4147+
@os_helper.skip_unless_symlink
4148+
def test_normpath_realpath_mismatch(self):
4149+
# The link-target check must validate the value that will actually
4150+
# be written to disk (the normalised linkname), not the original.
4151+
# Here 'a' is a symlink to a deep nonexistent path, so realpath()
4152+
# of 'a/../../...' stays inside the destination while normpath()
4153+
# collapses 'a/..' lexically and escapes.
4154+
depth = len(self.destdir.parts) + 5
4155+
deep = '/'.join(f'p{i}' for i in range(depth))
4156+
sneaky = 'a/' + '../' * depth + 'flag'
4157+
for kind in 'symlink_to', 'hardlink_to':
4158+
with self.subTest(kind):
4159+
with ArchiveMaker() as arc:
4160+
arc.add('a', symlink_to=deep)
4161+
arc.add('escape', **{kind: sneaky})
4162+
with self.check_context(arc.open(), 'data'):
4163+
self.expect_exception(
4164+
tarfile.LinkOutsideDestinationError)
4165+
4166+
@symlink_test
4167+
@os_helper.skip_unless_symlink
4168+
def test_symlink_trailing_slash(self):
4169+
# A trailing slash on a symlink member's name must not cause the
4170+
# link target to be resolved relative to the wrong directory.
4171+
with ArchiveMaker() as arc:
4172+
t = tarfile.TarInfo('x/')
4173+
t.type = tarfile.SYMTYPE
4174+
t.linkname = '..'
4175+
arc.tar_w.addfile(t)
4176+
arc.add('x/escaped', content='hi')
4177+
4178+
with self.check_context(arc.open(), 'data'):
4179+
self.expect_exception(tarfile.LinkOutsideDestinationError)
4180+
4181+
@symlink_test
4182+
@os_helper.skip_unless_symlink
4183+
def test_link_at_destination(self):
4184+
# A link member whose name resolves to the destination directory
4185+
# itself must be rejected: otherwise the destination is replaced
4186+
# by a symlink and later members can be redirected through it.
4187+
for name in '', '.', './':
4188+
with ArchiveMaker() as arc:
4189+
t = tarfile.TarInfo(name)
4190+
t.type = tarfile.SYMTYPE
4191+
t.linkname = '.'
4192+
arc.tar_w.addfile(t)
4193+
4194+
with self.check_context(arc.open(), 'data'):
4195+
self.expect_exception(tarfile.OutsideDestinationError)
4196+
4197+
@symlink_test
4198+
@os_helper.skip_unless_symlink
4199+
def test_empty_name_symlink_chain(self):
4200+
# Regression test for a chain of empty-named symlinks that
4201+
# incrementally redirects the destination outwards.
4202+
with ArchiveMaker() as arc:
4203+
for name, target in [('', ''), ('a/', '..'),
4204+
('', 'dummy'), ('', 'a'),
4205+
('b/', '..'),
4206+
('', 'dummy'), ('', 'a/b')]:
4207+
t = tarfile.TarInfo(name)
4208+
t.type = tarfile.SYMTYPE
4209+
t.linkname = target
4210+
arc.tar_w.addfile(t)
4211+
arc.add('escaped', content='hi')
4212+
4213+
with self.check_context(arc.open(), 'data'):
4214+
self.expect_exception(tarfile.FilterError)
4215+
41334216
@symlink_test
41344217
def test_deep_symlink(self):
41354218
# Test that symlinks and hardlinks inside a directory

Misc/NEWS.d/3.14.5.rst

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
.. date: 2026-04-06-13-55-00
2+
.. gh-issue: 148178
3+
.. nonce: Rs7kLm
4+
.. release date: 2026-05-10
5+
.. section: Security
6+
7+
Hardened :mod:`!_remote_debugging` by validating remote debug offset tables
8+
before using them to size memory reads or interpret remote layouts.
9+
10+
..
11+
12+
.. date: 2026-04-20-15-25-55
13+
.. gh-issue: 146270
14+
.. nonce: qZYfyc
15+
.. section: Core and Builtins
16+
17+
Fix a sequential consistency bug in ``structmember.c``.
18+
19+
..
20+
21+
.. date: 2025-08-01-20-31-30
22+
.. gh-issue: 137293
23+
.. nonce: 4x3JbV
24+
.. section: Core and Builtins
25+
26+
Fix :exc:`SystemError` when searching ELF Files in :func:`sys.remote_exec`.
27+
28+
..
29+
30+
.. date: 2026-05-07-21-58-17
31+
.. gh-issue: 149388
32+
.. nonce: DDBPeA
33+
.. section: Library
34+
35+
Make :class:`!asyncio.windows_utils.PipeHandle` closing idempotent.
36+
37+
..
38+
39+
.. date: 2026-05-04-19-28-48
40+
.. gh-issue: 149377
41+
.. nonce: WNlc8Y
42+
.. section: Library
43+
44+
Update bundled pip to 26.1.1
45+
46+
..
47+
48+
.. date: 2026-04-25-14-11-24
49+
.. gh-issue: 138907
50+
.. nonce: u21Wnh
51+
.. section: Library
52+
53+
Support :rfc:`9309` in :mod:`urllib.robotparser`.
54+
55+
..
56+
57+
.. date: 2026-04-15-16-08-12
58+
.. gh-issue: 148615
59+
.. nonce: Uvx50R
60+
.. section: Library
61+
62+
Fix :mod:`pdb` to accept standard -- end of options separator. Reported by
63+
haampie. Patched by Shrey Naithani.
64+
65+
..
66+
67+
.. date: 2026-02-19-04-40-57
68+
.. gh-issue: 130750
69+
.. nonce: 0hW52O
70+
.. section: Library
71+
72+
Restore quoting of choices in :mod:`argparse` error messages for improved
73+
clarity and consistency with documentation.
74+
75+
..
76+
77+
.. date: 2025-12-06-08-48-26
78+
.. gh-issue: 141449
79+
.. nonce: hQvNW_
80+
.. section: Library
81+
82+
Improve tests and documentation for non-function callables as
83+
:term:`annotate functions <annotate function>`.
84+
85+
..
86+
87+
.. date: 2026-05-05-18-49-44
88+
.. gh-issue: 149425
89+
.. nonce: QnQL8j
90+
.. section: Tests
91+
92+
Increase time delta in
93+
``test.test_zipfile.test_core.OtherTests.test_write_without_source_date_epoch``
94+
95+
..
96+
97+
.. date: 2026-05-05-17-08-36
98+
.. gh-issue: 145736
99+
.. nonce: JYdLx4
100+
.. section: Tests
101+
102+
Fix test_tkinter test_configure_values test case backport miss for Tk 9.
103+
104+
..
105+
106+
.. date: 2026-05-06-18-23-36
107+
.. gh-issue: 142295
108+
.. nonce: O9RmZH
109+
.. section: macOS
110+
111+
For Python macOS framework builds, update Info.plist files to be more
112+
compliant with current Apple guidelines. Original patch contributed by
113+
Martinus Verburg.
114+
115+
..
116+
117+
.. date: 2026-05-05-18-42-59
118+
.. gh-issue: 124111
119+
.. nonce: WmQG7S
120+
.. section: macOS
121+
122+
Update macOS installer to use Tcl/Tk 9.0.3.

Misc/NEWS.d/next/Core_and_Builtins/2025-08-01-20-31-30.gh-issue-137293.4x3JbV.rst

Lines changed: 0 additions & 1 deletion
This file was deleted.

Misc/NEWS.d/next/Core_and_Builtins/2026-04-20-15-25-55.gh-issue-146270.qZYfyc.rst

Lines changed: 0 additions & 1 deletion
This file was deleted.

Misc/NEWS.d/next/Library/2025-12-06-08-48-26.gh-issue-141449.hQvNW_.rst

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)