Co-authored-by: Caleb <23644849+ctrlaltf2@users.noreply.github.com> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Emma Smith <emma@emmatyping.dev> Co-authored-by: Jason R. Coombs <jaraco@jaraco.com>
Shamil [Wed, 20 May 2026 03:31:43 +0000 (06:31 +0300)]
[3.14] gh-142831: Fix use-after-free in json encoder during re-entrant mutation (gh-142851) (#150078)
gh-142831: Fix use-after-free in json encoder during re-entrant mutation (gh-142851)
User callbacks invoked during JSON encoding (e.g. the `default` callback or
a custom string encoder) can mutate or clear the dict or sequence being
encoded, invalidating borrowed references to items, keys, and values. Hold
strong references unconditionally while iterating.
`faulthandler_traverse` visits Python objects owned by `_PyRuntime`, not
by the module instance. With multi-phase init allowing multiple module
instances, each instance's GC traversal decrements `gc_refs` on the same
runtime-owned objects, driving it negative when two instances are
collected simultaneously.
(cherry picked from commit 56737483c2ffdaadfec648fd38d409c6b10941c0)
Saul Cooperman [Tue, 19 May 2026 12:34:06 +0000 (05:34 -0700)]
[3.14] gh-146452: Improve locking granularity in pickle's batch_dict_… (#150062)
[3.14] gh-146452: Improve locking granularity in pickle's batch_dict_exact and fix race condition (GH-150025)
Remove assertion that could fail in rare race condition.
Replace the coarse critical section wrapping the entire function with
fine-grained sections covering only PyDict_Next + Py_INCREF.
Also handle PyDict_Next returning 0 in the single-item fast path.
(cherry picked from commit 57a0e570d36f41b953a91bbaf4262a5d05d0391b)
[3.14] Link to existing rules in compound_stmts.rst (GH-149811) (GH-149837)
Link to existing rules in compound_stmts.rst (GH-149811)
In gh-138418, `!` was added to links to rules that don't exist in
the docs, in order to silence broken link warnings.
However, productionlist doesn't parse the `!`, which ends up in
the rendered documentation. (It's possible that gh-127835 broke
the `!` support.)
Replace the names with ones that appear in docs:
- `star_named_expression` in the grammar corresponds to
`flexible_expression` in the docs
- `star_named_expressions` in the grammar corresponds to
`flexible_expression_list` in the docs
- `named_expression` in the grammar corresponds to
`assignment_expression` in the docs
Having two sets of names isn't great of course. Consolidating them
is tracked in (subissues of) gh-127833.
(cherry picked from commit c37529293d1e05081cb4e8668162c76583b88007)
RFC 2047 Section 6.2 requires that "any 'linear-white-space' that
separates a pair of adjacent 'encoded-word's is ignored." The modern
header value parser correctly implements that for unstructured headers,
but had missed a case in structured headers. This could cause a parsed
address header to include extraneous spaces in a display-name.
Switch to @bitdancer's fix from review feedback. Recharacterize space
between ews as fws after parsing in get_phrase.
RDM: This fix is dependent on the fact that "subsequent" atoms will never have
leading whitespace because that's been consumed already. I don't think
it's worth adding extra code for the possibility of leading whitespace
because the parser won't produce it. It's a bit of parser fragility in the
face of code changes, but I think that's a minor concern given the
parser design (which is that it consumes whitespace greedily)
(cherry picked from commit 7a4c6dfb8839eb05fb87baf70364680e45001dd4)
Co-authored-by: Mike Edmunds <medmunds@gmail.com> Co-authored-by: R David Murray <rdmurray@bitdance.com>
[3.14] gh-87451: Apply CVE-2021-4189 PASV fix to ftplib.ftpcp() (GH-149648) (#149793)
gh-87451: Apply CVE-2021-4189 PASV fix to ftplib.ftpcp() (GH-149648)
ftpcp() called parse227() directly and passed the source server's
self-reported PASV IPv4 address to the target server's PORT command,
bypassing the CVE-2021-4189 fix that was applied only to FTP.makepasv().
A malicious source FTP server could use this to redirect the target
server's data connection to an arbitrary host:port (SSRF).
ftpcp() now uses the source server's actual peer address, honoring the
existing trust_server_pasv_ipv4_address opt-out, the same as makepasv().
[3.14] gh-148821: Add more strict tests for XML encodings (GH-149765) (GH-149771)
Exclude encodings like 'utf-8-sig', 'iso2022-jp' and 'hz' from the list of
supported encodings.
(cherry picked from commit fa2afa64d9467fb7362672ed603d29d8e246d240)
Sam Gross [Tue, 12 May 2026 17:21:31 +0000 (17:21 +0000)]
[3.14] gh-145235: Make dict watcher API thread-safe for free-threaded builds (gh-145233) (#149691)
In free-threaded builds, concurrent calls to PyDict_AddWatcher, PyDict_ClearWatcher, PyDict_Watch, and PyDict_Unwatch can race on the shared callback array and the per-dict watcher tags. This change adds a mutex to serialize watcher registration and removal, atomic operations for tag updates, and atomic acquire/release synchronization for callback dispatch in _PyDict_SendEvent.
[3.14] gh-149486: tarfile.data_filter: validate written link target (GH-149487) (GH-149554)
* gh-149486: tarfile.data_filter: validate written link target (GH-149487)
The data filter rewrote linknames with normpath() but ran the
containment check against the un-normalised value, and computed a
symlink's directory before stripping trailing slashes. Both let a
crafted archive create links pointing outside the destination. Also
reject link members that resolve to the destination directory itself,
which could otherwise replace it with a symlink and redirect all
subsequent members.
For Python macOS framework builds, update all Info.plist files to be more
compliant with current Apple guidelines. Original patch contributed by
Martinus Verburg.
Zachary Ware [Wed, 6 May 2026 15:49:11 +0000 (10:49 -0500)]
[3.14] Rewrite RTD configuration to use build.jobs rather than build.commands (GH-149432)
As part of this conversion, we now ensure that we're comparing against the
merge-base of the PR branch and the base branch when checking whether an RTD
build is worthwhile, deepening the history of the base branch by up to 500
commits if necessary. If the merge-base can't be found or there are merge
conflicts with the head of the base branch, the build is skipped since it would
give a warped perception of the actual changes anyway.
This unfortunately does nothing about RTD preview comments comparing against
the wrong base, other than skipping builds that shouldn't produce any diff at
all thus avoiding the comment.
gh-149096: Remove 'im_*' attribute reference from inspect module docstring (GH-149108)
The im_class/func/self names were removed in 3.0. The prefix appears nowhere else in inspect.py
and nowhere in inspect.rst.
(cherry picked from commit e4444538dcd60a1b655c620b4d3bba59a7830f25)
[3.14] GH-130750: Restore quoting of choices in argparse error messag… (#149385)
[3.14] GH-130750: Restore quoting of choices in argparse error messages to match documentation and improve clarity (GH-144983)
(cherry picked from commit 53a7f76501923059188922be231db855265fe9a4)
Treat the debug offset tables read from a target process as untrusted input
and validate them before the unwinder uses any reported sizes or offsets.
Add a shared validator in debug_offsets_validation.h and run it once when
_Py_DebugOffsets is loaded and once when AsyncioDebug is loaded. The checks
cover section sizes used for fixed local buffers and every offset that is
later dereferenced against a local buffer or local object view. This keeps
the bounds checks out of the sampling hot path while rejecting malformed
tables up front.
(cherry picked from commit 289fd2c97a7e5aecb8b69f94f5e838ccfeee7e67)
[3.14] gh-138907: Support RFC 9309 in robotparser (GH-138908) (GH-149374)
* empty lines are always ignored instead of separating groups
* the "user-agent" line after a rule starts a new group
* groups matching the same user agent are now merged
* the rule with the longest match wins instead of the first matching rule
* in case of equal matches, the “Allow” rule wins over “Disallow”
* special characters “$” and “*” are now supported in rules
* prefer full match for user agent
Avoid the phrasing ‘starting with ::FFFF/96’, which is confusing since
it seems to mix a prefix and a range. Instead, make it clear what the
actual range is, and refer to the relevant RFC.
The kind attribute of ast.Constant was not mentioned in the
documentation. It is set to 'u' for u-prefixed string literals
and None for all other constants.
[3.14] gh-148914: Fix memoization of in-band PickleBuffer in the Python implementation (GH-149052) (GH-149274)
Previously, identical PickleBuffers did not preserve identity.
Also, empty writable PickleBuffer memoized an empty bytearray object
in place of b'' which is a singleton in CPython, so the following
references to b'' were unpickled as an empty bytearray object.
(cherry picked from commit b89735625dff07005c31bdc86cbe7113ef1b59d0)
[3.14] gh-149117: Set `ImportError.name` on errors from `runpy.run_module`/`run_path` (gh-149159) (#149257)
gh-149117: Set `ImportError.name` on errors from `runpy.run_module`/`run_path` (gh-149159)
Set ImportError.name on errors from runpy.run_module/run_path
`runpy.run_module()` and `runpy.run_path()` now set the `name` attribute
of the `ImportError` they raise to the requested module name, matching
the behaviour of a regular import statement (previously `name` was
always `None`, which broke introspection).
The `name=` kwarg is gated on `issubclass(error, ImportError)` because
`_get_module_details()` is also used by `_run_module_as_main()` with
a private `_Error` sentinel class. `_Error` does not subclass
ImportError, and `BaseException.__init__` rejects unknown kwargs at
the C level, so passing `name=` unconditionally would break the
`python -m foo` codepath.
(cherry picked from commit ff35fe4633cc6d3a30f6af8281dfa641783c1d07)