From cb6afd7a0a613b9adb8e6df37eb9640b30c7f9ac Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Wed, 24 Sep 2025 11:21:18 +0100 Subject: [PATCH] Fix integer overflow with max limit & batchsize Eliminate unnecessary killCursors command when batchSize == limit can overflow if using Integer.MAX_VALUE for both. JAVA-5667 JAVA-5970 --- .../internal/operation/FindOperation.java | 2 +- .../FindOperationUnitSpecification.groovy | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/driver-core/src/main/com/mongodb/internal/operation/FindOperation.java b/driver-core/src/main/com/mongodb/internal/operation/FindOperation.java index 04d4d7afd67..4e1de40d150 100644 --- a/driver-core/src/main/com/mongodb/internal/operation/FindOperation.java +++ b/driver-core/src/main/com/mongodb/internal/operation/FindOperation.java @@ -390,7 +390,7 @@ private BsonDocument getCommand(final OperationContext operationContext, final i commandDocument.put("limit", new BsonInt32(Math.abs(batchSize))); } else if (batchSize != 0) { int effectiveBatchSize = Math.abs(batchSize); - if (effectiveBatchSize == limit) { + if (effectiveBatchSize == limit && effectiveBatchSize < Integer.MAX_VALUE) { // avoid an open cursor on server side when batchSize and limit are equal effectiveBatchSize++; } diff --git a/driver-core/src/test/unit/com/mongodb/internal/operation/FindOperationUnitSpecification.groovy b/driver-core/src/test/unit/com/mongodb/internal/operation/FindOperationUnitSpecification.groovy index 021b392593c..dd843985bbb 100644 --- a/driver-core/src/test/unit/com/mongodb/internal/operation/FindOperationUnitSpecification.groovy +++ b/driver-core/src/test/unit/com/mongodb/internal/operation/FindOperationUnitSpecification.groovy @@ -102,6 +102,27 @@ class FindOperationUnitSpecification extends OperationUnitSpecification { version << [[3, 2, 0]] * 10 + [[3, 4, 0]] * 10 } + def 'should find with correct command with effective batch size'() { + when: + def operation = new FindOperation(namespace, new BsonDocumentCodec()) + .batchSize(batchSize) + .limit(limit) + + def expectedCommand = new BsonDocument('find', new BsonString(namespace.getCollectionName())) + .append('batchSize', new BsonInt32(commandBatchSize)) + .append('limit', new BsonInt32(commandLimit)) + + then: + testOperation(operation, [7, 0, 0], expectedCommand, async, commandResult) + + where: + async << [true, true, false, false] + batchSize << [10, Integer.MAX_VALUE] * 2 + limit << [10, Integer.MAX_VALUE] * 2 + commandLimit << [10, Integer.MAX_VALUE] * 2 + commandBatchSize << [11, Integer.MAX_VALUE] * 2 + } + def 'should use the readPreference to set secondaryOk for commands'() { when: def operation = new FindOperation(namespace, new DocumentCodec())