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: Sat Oct 11 10:14:06 UTC 2025
Modified Files:
pkgsrc/lang/python314: Makefile distinfo options.mk
Added Files:
pkgsrc/lang/python314/patches:
patch-Lib_test_test__zipfile_test__core.py
patch-Lib_zipfile_____init____.py
Log Message:
python314: fix zip vulnerability using upstream patch
Bump PKGREVISION.
While here, fix option name and some pkglint.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 pkgsrc/lang/python314/Makefile
cvs rdiff -u -r1.1 -r1.2 pkgsrc/lang/python314/distinfo \
pkgsrc/lang/python314/options.mk
cvs rdiff -u -r0 -r1.1 \
pkgsrc/lang/python314/patches/patch-Lib_test_test__zipfile_test__core.py \
pkgsrc/lang/python314/patches/patch-Lib_zipfile_____init____.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.3 pkgsrc/lang/python314/Makefile:1.4
--- pkgsrc/lang/python314/Makefile:1.3 Fri Oct 10 13:57:52 2025
+++ pkgsrc/lang/python314/Makefile Sat Oct 11 10:14:06 2025
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.3 2025/10/10 13:57:52 wiz Exp $
+# $NetBSD: Makefile,v 1.4 2025/10/11 10:14:06 wiz Exp $
.include "dist.mk"
@@ -42,10 +42,10 @@ PTHREAD_OPTS+= require
.include "../../mk/bsd.prefs.mk"
# NetBSD-8 curses has enough support for py-curses
-USE_CURSES= getsyx update_panels wide
+USE_CURSES= getsyx update_panels wide
# But we build as ncurses still to get the full feature set easily
.if ${OPSYS} == "NetBSD"
-FAKE_NCURSES= yes
+FAKE_NCURSES= yes
## Force use of libuuid
CONFIGURE_ARGS+= ac_cv_header_uuid_h=false
.endif
@@ -197,6 +197,8 @@ setuptools-preinstall:
# for testing
ALLOW_NETWORK_ACCESS= yes
+# test status as of 3.14.0
+# Total test files: run=499/491 failed=10 skipped=31 resource_denied=2 rerun=10
.if ${OPSYS} == "Linux"
.include "../../databases/gdbm_compat/buildlink3.mk"
Index: pkgsrc/lang/python314/distinfo
diff -u pkgsrc/lang/python314/distinfo:1.1 pkgsrc/lang/python314/distinfo:1.2
--- pkgsrc/lang/python314/distinfo:1.1 Wed Oct 8 07:13:08 2025
+++ pkgsrc/lang/python314/distinfo Sat Oct 11 10:14:06 2025
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.1 2025/10/08 07:13:08 adam Exp $
+$NetBSD: distinfo,v 1.2 2025/10/11 10:14:06 wiz Exp $
BLAKE2s (Python-3.14.0.tar.xz) = 8b0bc589285d6bb131423b9cc89e5c322eaa4aaa77c3ae12216a16d9b5235064
SHA512 (Python-3.14.0.tar.xz) = 46e9e205c3a084cba68bf7f267ab2fd0862a05430165e0eb713f2d6b3a1a4452f72f563de5de55caea824be9df56f66dd568f4814941667a9bb0954229772c53
@@ -6,6 +6,8 @@ Size (Python-3.14.0.tar.xz) = 23595844 b
SHA1 (patch-Include_pymacro.h) = 7611315fefc305a48b4965f2f2b9bee53ae3d987
SHA1 (patch-Lib_ctypes_util.py) = 3dec1b6b7a36e46cbfa0dfcd71c5e7fac9f60764
SHA1 (patch-Lib_sysconfig_____init____.py) = 76a35b78b098978209f9bcc0e5357d439f281c6b
+SHA1 (patch-Lib_test_test__zipfile_test__core.py) = 6d487c732bf055ce83d61c2f994f1cc90d2b70b3
+SHA1 (patch-Lib_zipfile_____init____.py) = a2c5ec38abc88318938e0496fd49c2aab5dc782c
SHA1 (patch-Makefile.pre.in) = 620fa538eaebdf4e374eff0ed475a87775fb0a29
SHA1 (patch-Modules_faulthandler.c) = ca59c378d25bfc0769a7f5da887369d8c913e70c
SHA1 (patch-Modules_readline.c) = 232f6ac43b5a0e87c915f13117bae91ef069a6c1
Index: pkgsrc/lang/python314/options.mk
diff -u pkgsrc/lang/python314/options.mk:1.1 pkgsrc/lang/python314/options.mk:1.2
--- pkgsrc/lang/python314/options.mk:1.1 Wed Oct 8 07:13:08 2025
+++ pkgsrc/lang/python314/options.mk Sat Oct 11 10:14:06 2025
@@ -1,6 +1,6 @@
-# $NetBSD: options.mk,v 1.1 2025/10/08 07:13:08 adam Exp $
+# $NetBSD: options.mk,v 1.2 2025/10/11 10:14:06 wiz Exp $
-PKG_OPTIONS_VAR= PKG_OPTIONS.python313
+PKG_OPTIONS_VAR= PKG_OPTIONS.python314
PKG_SUPPORTED_OPTIONS= dtrace pymalloc tkinter x11 readline
PKG_SUGGESTED_OPTIONS= x11 readline
Added files:
Index: pkgsrc/lang/python314/patches/patch-Lib_test_test__zipfile_test__core.py
diff -u /dev/null pkgsrc/lang/python314/patches/patch-Lib_test_test__zipfile_test__core.py:1.1
--- /dev/null Sat Oct 11 10:14:06 2025
+++ pkgsrc/lang/python314/patches/patch-Lib_test_test__zipfile_test__core.py Sat Oct 11 10:14:06 2025
@@ -0,0 +1,162 @@
+$NetBSD: patch-Lib_test_test__zipfile_test__core.py,v 1.1 2025/10/11 10:14:06 wiz Exp $
+
+https://github.com/python/cpython/commit/d11e69d6203080e3ec450446bfed0516727b85c3
+
+--- Lib/test/test_zipfile/test_core.py.orig 2025-10-07 09:34:52.000000000 +0000
++++ Lib/test/test_zipfile/test_core.py
+@@ -898,6 +898,8 @@ class StoredTestZip64InSmallFiles(Abstra
+ self, file_size_64_set=False, file_size_extra=False,
+ compress_size_64_set=False, compress_size_extra=False,
+ header_offset_64_set=False, header_offset_extra=False,
++ extensible_data=b'',
++ end_of_central_dir_size=None, offset_to_end_of_central_dir=None,
+ ):
+ """Generate bytes sequence for a zip with (incomplete) zip64 data.
+
+@@ -951,6 +953,12 @@ class StoredTestZip64InSmallFiles(Abstra
+
+ central_dir_size = struct.pack('<Q', 58 + 8 * len(central_zip64_fields))
+ offset_to_central_dir = struct.pack('<Q', 50 + 8 * len(local_zip64_fields))
++ if end_of_central_dir_size is None:
++ end_of_central_dir_size = 44 + len(extensible_data)
++ if offset_to_end_of_central_dir is None:
++ offset_to_end_of_central_dir = (108
++ + 8 * len(local_zip64_fields)
++ + 8 * len(central_zip64_fields))
+
+ local_extra_length = struct.pack("<H", 4 + 8 * len(local_zip64_fields))
+ central_extra_length = struct.pack("<H", 4 + 8 * len(central_zip64_fields))
+@@ -979,14 +987,17 @@ class StoredTestZip64InSmallFiles(Abstra
+ + filename
+ + central_extra
+ # Zip64 end of central directory
+- + b"PK\x06\x06,\x00\x00\x00\x00\x00\x00\x00-\x00-"
+- + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00"
++ + b"PK\x06\x06"
++ + struct.pack('<Q', end_of_central_dir_size)
++ + b"-\x00-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00"
+ + b"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
+ + central_dir_size
+ + offset_to_central_dir
++ + extensible_data
+ # Zip64 end of central directory locator
+- + b"PK\x06\x07\x00\x00\x00\x00l\x00\x00\x00\x00\x00\x00\x00\x01"
+- + b"\x00\x00\x00"
++ + b"PK\x06\x07\x00\x00\x00\x00"
++ + struct.pack('<Q', offset_to_end_of_central_dir)
++ + b"\x01\x00\x00\x00"
+ # end of central directory
+ + b"PK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00:\x00\x00\x002\x00"
+ + b"\x00\x00\x00\x00"
+@@ -1017,6 +1028,7 @@ class StoredTestZip64InSmallFiles(Abstra
+ with self.assertRaises(zipfile.BadZipFile) as e:
+ zipfile.ZipFile(io.BytesIO(missing_file_size_extra))
+ self.assertIn('file size', str(e.exception).lower())
++ self.assertTrue(zipfile.is_zipfile(io.BytesIO(missing_file_size_extra)))
+
+ # zip64 file size present, zip64 compress size present, one field in
+ # extra, expecting two, equals missing compress size.
+@@ -1028,6 +1040,7 @@ class StoredTestZip64InSmallFiles(Abstra
+ with self.assertRaises(zipfile.BadZipFile) as e:
+ zipfile.ZipFile(io.BytesIO(missing_compress_size_extra))
+ self.assertIn('compress size', str(e.exception).lower())
++ self.assertTrue(zipfile.is_zipfile(io.BytesIO(missing_compress_size_extra)))
+
+ # zip64 compress size present, no fields in extra, expecting one,
+ # equals missing compress size.
+@@ -1037,6 +1050,7 @@ class StoredTestZip64InSmallFiles(Abstra
+ with self.assertRaises(zipfile.BadZipFile) as e:
+ zipfile.ZipFile(io.BytesIO(missing_compress_size_extra))
+ self.assertIn('compress size', str(e.exception).lower())
++ self.assertTrue(zipfile.is_zipfile(io.BytesIO(missing_compress_size_extra)))
+
+ # zip64 file size present, zip64 compress size present, zip64 header
+ # offset present, two fields in extra, expecting three, equals missing
+@@ -1051,6 +1065,7 @@ class StoredTestZip64InSmallFiles(Abstra
+ with self.assertRaises(zipfile.BadZipFile) as e:
+ zipfile.ZipFile(io.BytesIO(missing_header_offset_extra))
+ self.assertIn('header offset', str(e.exception).lower())
++ self.assertTrue(zipfile.is_zipfile(io.BytesIO(missing_header_offset_extra)))
+
+ # zip64 compress size present, zip64 header offset present, one field
+ # in extra, expecting two, equals missing header offset
+@@ -1063,6 +1078,7 @@ class StoredTestZip64InSmallFiles(Abstra
+ with self.assertRaises(zipfile.BadZipFile) as e:
+ zipfile.ZipFile(io.BytesIO(missing_header_offset_extra))
+ self.assertIn('header offset', str(e.exception).lower())
++ self.assertTrue(zipfile.is_zipfile(io.BytesIO(missing_header_offset_extra)))
+
+ # zip64 file size present, zip64 header offset present, one field in
+ # extra, expecting two, equals missing header offset
+@@ -1075,6 +1091,7 @@ class StoredTestZip64InSmallFiles(Abstra
+ with self.assertRaises(zipfile.BadZipFile) as e:
+ zipfile.ZipFile(io.BytesIO(missing_header_offset_extra))
+ self.assertIn('header offset', str(e.exception).lower())
++ self.assertTrue(zipfile.is_zipfile(io.BytesIO(missing_header_offset_extra)))
+
+ # zip64 header offset present, no fields in extra, expecting one,
+ # equals missing header offset
+@@ -1086,6 +1103,63 @@ class StoredTestZip64InSmallFiles(Abstra
+ with self.assertRaises(zipfile.BadZipFile) as e:
+ zipfile.ZipFile(io.BytesIO(missing_header_offset_extra))
+ self.assertIn('header offset', str(e.exception).lower())
++ self.assertTrue(zipfile.is_zipfile(io.BytesIO(missing_header_offset_extra)))
++
++ def test_bad_zip64_end_of_central_dir(self):
++ zipdata = self.make_zip64_file(end_of_central_dir_size=0)
++ with self.assertRaisesRegex(zipfile.BadZipFile, 'Corrupt.*record'):
++ zipfile.ZipFile(io.BytesIO(zipdata))
++ self.assertFalse(zipfile.is_zipfile(io.BytesIO(zipdata)))
++
++ zipdata = self.make_zip64_file(end_of_central_dir_size=100)
++ with self.assertRaisesRegex(zipfile.BadZipFile, 'Corrupt.*record'):
++ zipfile.ZipFile(io.BytesIO(zipdata))
++ self.assertFalse(zipfile.is_zipfile(io.BytesIO(zipdata)))
++
++ zipdata = self.make_zip64_file(offset_to_end_of_central_dir=0)
++ with self.assertRaisesRegex(zipfile.BadZipFile, 'Corrupt.*record'):
++ zipfile.ZipFile(io.BytesIO(zipdata))
++ self.assertFalse(zipfile.is_zipfile(io.BytesIO(zipdata)))
++
++ zipdata = self.make_zip64_file(offset_to_end_of_central_dir=1000)
++ with self.assertRaisesRegex(zipfile.BadZipFile, 'Corrupt.*locator'):
++ zipfile.ZipFile(io.BytesIO(zipdata))
++ self.assertFalse(zipfile.is_zipfile(io.BytesIO(zipdata)))
++
++ def test_zip64_end_of_central_dir_record_not_found(self):
++ zipdata = self.make_zip64_file()
++ zipdata = zipdata.replace(b"PK\x06\x06", b'\x00'*4)
++ with self.assertRaisesRegex(zipfile.BadZipFile, 'record not found'):
++ zipfile.ZipFile(io.BytesIO(zipdata))
++ self.assertFalse(zipfile.is_zipfile(io.BytesIO(zipdata)))
++
++ zipdata = self.make_zip64_file(
++ extensible_data=b'\xca\xfe\x04\x00\x00\x00data')
++ zipdata = zipdata.replace(b"PK\x06\x06", b'\x00'*4)
++ with self.assertRaisesRegex(zipfile.BadZipFile, 'record not found'):
++ zipfile.ZipFile(io.BytesIO(zipdata))
++ self.assertFalse(zipfile.is_zipfile(io.BytesIO(zipdata)))
++
++ def test_zip64_extensible_data(self):
++ # These values are what is set in the make_zip64_file method.
++ expected_file_size = 8
++ expected_compress_size = 8
++ expected_header_offset = 0
++ expected_content = b"test1234"
++
++ zipdata = self.make_zip64_file(
++ extensible_data=b'\xca\xfe\x04\x00\x00\x00data')
++ with zipfile.ZipFile(io.BytesIO(zipdata)) as zf:
++ zinfo = zf.infolist()[0]
++ self.assertEqual(zinfo.file_size, expected_file_size)
++ self.assertEqual(zinfo.compress_size, expected_compress_size)
++ self.assertEqual(zinfo.header_offset, expected_header_offset)
++ self.assertEqual(zf.read(zinfo), expected_content)
++ self.assertTrue(zipfile.is_zipfile(io.BytesIO(zipdata)))
++
++ with self.assertRaisesRegex(zipfile.BadZipFile, 'record not found'):
++ zipfile.ZipFile(io.BytesIO(b'prepended' + zipdata))
++ self.assertFalse(zipfile.is_zipfile(io.BytesIO(b'prepended' + zipdata)))
+
+ def test_generated_valid_zip64_extra(self):
+ # These values are what is set in the make_zip64_file method.
Index: pkgsrc/lang/python314/patches/patch-Lib_zipfile_____init____.py
diff -u /dev/null pkgsrc/lang/python314/patches/patch-Lib_zipfile_____init____.py:1.1
--- /dev/null Sat Oct 11 10:14:06 2025
+++ pkgsrc/lang/python314/patches/patch-Lib_zipfile_____init____.py Sat Oct 11 10:14:06 2025
@@ -0,0 +1,122 @@
+$NetBSD: patch-Lib_zipfile_____init____.py,v 1.1 2025/10/11 10:14:06 wiz Exp $
+
+https://github.com/python/cpython/commit/d11e69d6203080e3ec450446bfed0516727b85c3
+
+--- Lib/zipfile/__init__.py.orig 2025-10-07 09:34:52.000000000 +0000
++++ Lib/zipfile/__init__.py
+@@ -265,7 +265,7 @@ def is_zipfile(filename):
+ else:
+ with open(filename, "rb") as fp:
+ result = _check_zipfile(fp)
+- except OSError:
++ except (OSError, BadZipFile):
+ pass
+ return result
+
+@@ -275,9 +275,6 @@ def _handle_prepended_data(endrec, debug
+
+ # "concat" is zero, unless zip was concatenated to another file
+ concat = endrec[_ECD_LOCATION] - size_cd - offset_cd
+- if endrec[_ECD_SIGNATURE] == stringEndArchive64:
+- # If Zip64 extension structures are present, account for them
+- concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator)
+
+ if debug > 2:
+ inferred = concat + offset_cd
+@@ -289,16 +286,15 @@ def _EndRecData64(fpin, offset, endrec):
+ """
+ Read the ZIP64 end-of-archive records and use that to update endrec
+ """
+- try:
+- fpin.seek(offset - sizeEndCentDir64Locator, 2)
+- except OSError:
+- # If the seek fails, the file is not large enough to contain a ZIP64
++ offset -= sizeEndCentDir64Locator
++ if offset < 0:
++ # The file is not large enough to contain a ZIP64
+ # end-of-archive record, so just return the end record we were given.
+ return endrec
+-
++ fpin.seek(offset)
+ data = fpin.read(sizeEndCentDir64Locator)
+ if len(data) != sizeEndCentDir64Locator:
+- return endrec
++ raise OSError("Unknown I/O error")
+ sig, diskno, reloff, disks = struct.unpack(structEndArchive64Locator, data)
+ if sig != stringEndArchive64Locator:
+ return endrec
+@@ -306,16 +302,33 @@ def _EndRecData64(fpin, offset, endrec):
+ if diskno != 0 or disks > 1:
+ raise BadZipFile("zipfiles that span multiple disks are not supported")
+
+- # Assume no 'zip64 extensible data'
+- fpin.seek(offset - sizeEndCentDir64Locator - sizeEndCentDir64, 2)
++ offset -= sizeEndCentDir64
++ if reloff > offset:
++ raise BadZipFile("Corrupt zip64 end of central directory locator")
++ # First, check the assumption that there is no prepended data.
++ fpin.seek(reloff)
++ extrasz = offset - reloff
+ data = fpin.read(sizeEndCentDir64)
+ if len(data) != sizeEndCentDir64:
+- return endrec
++ raise OSError("Unknown I/O error")
++ if not data.startswith(stringEndArchive64) and reloff != offset:
++ # Since we already have seen the Zip64 EOCD Locator, it's
++ # possible we got here because there is prepended data.
++ # Assume no 'zip64 extensible data'
++ fpin.seek(offset)
++ extrasz = 0
++ data = fpin.read(sizeEndCentDir64)
++ if len(data) != sizeEndCentDir64:
++ raise OSError("Unknown I/O error")
++ if not data.startswith(stringEndArchive64):
++ raise BadZipFile("Zip64 end of central directory record not found")
++
+ sig, sz, create_version, read_version, disk_num, disk_dir, \
+ dircount, dircount2, dirsize, diroffset = \
+ struct.unpack(structEndArchive64, data)
+- if sig != stringEndArchive64:
+- return endrec
++ if (diroffset + dirsize != reloff or
++ sz + 12 != sizeEndCentDir64 + extrasz):
++ raise BadZipFile("Corrupt zip64 end of central directory record")
+
+ # Update the original endrec using data from the ZIP64 record
+ endrec[_ECD_SIGNATURE] = sig
+@@ -325,6 +338,7 @@ def _EndRecData64(fpin, offset, endrec):
+ endrec[_ECD_ENTRIES_TOTAL] = dircount2
+ endrec[_ECD_SIZE] = dirsize
+ endrec[_ECD_OFFSET] = diroffset
++ endrec[_ECD_LOCATION] = offset - extrasz
+ return endrec
+
+
+@@ -358,7 +372,7 @@ def _EndRecData(fpin):
+ endrec.append(filesize - sizeEndCentDir)
+
+ # Try to read the "Zip64 end of central directory" structure
+- return _EndRecData64(fpin, -sizeEndCentDir, endrec)
++ return _EndRecData64(fpin, filesize - sizeEndCentDir, endrec)
+
+ # Either this is not a ZIP file, or it is a ZIP file with an archive
+ # comment. Search the end of the file for the "end of central directory"
+@@ -382,8 +396,7 @@ def _EndRecData(fpin):
+ endrec.append(maxCommentStart + start)
+
+ # Try to read the "Zip64 end of central directory" structure
+- return _EndRecData64(fpin, maxCommentStart + start - filesize,
+- endrec)
++ return _EndRecData64(fpin, maxCommentStart + start, endrec)
+
+ # Unable to find a valid end of central directory structure
+ return None
+@@ -2142,7 +2155,7 @@ class ZipFile:
+ " would require ZIP64 extensions")
+ zip64endrec = struct.pack(
+ structEndArchive64, stringEndArchive64,
+- 44, 45, 45, 0, 0, centDirCount, centDirCount,
++ sizeEndCentDir64 - 12, 45, 45, 0, 0, centDirCount, centDirCount,
+ centDirSize, centDirOffset)
+ self.fp.write(zip64endrec)
+
Home |
Main Index |
Thread Index |
Old Index