pkgsrc-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: pkgsrc/lang/python314



Module Name:    pkgsrc
Committed By:   wiz
Date:           Wed Nov  5 22:20:05 UTC 2025

Modified Files:
        pkgsrc/lang/python314: Makefile distinfo
Added Files:
        pkgsrc/lang/python314/patches: patch-Lib_ntpath.py
            patch-Lib_posixpath.py patch-Lib_test_test__genericpath.py
            patch-Lib_test_test__ntpath.py

Log Message:
python314: apply upstream patch fixing CVE-2025-6075

Bump PKGREVISION.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 pkgsrc/lang/python314/Makefile
cvs rdiff -u -r1.2 -r1.3 pkgsrc/lang/python314/distinfo
cvs rdiff -u -r0 -r1.1 pkgsrc/lang/python314/patches/patch-Lib_ntpath.py \
    pkgsrc/lang/python314/patches/patch-Lib_posixpath.py \
    pkgsrc/lang/python314/patches/patch-Lib_test_test__genericpath.py \
    pkgsrc/lang/python314/patches/patch-Lib_test_test__ntpath.py

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/lang/python314/Makefile
diff -u pkgsrc/lang/python314/Makefile:1.6 pkgsrc/lang/python314/Makefile:1.7
--- pkgsrc/lang/python314/Makefile:1.6  Wed Oct 22 13:46:55 2025
+++ pkgsrc/lang/python314/Makefile      Wed Nov  5 22:20:05 2025
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.6 2025/10/22 13:46:55 jperkin Exp $
+# $NetBSD: Makefile,v 1.7 2025/11/05 22:20:05 wiz Exp $
 
 .include "dist.mk"
 
 PKGNAME=       python314-${PY_DISTVERSION}
-PKGREVISION=   2
+PKGREVISION=   3
 CATEGORIES=    lang python
 
 MAINTAINER=    pkgsrc-users%NetBSD.org@localhost

Index: pkgsrc/lang/python314/distinfo
diff -u pkgsrc/lang/python314/distinfo:1.2 pkgsrc/lang/python314/distinfo:1.3
--- pkgsrc/lang/python314/distinfo:1.2  Sat Oct 11 10:14:06 2025
+++ pkgsrc/lang/python314/distinfo      Wed Nov  5 22:20:05 2025
@@ -1,11 +1,15 @@
-$NetBSD: distinfo,v 1.2 2025/10/11 10:14:06 wiz Exp $
+$NetBSD: distinfo,v 1.3 2025/11/05 22:20:05 wiz Exp $
 
 BLAKE2s (Python-3.14.0.tar.xz) = 8b0bc589285d6bb131423b9cc89e5c322eaa4aaa77c3ae12216a16d9b5235064
 SHA512 (Python-3.14.0.tar.xz) = 46e9e205c3a084cba68bf7f267ab2fd0862a05430165e0eb713f2d6b3a1a4452f72f563de5de55caea824be9df56f66dd568f4814941667a9bb0954229772c53
 Size (Python-3.14.0.tar.xz) = 23595844 bytes
 SHA1 (patch-Include_pymacro.h) = 7611315fefc305a48b4965f2f2b9bee53ae3d987
 SHA1 (patch-Lib_ctypes_util.py) = 3dec1b6b7a36e46cbfa0dfcd71c5e7fac9f60764
+SHA1 (patch-Lib_ntpath.py) = bded5ab2f680253a281ad63c87d2794c198bfb9a
+SHA1 (patch-Lib_posixpath.py) = a8c17a3ea795885e4e18b921a2bc4c259edf80de
 SHA1 (patch-Lib_sysconfig_____init____.py) = 76a35b78b098978209f9bcc0e5357d439f281c6b
