[CXX-1281] collection::find() and collection::distinct() leak a mongoc_cursor_t on some error paths Created: 22/Mar/17  Updated: 29/Mar/17  Resolved: 29/Mar/17

Status: Closed
Project: C++ Driver
Component/s: Implementation
Affects Version/s: None
Fix Version/s: 3.2.0-rc0

Type: Bug Priority: Major - P3
Reporter: J Rassi Assignee: Samuel Rossi (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   
  • If a user calls collection::find() with an invalid value for options::find::max_await_time(), a mongoc_cursor_t object will be leaked when a logic_error is thrown.
  • If a user calls collection::distinct() in circumstances such that mongoc_cursor_new_from_command() reply returns a cursor with an error set, the mongoc_cursor_t object will be leaked when an operation_exception is thrown.


 Comments   
Comment by Githook User [ 29/Mar/17 ]

Author:

{u'username': u'saghm', u'name': u'Saghm Rossi', u'email': u'saghmrossi@gmail.com'}

Message: CXX-1281 collection::find() and collection::distinct() leak a mongoc_cursor_t on some error paths
Branch: master
https://github.com/mongodb/mongo-cxx-driver/commit/c835ec8f7c9d9dfa0c93526cdd3994695fa15faa

Comment by J Rassi [ 22/Mar/17 ]

Initial fix proposal below, created during today's meeting. The below fix should be verified for correctness, and we should consider adding tests that trigger our leak detector against the current version of the code.

diff --git a/src/mongocxx/collection.cpp b/src/mongocxx/collection.cpp
index 306d4c3..3ce3a57 100644
--- a/src/mongocxx/collection.cpp
+++ b/src/mongocxx/collection.cpp
@@ -44,6 +44,7 @@
 #include <mongocxx/private/bulk_write.hh>
 #include <mongocxx/private/client.hh>
 #include <mongocxx/private/collection.hh>
+#include <mongocxx/private/cursor.hh>
 #include <mongocxx/private/database.hh>
 #include <mongocxx/private/libbson.hh>
 #include <mongocxx/private/libmongoc.hh>
@@ -307,18 +308,21 @@ cursor collection::find(view_or_value filter, const options::find& options) {
         rp_ptr = options_converted.read_preference()->_impl->read_preference_t;
     }
 
-    auto mongoc_cursor = libmongoc::collection_find_with_opts(
-        _get_impl().collection_t, filter_bson.bson(), options_bson.bson(), rp_ptr);
+    cursor query_cursor{
+        libmongoc::collection_find_with_opts(
+            _get_impl().collection_t, filter_bson.bson(), options_bson.bson(), rp_ptr),
+        options_converted.cursor_type()};
 
     if (options_converted.max_await_time()) {
         const auto count = options_converted.max_await_time()->count();
         if ((count < 0) || (count >= std::numeric_limits<std::uint32_t>::max())) {
             throw logic_error{error_code::k_invalid_parameter};
         }
-        libmongoc::cursor_set_max_await_time_ms(mongoc_cursor, static_cast<std::uint32_t>(count));
+        libmongoc::cursor_set_max_await_time_ms(query_cursor._impl->cursor_t,
+                                                static_cast<std::uint32_t>(count));
     }
 
-    return cursor{mongoc_cursor, options_converted.cursor_type()};
+    return query_cursor;
 }
 
 stdx::optional<bsoncxx::document::value> collection::find_one(view_or_value filter,
@@ -935,13 +939,13 @@ cursor collection::distinct(bsoncxx::string::view_or_value field_name,
         throw bsoncxx::exception{bsoncxx::error_code::k_internal_error};
     }
 
-    mongoc_cursor_t* fake_cursor =
-        libmongoc::cursor_new_from_command_reply(_get_impl().client_impl->client_t, reply_bson, 0);
-    if (libmongoc::cursor_error(fake_cursor, &error)) {
+    cursor fake_cursor{
+        libmongoc::cursor_new_from_command_reply(_get_impl().client_impl->client_t, reply_bson, 0)};
+    if (libmongoc::cursor_error(fake_cursor._impl->cursor_t, &error)) {
         throw_exception<operation_exception>(error);
     }
 
-    return cursor{fake_cursor};
+    return fake_cursor;
 }
 
 cursor collection::list_indexes() const {

Generated at Wed Feb 07 22:02:02 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.