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(