+SHA1 (patch-Lib_test_test__genericpath.py) = d5f50c0e92e8da690d738003d2eb2ff22c8cb458
+SHA1 (patch-Lib_test_test__ntpath.py) = 663d286d196b781b6f53dea2faf917b2c05d9cb0
 SHA1 (patch-Lib_test_test__zipfile_test__core.py) = 6d487c732bf055ce83d61c2f994f1cc90d2b70b3
 SHA1 (patch-Lib_zipfile_____init____.py) = a2c5ec38abc88318938e0496fd49c2aab5dc782c
 SHA1 (patch-Makefile.pre.in) = 620fa538eaebdf4e374eff0ed475a87775fb0a29

Added files:

Index: pkgsrc/lang/python314/patches/patch-Lib_ntpath.py
diff -u /dev/null pkgsrc/lang/python314/patches/patch-Lib_ntpath.py:1.1
--- /dev/null   Wed Nov  5 22:20:05 2025
+++ pkgsrc/lang/python314/patches/patch-Lib_ntpath.py   Wed Nov  5 22:20:05 2025
@@ -0,0 +1,161 @@
+$NetBSD: patch-Lib_ntpath.py,v 1.1 2025/11/05 22:20:05 wiz Exp $
+
+[3.14] gh-136065: Fix quadratic complexity in os.path.expandvars() (GH-134952) (GH-140844)
+https://github.com/python/cpython/commit/631ba3407e3348ccd56ce5160c4fb2c5dc5f4d84
+
+--- Lib/ntpath.py.orig 2025-10-07 09:34:52.000000000 +0000
++++ Lib/ntpath.py
+@@ -400,17 +400,23 @@ def expanduser(path):
+ # XXX With COMMAND.COM you can use any characters in a variable name,
+ # XXX except '^|<>='.
+ 
++_varpattern = r"'[^']*'?|%(%|[^%]*%?)|\$(\$|[-\w]+|\{[^}]*\}?)"
++_varsub = None
++_varsubb = None
++
+ def expandvars(path):
+     """Expand shell variables of the forms $var, ${var} and %var%.
+ 
+     Unknown variables are left unchanged."""
+     path = os.fspath(path)
++    global _varsub, _varsubb
+     if isinstance(path, bytes):
+         if b'$' not in path and b'%' not in path:
+             return path
+-        import string
+-        varchars = bytes(string.ascii_letters + string.digits + '_-', 'ascii')
+-        quote = b'\''
++        if not _varsubb:
++            import re
++            _varsubb = re.compile(_varpattern.encode(), re.ASCII).sub
++        sub = _varsubb
+         percent = b'%'
+         brace = b'{'
+         rbrace = b'}'
+@@ -419,94 +425,44 @@ def expandvars(path):
+     else:
+         if '$' not in path and '%' not in path:
+             return path
+-        import string
+-        varchars = string.ascii_letters + string.digits + '_-'
+-        quote = '\''
++        if not _varsub:
++            import re
++            _varsub = re.compile(_varpattern, re.ASCII).sub
++        sub = _varsub
+         percent = '%'
+         brace = '{'
+         rbrace = '}'
+         dollar = '$'
+         environ = os.environ
+-    res = path[:0]
+-    index = 0
+-    pathlen = len(path)
+-    while index < pathlen:
+-        c = path[index:index+1]
+-        if c == quote:   # no expansion within single quotes
+-            path = path[index + 1:]
+-            pathlen = len(path)
+-            try:
+-                index = path.index(c)
+-                res += c + path[:index + 1]
+-            except ValueError:
+-                res += c + path
+-                index = pathlen - 1
+-        elif c == percent:  # variable or '%'
+-            if path[index + 1:index + 2] == percent:
+-                res += c
+-                index += 1
+-            else:
+-                path = path[index+1:]
+-                pathlen = len(path)
+-                try:
+-                    index = path.index(percent)
+-                except ValueError:
+-                    res += percent + path
+-                    index = pathlen - 1
+-                else:
+-                    var = path[:index]
+-                    try:
+-                        if environ is None:
+-                            value = os.fsencode(os.environ[os.fsdecode(var)])
+-                        else:
+-                            value = environ[var]
+-                    except KeyError:
+-                        value = percent + var + percent
+-                    res += value
+-        elif c == dollar:  # variable or '$$'
+-            if path[index + 1:index + 2] == dollar:
+-                res += c
+-                index += 1
+-            elif path[index + 1:index + 2] == brace:
+-                path = path[index+2:]
+-                pathlen = len(path)
+-                try:
+-                    index = path.index(rbrace)
+-                except ValueError:
+-                    res += dollar + brace + path
+-                    index = pathlen - 1
+-                else:
+-                    var = path[:index]
+-                    try:
+-                        if environ is None:
+-                            value = os.fsencode(os.environ[os.fsdecode(var)])
+-                        else:
+-                            value = environ[var]
+-                    except KeyError:
+-                        value = dollar + brace + var + rbrace
+-                    res += value
+-            else:
+-                var = path[:0]
+-                index += 1
+-                c = path[index:index + 1]
+-                while c and c in varchars:
+-                    var += c
+-                    index += 1
+-                    c = path[index:index + 1]
+-                try:
+-                    if environ is None:
+-                        value = os.fsencode(os.environ[os.fsdecode(var)])
+-                    else:
+-                        value = environ[var]
+-                except KeyError:
+-                    value = dollar + var
+-                res += value
+-                if c:
+-                    index -= 1
++
++    def repl(m):
++        lastindex = m.lastindex
++        if lastindex is None:
++            return m[0]
++        name = m[lastindex]
++        if lastindex == 1:
++            if name == percent:
++                return name
++            if not name.endswith(percent):
++                return m[0]
++            name = name[:-1]
+         else:
+-            res += c
+-        index += 1
+-    return res
++            if name == dollar:
++                return name
++            if name.startswith(brace):
++                if not name.endswith(rbrace):
++                    return m[0]
++                name = name[1:-1]
++
++        try:
++            if environ is None:
++                return os.fsencode(os.environ[os.fsdecode(name)])
++            else:
++                return environ[name]
++        except KeyError:
++            return m[0]
++
++    return sub(repl, path)
+ 
+ 
+ # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
Index: pkgsrc/lang/python314/patches/patch-Lib_posixpath.py
diff -u /dev/null pkgsrc/lang/python314/patches/patch-Lib_posixpath.py:1.1
--- /dev/null   Wed Nov  5 22:20:05 2025
+++ pkgsrc/lang/python314/patches/patch-Lib_posixpath.py        Wed Nov  5 22:20:05 2025
@@ -0,0 +1,84 @@
+$NetBSD: patch-Lib_posixpath.py,v 1.1 2025/11/05 22:20:05 wiz Exp $
+
+[3.14] gh-136065: Fix quadratic complexity in os.path.expandvars() (GH-134952) (GH-140844)
+https://github.com/python/cpython/commit/631ba3407e3348ccd56ce5160c4fb2c5dc5f4d84
+
+--- Lib/posixpath.py.orig      2025-10-07 09:34:52.000000000 +0000
++++ Lib/posixpath.py
+@@ -284,42 +284,41 @@ def expanduser(path):
+ # This expands the forms $variable and ${variable} only.
+ # Non-existent variables are left unchanged.
+ 
+-_varprog = None
+-_varprogb = None
++_varpattern = r'\$(\w+|\{[^}]*\}?)'
++_varsub = None
++_varsubb = None
+ 
+ def expandvars(path):
+     """Expand shell variables of form $var and ${var}.  Unknown variables
+     are left unchanged."""
+     path = os.fspath(path)
+-    global _varprog, _varprogb
++    global _varsub, _varsubb
+     if isinstance(path, bytes):
+         if b'$' not in path:
+             return path
+-        if not _varprogb:
++        if not _varsubb:
+             import re
+-            _varprogb = re.compile(br'\$(\w+|\{[^}]*\})', re.ASCII)
+-        search = _varprogb.search
++            _varsubb = re.compile(_varpattern.encode(), re.ASCII).sub
++        sub = _varsubb
+         start = b'{'
+         end = b'}'
+         environ = getattr(os, 'environb', None)
+     else:
+         if '$' not in path:
+             return path
+-        if not _varprog:
++        if not _varsub:
+             import re
+-            _varprog = re.compile(r'\$(\w+|\{[^}]*\})', re.ASCII)
+-        search = _varprog.search
++            _varsub = re.compile(_varpattern, re.ASCII).sub
++        sub = _varsub
+         start = '{'
+         end = '}'
+         environ = os.environ
+-    i = 0
+-    while True:
+-        m = search(path, i)
+-        if not m:
+-            break
+-        i, j = m.span(0)
+-        name = m.group(1)
+-        if name.startswith(start) and name.endswith(end):
++
++    def repl(m):
++        name = m[1]
++        if name.startswith(start):
++            if not name.endswith(end):
++                return m[0]
+             name = name[1:-1]
+         try:
+             if environ is None:
+@@ -327,13 +326,11 @@ def expandvars(path):
+             else:
+                 value = environ[name]
+         except KeyError:
+-            i = j
++            return m[0]
+         else:
+-            tail = path[j:]
+-            path = path[:i] + value
+-            i = len(path)
+-            path += tail
+-    return path
++            return value
++
++    return sub(repl, path)
+ 
+ 
+ # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
Index: pkgsrc/lang/python314/patches/patch-Lib_test_test__genericpath.py
diff -u /dev/null pkgsrc/lang/python314/patches/patch-Lib_test_test__genericpath.py:1.1
--- /dev/null   Wed Nov  5 22:20:05 2025
+++ pkgsrc/lang/python314/patches/patch-Lib_test_test__genericpath.py   Wed Nov  5 22:20:05 2025
@@ -0,0 +1,49 @@
+$NetBSD: patch-Lib_test_test__genericpath.py,v 1.1 2025/11/05 22:20:05 wiz Exp $
+
+[3.14] gh-136065: Fix quadratic complexity in os.path.expandvars() (GH-134952) (GH-140844)
+https://github.com/python/cpython/commit/631ba3407e3348ccd56ce5160c4fb2c5dc5f4d84
+
+--- Lib/test/test_genericpath.py.orig  2025-10-07 09:34:52.000000000 +0000
++++ Lib/test/test_genericpath.py
+@@ -7,9 +7,9 @@ import os
+ import sys
+ import unittest
+ import warnings
+-from test.support import (
+-    is_apple, is_emscripten, os_helper, warnings_helper
+-)
++from test import support
++from test.support import os_helper
++from test.support import warnings_helper
+ from test.support.script_helper import assert_python_ok
+ from test.support.os_helper import FakePath
+ 
+@@ -445,6 +445,19 @@ class CommonTest(GenericTest):
+                   os.fsencode('$bar%s bar' % nonascii))
+             check(b'$spam}bar', os.fsencode('%s}bar' % nonascii))
+ 
++    @support.requires_resource('cpu')
++    def test_expandvars_large(self):
++        expandvars = self.pathmodule.expandvars
++        with os_helper.EnvironmentVarGuard() as env:
++            env.clear()
++            env["A"] = "B"
++            n = 100_000
++            self.assertEqual(expandvars('$A'*n), 'B'*n)
++            self.assertEqual(expandvars('${A}'*n), 'B'*n)
++            self.assertEqual(expandvars('$A!'*n), 'B!'*n)
++            self.assertEqual(expandvars('${A}A'*n), 'BA'*n)
++            self.assertEqual(expandvars('${'*10*n), '${'*10*n)
++
+     def test_abspath(self):
+         self.assertIn("foo", self.pathmodule.abspath("foo"))
+         with warnings.catch_warnings():
+@@ -502,7 +515,7 @@ class CommonTest(GenericTest):
+             # directory (when the bytes name is used).
+             and sys.platform not in {
+                 "win32", "emscripten", "wasi"
+-            } and not is_apple
++            } and not support.is_apple
+         ):
+             name = os_helper.TESTFN_UNDECODABLE
+         elif os_helper.TESTFN_NONASCII:
Index: pkgsrc/lang/python314/patches/patch-Lib_test_test__ntpath.py
diff -u /dev/null pkgsrc/lang/python314/patches/patch-Lib_test_test__ntpath.py:1.1
--- /dev/null   Wed Nov  5 22:20:05 2025
+++ pkgsrc/lang/python314/patches/patch-Lib_test_test__ntpath.py        Wed Nov  5 22:20:05 2025
@@ -0,0 +1,64 @@
+$NetBSD: patch-Lib_test_test__ntpath.py,v 1.1 2025/11/05 22:20:05 wiz Exp $
+
+[3.14] gh-136065: Fix quadratic complexity in os.path.expandvars() (GH-134952) (GH-140844)
+https://github.com/python/cpython/commit/631ba3407e3348ccd56ce5160c4fb2c5dc5f4d84
+
+--- Lib/test/test_ntpath.py.orig       2025-10-07 09:34:52.000000000 +0000
++++ Lib/test/test_ntpath.py
+@@ -7,8 +7,7 @@ import sys
+ import unittest
+ import warnings
+ from test import support
+-from test.support import cpython_only, os_helper
+-from test.support import TestFailed
++from test.support import os_helper
+ from ntpath import ALLOW_MISSING
+ from test.support.os_helper import FakePath
+ from test import test_genericpath
+@@ -59,7 +58,7 @@ def tester(fn, wantResult):
+     fn = fn.replace("\\", "\\\\")
+     gotResult = eval(fn)
+     if wantResult != gotResult and _norm(wantResult) != _norm(gotResult):
+-        raise TestFailed("%s should return: %s but returned: %s" \
++        raise support.TestFailed("%s should return: %s but returned: %s" \
+               %(str(fn), str(wantResult), str(gotResult)))
+ 
+     # then with bytes
+@@ -75,7 +74,7 @@ def tester(fn, wantResult):
+         warnings.simplefilter("ignore", DeprecationWarning)
+         gotResult = eval(fn)
+     if _norm(wantResult) != _norm(gotResult):
+-        raise TestFailed("%s should return: %s but returned: %s" \
++        raise support.TestFailed("%s should return: %s but returned: %s" \
+               %(str(fn), str(wantResult), repr(gotResult)))
+ 
+ 
+@@ -1022,6 +1021,19 @@ class TestNtpath(NtpathTestCase):
+             check('%spam%bar', '%sbar' % nonascii)
+             check('%{}%bar'.format(nonascii), 'ham%sbar' % nonascii)
+ 
++    @support.requires_resource('cpu')
++    def test_expandvars_large(self):
++        expandvars = ntpath.expandvars
++        with os_helper.EnvironmentVarGuard() as env:
++            env.clear()
++            env["A"] = "B"
++            n = 100_000
++            self.assertEqual(expandvars('%A%'*n), 'B'*n)
++            self.assertEqual(expandvars('%A%A'*n), 'BA'*n)
++            self.assertEqual(expandvars("''"*n + '%%'), "''"*n + '%')
++            self.assertEqual(expandvars("%%"*n), "%"*n)
++            self.assertEqual(expandvars("$$"*n), "$"*n)
++
+     def test_expanduser(self):
+         tester('ntpath.expanduser("test")', 'test')
+ 
+@@ -1439,7 +1451,7 @@ class TestNtpath(NtpathTestCase):
+         self.assertTrue(os.path.exists(r"\\.\CON"))
+ 
+     @unittest.skipIf(sys.platform != 'win32', "Fast paths are only for win32")
+-    @cpython_only
++    @support.cpython_only
+     def test_fast_paths_in_use(self):
+         # There are fast paths of these functions implemented in posixmodule.c.
+         # Confirm that they are being used, and not the Python fallbacks in



Home | Main Index | Thread Index | Old Index