Skip to content

Commit fdb0d3d

Browse files
Clean up of estimated_document_count (#1645)
Control flow of estimated_document_count is needlessly complex when we have C99 available to mix declarations. This fixes a false-positive in static analysis on reply_local being destroyed while uninitialized.
1 parent e4689bc commit fdb0d3d

File tree

1 file changed

+30
-37
lines changed

1 file changed

+30
-37
lines changed

src/libmongoc/src/mongoc/mongoc-collection.c

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <stdio.h>
1919

20+
#include "bson/bson.h"
2021
#include "mongoc-aggregate-private.h"
2122
#include "mongoc-bulk-operation.h"
2223
#include "mongoc-bulk-operation-private.h"
@@ -766,57 +767,49 @@ mongoc_collection_estimated_document_count (mongoc_collection_t *coll,
766767
bson_t *reply,
767768
bson_error_t *error)
768769
{
769-
bson_iter_t iter;
770-
int64_t count = -1;
771-
bool ret;
772-
bson_t reply_local;
773-
bson_t *reply_ptr;
774-
bson_t cmd = BSON_INITIALIZER;
775-
mongoc_server_stream_t *server_stream = NULL;
776-
777770
ENTRY;
778771

779772
BSON_ASSERT_PARAM (coll);
780773

781-
server_stream = mongoc_cluster_stream_for_reads (&coll->client->cluster, read_prefs, NULL, NULL, reply, error);
782-
774+
// No sessionId allowed
783775
if (opts && bson_has_field (opts, "sessionId")) {
784776
bson_set_error (error,
785777
MONGOC_ERROR_COMMAND,
786778
MONGOC_ERROR_COMMAND_INVALID_ARG,
787779
"Collection count must not specify explicit session");
788-
GOTO (done);
780+
RETURN (-1);
789781
}
790782

791-
reply_ptr = reply ? reply : &reply_local;
792-
793-
BSON_APPEND_UTF8 (&cmd, "count", coll->collection);
794-
ret = _mongoc_client_command_with_opts (coll->client,
795-
coll->db,
796-
&cmd,
797-
MONGOC_CMD_READ,
798-
opts,
799-
MONGOC_QUERY_NONE,
800-
read_prefs,
801-
coll->read_prefs,
802-
coll->read_concern,
803-
coll->write_concern,
804-
reply_ptr,
805-
error);
806-
if (ret) {
807-
if (bson_iter_init_find (&iter, reply_ptr, "n")) {
808-
count = bson_iter_as_int64 (&iter);
809-
}
810-
}
783+
// Storage for the reply if no storage was given by caller
784+
bson_t reply_local = BSON_INITIALIZER;
785+
// Write the reply to either the caller's storage or a local variable
786+
bson_t *const reply_ptr = reply ? reply : &reply_local;
787+
788+
// Create and execute a "count" command
789+
bsonBuildDecl (cmd, kv ("count", cstr (coll->collection)));
790+
const bool command_ok = _mongoc_client_command_with_opts (coll->client,
791+
coll->db,
792+
&cmd,
793+
MONGOC_CMD_READ,
794+
opts,
795+
MONGOC_QUERY_NONE,
796+
read_prefs,
797+
coll->read_prefs,
798+
coll->read_concern,
799+
coll->write_concern,
800+
reply_ptr,
801+
error);
802+
bson_destroy (&cmd);
811803

812-
done:
813-
if (!reply) {
814-
bson_destroy (&reply_local);
804+
// Extract the "n" field from the response
805+
int64_t ret_count = -1;
806+
if (command_ok) {
807+
bsonParse (*reply_ptr, find (key ("n"), do (ret_count = bson_iter_as_int64 (&bsonVisitIter))));
815808
}
816-
bson_destroy (&cmd);
817-
mongoc_server_stream_cleanup (server_stream);
809+
// Destroy the local storage. This is a no-op if we used the caller's storage.
810+
bson_destroy (&reply_local);
818811

819-
RETURN (count);
812+
RETURN (ret_count);
820813
}
821814

822815

0 commit comments

Comments
 (0)