Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-pymongo for openSUSE:Factory 
checked in at 2026-09-30 16:22:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pymongo (Old)
 and      /work/SRC/openSUSE:Factory/.python-pymongo.new.1465845 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pymongo"

Wed Sep 30 16:22:02 2026 rev:53 rq:1381302 version:4.18.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pymongo/python-pymongo.changes    
2026-09-17 17:00:12.515099739 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-pymongo.new.1465845/python-pymongo.changes   
    2026-09-30 16:22:55.881047301 +0200
@@ -1,0 +2,11 @@
+Tue Sep 29 05:57:39 UTC 2026 - Daniel Garcia <[email protected]>
+
+- Update to 4.18.2 (bsc#1282827, bsc#1282845, bsc#1282844):
+  - Hardened the bson buffer size guard against signed integer
+    overflow. (CVE-2026-96749)
+  - Fixed connection string parsing to percent-decode each host
+    individually. (CVE-2026-96748)
+  - Client-side field level encryption now rejects a KMS endpoint
+    ending in .sock. (CVE-2026-96747)
+
+-------------------------------------------------------------------

Old:
----
  pymongo-4.18.1.tar.gz

New:
----
  pymongo-4.18.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pymongo.spec ++++++
--- /var/tmp/diff_new_pack.Teisk6/_old  2026-09-30 16:22:57.397110699 +0200
+++ /var/tmp/diff_new_pack.Teisk6/_new  2026-09-30 16:22:57.399110783 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-pymongo
-Version:        4.18.1
+Version:        4.18.2
 Release:        0
 Summary:        Python driver for MongoDB
 License:        Apache-2.0

++++++ pymongo-4.18.1.tar.gz -> pymongo-4.18.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/PKG-INFO new/pymongo-4.18.2/PKG-INFO
--- old/pymongo-4.18.1/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
+++ new/pymongo-4.18.2/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: pymongo
-Version: 4.18.1
+Version: 4.18.2
 Summary: PyMongo - the Official MongoDB Python driver
 Project-URL: Homepage, https://www.mongodb.org
 Project-URL: Documentation, 
https://www.mongodb.com/docs/languages/python/pymongo-driver/current/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/bson/buffer.c 
new/pymongo-4.18.2/bson/buffer.c
--- old/pymongo-4.18.1/bson/buffer.c    2020-02-02 01:00:00.000000000 +0100
+++ new/pymongo-4.18.2/bson/buffer.c    2020-02-02 01:00:00.000000000 +0100
@@ -18,6 +18,7 @@
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
 
+#include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -105,18 +106,25 @@
  * Return non-zero and sets MemoryError on allocation failure.
  * Return non-zero and sets ValueError if `size` would exceed 2GiB. */
 static int buffer_assure_space(buffer_t buffer, int size) {
-    int new_size = buffer->position + size;
-    /* Check for overflow. */
-    if (new_size < buffer->position) {
+    long long new_size;
+    if (size < 0) {
         PyErr_SetString(PyExc_ValueError,
                         "Document would overflow BSON size limit");
         return 1;
     }
 
-    if (new_size <= buffer->size) {
+    /* Compute in a wider type so the addition cannot overflow `int`. */
+    new_size = (long long)buffer->position + (long long)size;
+    if (new_size > INT_MAX) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Document would overflow BSON size limit");
+        return 1;
+    }
+
+    if ((int)new_size <= buffer->size) {
         return 0;
     }
-    return buffer_grow(buffer, new_size);
+    return buffer_grow(buffer, (int)new_size);
 }
 
 /* Save `size` bytes from the current position in `buffer` (and grow if 
needed).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/doc/changelog.rst 
new/pymongo-4.18.2/doc/changelog.rst
--- old/pymongo-4.18.1/doc/changelog.rst        2020-02-02 01:00:00.000000000 
+0100
+++ new/pymongo-4.18.2/doc/changelog.rst        2020-02-02 01:00:00.000000000 
+0100
@@ -1,15 +1,33 @@
 Changelog
 =========
 
+Changes in Version 4.18.2 (2026/09/24)
+--------------------------------------
+
+Version 4.18.2 is a bug fix release.
+
+- Hardened the bson buffer size guard against signed integer overflow.
+- Fixed connection string parsing to percent-decode each host individually.
+- Client-side field level encryption now rejects a KMS endpoint ending in
+  ``.sock``.
+
+Issues Resolved
+...............
+
+See the `PyMongo 4.18.2 release notes in JIRA`_ for the list of resolved issues
+in this release.
+
+.. _PyMongo 4.18.2 release notes in JIRA: 
https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=52896
+
 Changes in Version 4.18.1 (2026/09/10)
 --------------------------------------
 
 Version 4.18.1 is a bug fix release.
 
 - Use an exact match for the file ID in GridFS delete methods
-  (`PYTHON-5994`_).
+  (`CVE-2026-88029`_).
 
-.. _PYTHON-5994: https://jira.mongodb.org/browse/PYTHON-5994
+.. _CVE-2026-88029: https://www.cve.org/CVERecord?id=CVE-2026-88029
 
 Changes in Version 4.18.0 (2026/09/03)
 --------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/pymongo/_version.py 
new/pymongo-4.18.2/pymongo/_version.py
--- old/pymongo-4.18.1/pymongo/_version.py      2020-02-02 01:00:00.000000000 
+0100
+++ new/pymongo-4.18.2/pymongo/_version.py      2020-02-02 01:00:00.000000000 
+0100
@@ -19,7 +19,7 @@
 import re
 from typing import Union
 
-__version__ = "4.18.1"
+__version__ = "4.18.2"
 
 
 def get_version_tuple(version: str) -> tuple[Union[int, str], ...]:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/pymongo/asynchronous/encryption.py 
new/pymongo-4.18.2/pymongo/asynchronous/encryption.py
--- old/pymongo-4.18.1/pymongo/asynchronous/encryption.py       2020-02-02 
01:00:00.000000000 +0100
+++ new/pymongo-4.18.2/pymongo/asynchronous/encryption.py       2020-02-02 
01:00:00.000000000 +0100
@@ -187,6 +187,8 @@
             ssl_context=ctx,
         )
         address = parse_host(endpoint, _HTTPS_PORT)
+        if address[0].endswith(".sock"):
+            raise ConfigurationError(f"Invalid KMS endpoint {endpoint!r}")
         sleep_u = kms_context.usleep
         if sleep_u:
             sleep_sec = float(sleep_u) / 1e6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/pymongo/asynchronous/uri_parser.py 
new/pymongo-4.18.2/pymongo/asynchronous/uri_parser.py
--- old/pymongo-4.18.1/pymongo/asynchronous/uri_parser.py       2020-02-02 
01:00:00.000000000 +0100
+++ new/pymongo-4.18.2/pymongo/asynchronous/uri_parser.py       2020-02-02 
01:00:00.000000000 +0100
@@ -18,7 +18,6 @@
 from __future__ import annotations
 
 from typing import Any, Optional
-from urllib.parse import unquote_plus
 
 from pymongo.asynchronous.srv_resolver import _SrvResolver
 from pymongo.common import SRV_SERVICE_NAME, _CaseInsensitiveDictionary
@@ -159,7 +158,6 @@
     else:
         hosts = host_part
 
-    hosts = unquote_plus(hosts)
     srv_max_hosts = srv_max_hosts or options.get("srvMaxHosts")
     srv_allowed_hosts_suffix = srv_allowed_hosts_suffix or 
options.get("srvAllowedHostsSuffix")
     if is_srv:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/pymongo/synchronous/encryption.py 
new/pymongo-4.18.2/pymongo/synchronous/encryption.py
--- old/pymongo-4.18.1/pymongo/synchronous/encryption.py        2020-02-02 
01:00:00.000000000 +0100
+++ new/pymongo-4.18.2/pymongo/synchronous/encryption.py        2020-02-02 
01:00:00.000000000 +0100
@@ -186,6 +186,8 @@
             ssl_context=ctx,
         )
         address = parse_host(endpoint, _HTTPS_PORT)
+        if address[0].endswith(".sock"):
+            raise ConfigurationError(f"Invalid KMS endpoint {endpoint!r}")
         sleep_u = kms_context.usleep
         if sleep_u:
             sleep_sec = float(sleep_u) / 1e6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/pymongo/synchronous/uri_parser.py 
new/pymongo-4.18.2/pymongo/synchronous/uri_parser.py
--- old/pymongo-4.18.1/pymongo/synchronous/uri_parser.py        2020-02-02 
01:00:00.000000000 +0100
+++ new/pymongo-4.18.2/pymongo/synchronous/uri_parser.py        2020-02-02 
01:00:00.000000000 +0100
@@ -18,7 +18,6 @@
 from __future__ import annotations
 
 from typing import Any, Optional
-from urllib.parse import unquote_plus
 
 from pymongo.common import SRV_SERVICE_NAME, _CaseInsensitiveDictionary
 from pymongo.errors import ConfigurationError, InvalidURI
@@ -159,7 +158,6 @@
     else:
         hosts = host_part
 
-    hosts = unquote_plus(hosts)
     srv_max_hosts = srv_max_hosts or options.get("srvMaxHosts")
     srv_allowed_hosts_suffix = srv_allowed_hosts_suffix or 
options.get("srvAllowedHostsSuffix")
     if is_srv:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/pymongo/uri_parser_shared.py 
new/pymongo-4.18.2/pymongo/uri_parser_shared.py
--- old/pymongo-4.18.1/pymongo/uri_parser_shared.py     2020-02-02 
01:00:00.000000000 +0100
+++ new/pymongo-4.18.2/pymongo/uri_parser_shared.py     2020-02-02 
01:00:00.000000000 +0100
@@ -450,10 +450,23 @@
         if not entity:
             raise ConfigurationError("Empty host (or extra comma in host 
list)")
         port = default_port
-        # Unix socket entities don't have ports
+        node = entity
+        # Decoding happens per entity, after splitting on ",".
         if entity.endswith(".sock"):
+            # Unix socket entities don't have ports. Socket paths are the
+            # only host identifiers permitted to contain reserved
+            # characters (e.g. "/") that require escaping.
+            node = unquote_plus(entity)
             port = None
-        nodes.append(parse_host(entity, port))
+        elif entity.startswith("["):
+            # An IPv6 zone index is escaped as "%25" (RFC 6874).
+            node = entity.replace("%25", "%")
+        elif "%" in entity:
+            raise InvalidURI(
+                "Percent-encoding is only allowed in Unix domain socket paths "
+                f"and IPv6 zone indexes, not in hostnames: {entity}"
+            )
+        nodes.append(parse_host(node, port))
     return nodes
 
 
@@ -576,7 +589,6 @@
     if "/" in hosts:
         raise InvalidURI(f"Any '/' in a unix domain socket must be 
percent-encoded: {host_part}")
 
-    hosts = unquote_plus(hosts)
     fqdn = None
     srv_max_hosts = srv_max_hosts or options.get("srvMaxHosts")
     if is_srv:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/test/asynchronous/test_encryption.py 
new/pymongo-4.18.2/test/asynchronous/test_encryption.py
--- old/pymongo-4.18.1/test/asynchronous/test_encryption.py     2020-02-02 
01:00:00.000000000 +0100
+++ new/pymongo-4.18.2/test/asynchronous/test_encryption.py     2020-02-02 
01:00:00.000000000 +0100
@@ -1299,6 +1299,14 @@
         with self.assertRaisesRegex(EncryptionError, "localhost:12345"):
             await self.client_encryption.create_data_key("kmip", 
master_key=master_key)
 
+    async def test_kmip_endpoint_unix_socket_rejected(self):
+        # PYTHON-5990: a masterKey.endpoint ending in ".sock" must not be
+        # treated as a Unix domain socket path. KMS endpoints must be a TCP
+        # host[:port].
+        master_key = {"keyId": "1", "endpoint": "example.sock"}
+        with self.assertRaisesRegex(EncryptionError, "Invalid KMS endpoint"):
+            await self.client_encryption.create_data_key("kmip", 
master_key=master_key)
+
     @unittest.skipUnless(any(AWS_CREDS.values()), "AWS environment credentials 
are not set")
     async def test_05_aws_endpoint_wrong_region(self):
         master_key = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/test/test_bson.py 
new/pymongo-4.18.2/test/test_bson.py
--- old/pymongo-4.18.1/test/test_bson.py        2020-02-02 01:00:00.000000000 
+0100
+++ new/pymongo-4.18.2/test/test_bson.py        2020-02-02 01:00:00.000000000 
+0100
@@ -691,6 +691,14 @@
         self.assertTrue(encode({"x": -9223372036854775808}))
         self.assertRaises(OverflowError, encode, {"x": -9223372036854775809})
 
+    @unittest.skipUnless(bson.has_c(), "This test requires the C extension")
+    def test_encode_size_limit(self):
+        # PYTHON-5996: encoding must raise when a document's encoded size
+        # exceeds the BSON size limit.
+        big_value = "a" * (1 << 30)
+        with self.assertRaises(ValueError):
+            encode({"a": big_value, "b": big_value, "c": big_value})
+
     def test_small_long_encode_decode(self):
         encoded1 = encode({"x": 256})
         decoded1 = decode(encoded1)["x"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/test/test_encryption.py 
new/pymongo-4.18.2/test/test_encryption.py
--- old/pymongo-4.18.1/test/test_encryption.py  2020-02-02 01:00:00.000000000 
+0100
+++ new/pymongo-4.18.2/test/test_encryption.py  2020-02-02 01:00:00.000000000 
+0100
@@ -1293,6 +1293,14 @@
         with self.assertRaisesRegex(EncryptionError, "localhost:12345"):
             self.client_encryption.create_data_key("kmip", 
master_key=master_key)
 
+    def test_kmip_endpoint_unix_socket_rejected(self):
+        # PYTHON-5990: a masterKey.endpoint ending in ".sock" must not be
+        # treated as a Unix domain socket path. KMS endpoints must be a TCP
+        # host[:port].
+        master_key = {"keyId": "1", "endpoint": "example.sock"}
+        with self.assertRaisesRegex(EncryptionError, "Invalid KMS endpoint"):
+            self.client_encryption.create_data_key("kmip", 
master_key=master_key)
+
     @unittest.skipUnless(any(AWS_CREDS.values()), "AWS environment credentials 
are not set")
     def test_05_aws_endpoint_wrong_region(self):
         master_key = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pymongo-4.18.1/test/test_uri_parser.py 
new/pymongo-4.18.2/test/test_uri_parser.py
--- old/pymongo-4.18.1/test/test_uri_parser.py  2020-02-02 01:00:00.000000000 
+0100
+++ new/pymongo-4.18.2/test/test_uri_parser.py  2020-02-02 01:00:00.000000000 
+0100
@@ -86,6 +86,17 @@
         self.assertEqual([("::1", 27017)], split_hosts("[::1]:27017"))
         self.assertEqual([("::1", 27017)], split_hosts("[::1]"))
 
+    def test_split_hosts_percent_encoded_host(self):
+        # PYTHON-5986: percent-encoding in a hostname is rejected rather than
+        # decoded. Only socket paths and IPv6 zone indexes are decoded.
+        self.assertRaises(InvalidURI, split_hosts, 
"example.com%2Cexample.org%3A27017")
+        self.assertRaises(InvalidURI, split_hosts, "example.com%2F27017")
+
+    def test_split_hosts_ipv6_zone_index(self):
+        # An IPv6 zone index is escaped as "%25" (RFC 6874) and must still
+        # decode, unlike percent-encoding in a plain hostname.
+        self.assertEqual([("fe80::1%eth0", 27017)], 
split_hosts("[fe80::1%25eth0]:27017"))
+
     def test_split_options(self):
         self.assertRaises(ConfigurationError, split_options, "foo")
         self.assertRaises(ConfigurationError, split_options, "foo=bar;foo")
@@ -672,6 +683,10 @@
         self.assertRaises(InvalidURI, parse_uri, "mongodb://localhost/%24db")
         self.assertRaises(InvalidURI, parse_uri, "mongodb://localhost/my%20db")
 
+    def test_validate_uri_percent_encoded_host(self):
+        # PYTHON-5986: a percent-encoded hostname is rejected by parse_uri too.
+        self.assertRaises(InvalidURI, parse_uri, 
"mongodb://example.com%2Cexample.org%3A27017/")
+
     def test_validate_uri_srv_structure(self):
         with patch("pymongo.uri_parser_shared._have_dnspython", 
return_value=True):
             self.assertRaises(

Reply via email to