new file mode 100644
@@ -0,0 +1,840 @@
+From fa676586ba4b399168a4d1d41c30dc2166cc44fd Mon Sep 17 00:00:00 2001
+From: Jeffrey 'Alex' Clark <aclark@aclark.net>
+Date: Thu, 10 Sep 2026 10:12:37 -0400
+Subject: [PATCH] PYTHON-5994 Use exact match for file ID in GridFS delete
+ methods (#3046)
+
+Co-authored-by: Iris <58442094+sleepyStick@users.noreply.github.com>
+
+CVE: CVE-2026-88029
+Upstream-Status: Backport [https://github.com/mongodb/mongo-python-driver/commit/fa676586ba4b399168a4d1d41c30dc2166cc44fd]
+
+Backport Changes:
+- Mapped upstream GridFS operations into the 4.6.3 monolithic
+ gridfs/__init__.py and gridfs/grid_file.py implementations.
+- Ported the synchronous GridIn.abort() regression test to the
+ existing test/test_gridfs_bucket.py suite.
+- Updated the bundled legacy retryable-read GridFS download fixtures
+ to expect the new exact-match filters.
+- Omitted asynchronous and unified integration tests and fixtures because
+ this recipe does not run those upstream integration suites.
+
+Signed-off-by: Yogita Urade <yurade@cisco.com>
+---
+ gridfs/__init__.py | 14 +-
+ gridfs/grid_file.py | 20 ++-
+ .../legacy/gridfs-download-serverErrors.json | 144 +++++++++++++++------
+ test/retryable_reads/legacy/gridfs-download.json | 32 +++--
+ .../legacy/gridfs-downloadByName-serverErrors.json | 44 +++++--
+ .../legacy/gridfs-downloadByName.json | 8 +-
+ test/test_gridfs_bucket.py | 28 ++++
+ 7 files changed, 221 insertions(+), 69 deletions(-)
+
+diff --git a/gridfs/__init__.py b/gridfs/__init__.py
+index 63aa406..8abd0a4 100644
+--- a/gridfs/__init__.py
++++ b/gridfs/__init__.py
+@@ -273,8 +273,8 @@ class GridFS:
+ ``delete`` no longer ensures indexes.
+ """
+ _disallow_transactions(session)
+- self.__files.delete_one({"_id": file_id}, session=session)
+- self.__chunks.delete_many({"files_id": file_id}, session=session)
++ self.__files.delete_one({"_id": {"$eq": file_id}}, session=session)
++ self.__chunks.delete_many({"files_id": {"$eq": file_id}}, session=session)
+
+ def list(self, session: Optional[ClientSession] = None) -> list[str]:
+ """List the names of all files stored in this instance of
+@@ -328,7 +328,7 @@ class GridFS:
+ Added ``session`` parameter.
+ """
+ if filter is not None and not isinstance(filter, abc.Mapping):
+- filter = {"_id": filter}
++ filter = {"_id": {"$eq": filter}}
+
+ _disallow_transactions(session)
+ for f in self.find(filter, *args, session=session, **kwargs):
+@@ -444,6 +444,8 @@ class GridFS:
+ if kwargs:
+ f = self.__files.find_one(kwargs, ["_id"], session=session)
+ else:
++ if document_or_id is not None and not isinstance(document_or_id, abc.Mapping):
++ document_or_id = {"_id": {"$eq": document_or_id}}
+ f = self.__files.find_one(document_or_id, ["_id"], session=session)
+
+ return f is not None
+@@ -826,8 +828,8 @@ class GridFSBucket:
+ Added ``session`` parameter.
+ """
+ _disallow_transactions(session)
+- res = self._files.delete_one({"_id": file_id}, session=session)
+- self._chunks.delete_many({"files_id": file_id}, session=session)
++ res = self._files.delete_one({"_id": {"$eq": file_id}}, session=session)
++ self._chunks.delete_many({"files_id": {"$eq": file_id}}, session=session)
+ if not res.deleted_count:
+ raise NoFile("no file could be deleted because none matched %s" % file_id)
+
+@@ -1012,7 +1014,7 @@ class GridFSBucket:
+ """
+ _disallow_transactions(session)
+ result = self._files.update_one(
+- {"_id": file_id}, {"$set": {"filename": new_filename}}, session=session
++ {"_id": {"$eq": file_id}}, {"$set": {"filename": new_filename}}, session=session
+ )
+ if not result.matched_count:
+ raise NoFile(
+diff --git a/gridfs/grid_file.py b/gridfs/grid_file.py
+index 685d097..e6f7b85 100644
+--- a/gridfs/grid_file.py
++++ b/gridfs/grid_file.py
+@@ -72,7 +72,9 @@ def _grid_in_property(
+
+ def setter(self: Any, value: Any) -> Any:
+ if self._closed:
+- self._coll.files.update_one({"_id": self._file["_id"]}, {"$set": {field_name: value}})
++ self._coll.files.update_one(
++ {"_id": {"$eq": self._file["_id"]}}, {"$set": {field_name: value}}
++ )
+ self._file[field_name] = value
+
+ if read_only:
+@@ -223,8 +225,10 @@ class GridIn:
+
+ def abort(self) -> None:
+ """Remove all chunks/files that may have been uploaded and close."""
+- self._coll.chunks.delete_many({"files_id": self._file["_id"]}, session=self._session)
+- self._coll.files.delete_one({"_id": self._file["_id"]}, session=self._session)
++ self._coll.chunks.delete_many(
++ {"files_id": {"$eq": self._file["_id"]}}, session=self._session
++ )
++ self._coll.files.delete_one({"_id": {"$eq": self._file["_id"]}}, session=self._session)
+ object.__setattr__(self, "_closed", True)
+
+ @property
+@@ -268,7 +272,9 @@ class GridIn:
+ # them now.
+ self._file[name] = value
+ if self._closed:
+- self._coll.files.update_one({"_id": self._file["_id"]}, {"$set": {name: value}})
++ self._coll.files.update_one(
++ {"_id": {"$eq": self._file["_id"]}}, {"$set": {name: value}}
++ )
+
+ def __flush_data(self, data: Any) -> None:
+ """Flush `data` to a chunk."""
+@@ -507,7 +513,9 @@ class GridOut(io.IOBase):
+ def _ensure_file(self) -> None:
+ if not self._file:
+ _disallow_transactions(self._session)
+- self._file = self.__files.find_one({"_id": self.__file_id}, session=self._session)
++ self._file = self.__files.find_one(
++ {"_id": {"$eq": self.__file_id}}, session=self._session
++ )
+ if not self._file:
+ raise NoFile(
+ f"no file in gridfs collection {self.__files!r} with _id {self.__file_id!r}"
+@@ -779,7 +787,7 @@ class _GridOutChunkIterator:
+ return self
+
+ def _create_cursor(self) -> None:
+- filter = {"files_id": self._id}
++ filter = {"files_id": {"$eq": self._id}}
+ if self._next_chunk > 0:
+ filter["n"] = {"$gte": self._next_chunk}
+ _disallow_transactions(self._session)
+diff --git a/test/retryable_reads/legacy/gridfs-download-serverErrors.json b/test/retryable_reads/legacy/gridfs-download-serverErrors.json
+index cec3a50..b5a3126 100644
+--- a/test/retryable_reads/legacy/gridfs-download-serverErrors.json
++++ b/test/retryable_reads/legacy/gridfs-download-serverErrors.json
+@@ -83,7 +83,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -96,7 +98,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -109,7 +113,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -153,7 +159,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -166,7 +174,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -179,7 +189,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -223,7 +235,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -236,7 +250,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -249,7 +265,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -293,7 +311,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -306,7 +326,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -319,7 +341,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -363,7 +387,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -376,7 +402,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -389,7 +417,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -433,7 +463,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -446,7 +478,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -459,7 +493,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -503,7 +539,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -516,7 +554,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -529,7 +569,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -573,7 +615,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -586,7 +630,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -599,7 +645,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -643,7 +691,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -656,7 +706,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -669,7 +721,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -713,7 +767,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -726,7 +782,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -739,7 +797,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -783,7 +843,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -796,7 +858,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -809,7 +873,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -854,7 +920,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -867,7 +935,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -912,7 +982,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+diff --git a/test/retryable_reads/legacy/gridfs-download.json b/test/retryable_reads/legacy/gridfs-download.json
+index 4d0d5a1..8acd5c7 100644
+--- a/test/retryable_reads/legacy/gridfs-download.json
++++ b/test/retryable_reads/legacy/gridfs-download.json
+@@ -71,7 +71,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -84,7 +86,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -128,7 +132,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -141,7 +147,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -154,7 +162,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -202,7 +212,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -244,7 +256,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+@@ -257,7 +271,9 @@
+ "find": "fs.files",
+ "filter": {
+ "_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ }
+ },
+diff --git a/test/retryable_reads/legacy/gridfs-downloadByName-serverErrors.json b/test/retryable_reads/legacy/gridfs-downloadByName-serverErrors.json
+index a64230d..9038e2f 100644
+--- a/test/retryable_reads/legacy/gridfs-downloadByName-serverErrors.json
++++ b/test/retryable_reads/legacy/gridfs-downloadByName-serverErrors.json
+@@ -103,7 +103,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -167,7 +169,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -231,7 +235,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -295,7 +301,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -359,7 +367,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -423,7 +433,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -487,7 +499,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -551,7 +565,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -615,7 +631,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -679,7 +697,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -743,7 +763,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+diff --git a/test/retryable_reads/legacy/gridfs-downloadByName.json b/test/retryable_reads/legacy/gridfs-downloadByName.json
+index 48f2168..282e120 100644
+--- a/test/retryable_reads/legacy/gridfs-downloadByName.json
++++ b/test/retryable_reads/legacy/gridfs-downloadByName.json
+@@ -80,7 +80,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+@@ -144,7 +146,9 @@
+ "find": "fs.chunks",
+ "filter": {
+ "files_id": {
+- "$oid": "000000000000000000000001"
++ "$eq": {
++ "$oid": "000000000000000000000001"
++ }
+ }
+ },
+ "sort": {
+diff --git a/test/test_gridfs_bucket.py b/test/test_gridfs_bucket.py
+index 53e5cad..1352f08 100644
+--- a/test/test_gridfs_bucket.py
++++ b/test/test_gridfs_bucket.py
+@@ -27,6 +27,7 @@ from test.utils import joinall, one, rs_client, rs_or_single_client, single_clie
+ import gridfs
+ from bson.binary import Binary
+ from bson.int64 import Int64
++from bson.min_key import MinKey
+ from bson.objectid import ObjectId
+ from bson.son import SON
+ from gridfs.errors import CorruptGridFile, NoFile
+@@ -34,6 +35,7 @@ from pymongo.errors import (
+ ConfigurationError,
+ NotPrimaryError,
+ ServerSelectionTimeoutError,
++ WriteError,
+ )
+ from pymongo.mongo_client import MongoClient
+ from pymongo.read_preferences import ReadPreference
+@@ -373,6 +375,32 @@ class TestGridfs(IntegrationTest):
+ self.assertRaises(ValueError, gin.write, b"test4")
+ self.assertEqual(0, self.db.fs.chunks.count_documents({"files_id": gin._id}))
+
++ # Server versions older than 5.0 do not support document values with
++ # "$"-prefixed keys.
++ @client_context.require_version_min(5, 0)
++ def test_abort_with_injected_file_id_does_not_delete_other_files(self):
++ bucket = self.fs
++ file1_bytes = b"\x11\x22\x33\x44"
++ bucket.upload_from_stream("file1", file1_bytes)
++
++ upload_stream = bucket.open_upload_stream_with_id(
++ {"$gt": MinKey()}, "file2", chunk_size_bytes=2
++ )
++ upload_stream.write(b"\x55\x66\x77\x88")
++ try:
++ upload_stream.abort()
++ except WriteError:
++ # Newer server versions reject an equality match on "_id" whose
++ # operand itself resembles a query operator, even when the
++ # driver safely wraps it in "$eq". The chunks are still cleaned
++ # up in that case; only the (never created) files document
++ # delete is rejected.
++ pass
++
++ self.assertEqual(file1_bytes, (bucket.open_download_stream_by_name("file1")).read())
++ with self.assertRaises(NoFile):
++ bucket.open_download_stream_by_name("file2")
++
+ def test_download_to_stream(self):
+ file1 = BytesIO(b"hello world")
+ # Test with one chunk.
@@ -8,6 +8,9 @@ HOMEPAGE = "http://github.com/mongodb/mongo-python-driver"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327"
+SRC_URI = "file://CVE-2026-88029.patch \
+ "
+
SRC_URI[sha256sum] = "400074090b9a631f120b42c61b222fd743490c133a5d2f99c0208cefcccc964e"
inherit pypi setuptools3
This patch applies the upstream fix as referenced in [2], using the commit shown in [1]. [1] https://github.com/mongodb/mongo-python-driver/commit/fa676586ba4b399168a4d1d41c30dc2166cc44fd [2] https://jira.mongodb.org/browse/PYTHON-5994 Signed-off-by: Yogita Urade <yurade@cisco.com> --- .../python3-pymongo/CVE-2026-88029.patch | 840 ++++++++++++++++++ .../python/python3-pymongo_4.6.3.bb | 3 + 2 files changed, 843 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-pymongo/CVE-2026-88029.patch