Skip to content

Integrate 2.7.18.14 release into 2.7#83

Open
icanhasmath wants to merge 38 commits into
2.7from
2.7.18.14
Open

Integrate 2.7.18.14 release into 2.7#83
icanhasmath wants to merge 38 commits into
2.7from
2.7.18.14

Conversation

@icanhasmath
Copy link
Copy Markdown

Integrates the 2.7.18.14 release line into the long-lived 2.7 branch. The 2.7 branch is currently 38 commits behind; this brings it up to the 2.7.18.14 tag.

What's included

Security / CVE backports (already on the release branch):

Test-suite fixes (this branch, commit bc3b091) — surfaced by running python2 -m test against the build:

  • test_posixpath: guard test_expandvars_nonascii_word with @skipUnless(test_support.FS_NONASCII, …). It dereferenced FS_NONASCII (None under an ASCII/C-locale filesystem encoding) before its skip check, crashing with AttributeError: 'NoneType' object has no attribute 'encode'. Regression from the CVE-2025-6075 expandvars backport.
  • test_socket: restore the missing _have_socket_can() helper. HAVE_SOCKET_CAN = _have_socket_can() referenced an undefined function → NameError crashed the module at import.

Build context (not in this repo's diff)

This release was also unblocked by a builder-side fix for GCC 14, which now treats -Wincompatible-pointer-types and -Wimplicit-function-declaration as default errors — this had dropped _tkinter and mis-detected wchar_t/Py_UNICODE. That fix lives in the platform-builders repo; noted here only for traceability.

Test status

With the two fixes above, python2 -m test goes from 6 failures to 4. The remaining 4 (test_distutils, test_subprocess, test_ssl, test_ftplib) are environmental artifacts of running the suite against a relocated install in a bare container (linker can't find -lpython2.7, child interpreters need PYTHONHOME, in-test TLS servers reset) — not defects in the produced interpreter.

rickprice and others added 30 commits May 1, 2024 19:17
Add #define for XML_GE which exists in the newer version

Rename struct "PREFIX" that conflicts, perhaps with MSVC
…te-IIII

Be 4504 python 2 7 expat update iiii
…te-III

BE-4921 Expat 2.6.4 Vendored into Python2
…te-FixErrors

Be 4504 python 2 7 expat update fix errors
* CVE-2023-27043 First attempt at porting the patch

From here:
https://github.com/python/cpython/pull/123770/files#diff-e3fbfb8d74a5297a5432876e8cc63b8a91836b416989c117cecab3722285ce21

* CVE-2023-27043 First pass at fixing errors

* CVE-2023-27043 Fixup some more tests

* CVE-2023-27043 Test both strict and non-strict getaddresses

As per Python3.9
CVE-2025-8194: tarfile accepted negative member offsets (reachable via a
PAX extended header with a negative "size"), causing TarInfo._block to
return a negative block count that moved the archive offset backwards and
could hang (seekable files) or raise StreamError (streams). _block now
rejects negative counts with InvalidHeaderError.

CVE-2026-4786 / CVE-2026-4519: webbrowser.open passed attacker-controlled
URLs to the browser command line unvalidated, so a URL starting with "-"
could be treated as a command-line option (argument injection). Add
BaseBrowser._check_url and call it from GenericBrowser, BackgroundBrowser
and UnixBrowser; UnixBrowser validates the URL after %action expansion and
substitutes %action before %s so %action cannot smuggle a leading dash.

Adds tests in test_tarfile (negative _block count and a PAX negative-size
archive) and a new test_webbrowser covering URL rejection and the %action
bypass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Backports a uniform "reject C0 control characters and DEL" defense across
several stdlib modules where unvalidated user input was emitted into
protocol headers/commands, enabling CR/LF (and NUL) injection:

- wsgiref.headers.Headers: validate name/value in __init__, __setitem__
  and add_header (CVE-2026-0865), raising ValueError.
- Cookie.Morsel: reject control chars in set()/__setitem__ key, value and
  coded value (CVE-2026-0672), raising CookieError. Validation lives at the
  value-storage chokepoints, so the CVE-2026-3644-style bypasses do not
  apply (2.7 has no Morsel.update/|=/__setstate__).
- imaplib.IMAP4._command: reject control chars in command arguments
  (CVE-2025-15366), raising ValueError.
- poplib.POP3._putline (and the SSL override): reject control chars in the
  command line (CVE-2025-15367), raising error_proto.
- httplib.HTTPConnection.set_tunnel: validate the CONNECT tunnel host via
  the existing _validate_host (CVE-2026-1502), raising InvalidURL.

Adds focused tests to test_cookie, test_wsgiref, test_imaplib, test_poplib
and test_httplib.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
email.generator.Generator wrote header values verbatim, so a value
containing a bare CR/LF (e.g. set via msg['To'] = 'a\r\nBcc: x') could
inject additional headers or body content.

Port the upstream verify_generated_headers behaviour into _write_headers:
after computing each header's serialized form, reject it (raise the new
email.errors.HeaderWriteError) if it contains a CR/LF that is not part of
valid folding, using NEWLINE_WITHOUT_FWSP = re.compile(
r'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]'). Since 2.7's email has no policy
framework, the check is unconditional (matching upstream's default-on).

Adds email.errors.HeaderWriteError and a regression test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
icanhasmath and others added 8 commits May 27, 2026 23:17
CVE-2024-0450: zipfile did not detect "quoted overlap" archives where an
entry's compressed data overruns the start of the next entry, a high-ratio
zip bomb. _RealGetContents now records each member's _end_offset (the start
of the next local header, or the central directory for the last member) and
ZipFile.open raises BadZipfile if an entry's data would extend past it.

CVE-2025-8291: _EndRecData64 trusted that the ZIP64 end-of-central-directory
record sat immediately before its locator and ignored the locator's stored
relative offset. It now rejects archives whose locator offset points past
the expected record position ("Corrupt zip64 end of central directory
locator").

Adds _end_offset to ZipInfo (slots + __init__) and regression tests for
both issues.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
urlparse.urlsplit only rejected mismatched IPv6 brackets, so a netloc like
"ex[ample].com" or "[example.com]" was accepted, parsing differently from
RFC 3986-compliant tools (a differential-parsing / SSRF vector).

Add _check_bracketed_netloc / _check_bracketed_host (ported from the
upstream fix) and call them from both urlsplit code paths. Brackets are now
allowed only when they enclose a valid IPv6/IPvFuture host. Since 2.7 lacks
the ipaddress module, IPv6 content is validated via socket.inet_pton (with a
conservative character fallback where inet_pton is unavailable).

Adds a regression test covering rejected and accepted bracketed hosts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CVE-2025-12084: xml.dom.minidom._clear_id_cache called _in_document(), which
walks the parent chain to the document root on every node mutation, making
deeply nested appendChild()/insertBefore() O(n^2). Replace the walk with an
O(1) `node.ownerDocument` check (over-clearing a detached node's cache is
harmless; the cache is rebuilt lazily).

CVE-2025-6075: posixpath.expandvars rebuilt the whole path string on each
substitution and ntpath.expandvars concatenated to a result string char by
char, both quadratic in the input size. posixpath now accumulates output
segments; ntpath now expands via a single regex-substitution pass (ported
from upstream), preserving the existing matching semantics.

Adds bulk/regression tests for both expandvars implementations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When close() flushed input ending in an unterminated construct, goahead()
advanced only to the next '<' and re-parsed, so an input with many
incomplete constructs (e.g. repeated "<!--") scanned the remaining buffer
once per construct -- O(n^2).

Backport the upstream fix: at EOF an unterminated construct is closed per
HTML5 (comments/declarations/CDATA/PI are emitted via their handlers, and
incomplete tags are ignored) and the rest of the buffer is consumed in one
step (k = n), making it linear. Adds endtagopen and updates the affected
EOF expectations in test_htmlparser, plus new test_eof_in_* cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
base64.b64decode silently discarded non-alphabet characters and, with an
alternative alphabet, still accepted the standard '+'/'/' characters
(CVE-2025-12781); it also ignored any data after the padding
(CVE-2026-3446).

Add a validate=False parameter (mirroring Python 3). When validate=True the
input is checked against the *requested* alphabet -- so '+'/'/' are rejected
when altchars is given, and embedded or post-padding junk is rejected rather
than silently dropped. This goes beyond upstream, which only deprecates the
lenient behaviour. The default (validate=False) is unchanged.

Adds a regression test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tarfile normalized an AREGTYPE ('\x00') header whose name ends in a slash to
DIRTYPE.  This was also applied to follow-up headers (a GNU long name/link
or a pax header), letting a crafted archive be interpreted differently from
other tools.

Split the header parsing into _frombuf(dircheck=...) / _fromtarfile and
perform the AREGTYPE->DIRTYPE normalization only for primary headers; the
follow-up reads in _proc_gnulong and _proc_pax pass dircheck=False. The
public frombuf()/fromtarfile() signatures are unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bump PY_VERSION to 2.7.18.14 and add release notes for the security fixes
addressed in this release: CVE-2025-8194, CVE-2026-4519, CVE-2026-4786,
CVE-2026-0865, CVE-2026-0672, CVE-2025-15366, CVE-2025-15367, CVE-2026-1502,
CVE-2024-6923, CVE-2024-0450, CVE-2025-8291, CVE-2025-0938, CVE-2024-11168,
CVE-2025-6069, CVE-2025-6075, CVE-2025-12084, CVE-2025-13462, CVE-2025-12781
and CVE-2026-3446.  Documents "not affected" determinations for
CVE-2025-13836, CVE-2025-15282, CVE-2025-11468, CVE-2025-1795, CVE-2026-3644
and CVE-2024-5642.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…_can

Two test-suite fixes surfaced by running `python2 -m test` against the
2.7.18.14 build:

* test_posixpath: test_expandvars_nonascii_word dereferenced
  test_support.FS_NONASCII (None under an ASCII/C-locale filesystem
  encoding) before its skipTest check, crashing with
  AttributeError: 'NoneType' object has no attribute 'encode'.
  Guard it with @skipUnless(test_support.FS_NONASCII, ...) to match
  its sibling test_expandvars_many and upstream CPython. Regression
  from the CVE-2025-6075 expandvars backport.

* test_socket: HAVE_SOCKET_CAN = _have_socket_can() called a helper
  that was missing from the module, raising NameError at import and
  crashing the whole test. Restore the upstream _have_socket_can()
  definition; it resolves to False where PF_CAN/CAN_RAW are absent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants