summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Storch <david.storch@mongodb.com>2021-06-02 10:52:33 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-06-03 00:29:41 +0000
commit038c8e529ff493771af752001093fdba8b566268 (patch)
tree7c1177578c6dd9c7d546c67ac3976ec5ab7a522d
parentec0158de27c891599c2d442c0e8c92275b7d23b8 (diff)
downloadmongo-038c8e529ff493771af752001093fdba8b566268.tar.gz
SERVER-56819 Make indexOfCP's classic engine impl always return -1 when end is less than start
(cherry picked from commit 934d6de41bb3adbecee23e3837852e29c7ff4af6) (cherry picked from commit 2141bb0d88dc9938fe568a7c4f4584d3c191319a) (cherry picked from commit 55c75b382453b4fe9ae83b1e73437a20a028d9dd) (cherry picked from commit 823909a49c1cd29218c2a696516060511b52580d)
-rw-r--r--jstests/aggregation/expressions/indexof_codepoints.js16
-rw-r--r--src/mongo/db/pipeline/expression.cpp6
2 files changed, 21 insertions, 1 deletions
diff --git a/jstests/aggregation/expressions/indexof_codepoints.js b/jstests/aggregation/expressions/indexof_codepoints.js
index 506b1a13cfa..bd6a261c121 100644
--- a/jstests/aggregation/expressions/indexof_codepoints.js
+++ b/jstests/aggregation/expressions/indexof_codepoints.js
@@ -30,7 +30,21 @@ load("jstests/aggregation/extras/utils.js"); // For assertErrorCode and testExp
}
}
- var coll = db.indexofcp;
+ const coll = db.indexofcp;
+ coll.drop();
+ assert.commandWorked(coll.insert({item: 'foobar foobar', emptyStr: ''}));
+
+ // Test the edge case of searching for an empty string inside an empty string, where the start
+ // index is past the end index. These cases are designed to reproduce SERVER-56819.
+ assert.eq(-1,
+ coll.aggregate({$project: {byteLocation: {$indexOfCP: ['', '$emptyStr', 3]}}})
+ .toArray()[0]
+ .byteLocation);
+ assert.eq(-1,
+ coll.aggregate({$project: {byteLocation: {$indexOfCP: ['', '$emptyStr', 3, 1]}}})
+ .toArray()[0]
+ .byteLocation);
+
coll.drop();
// Insert a dummy document so something flows through the pipeline.
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index 33659fe89e2..c378c7a94c6 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -3045,6 +3045,12 @@ Value ExpressionIndexOfCP::evaluate(const Document& root, Variables* variables)
std::min(codePointLength, static_cast<size_t>(endIndexArg.coerceToInt()));
}
+ // If the start index is past the end, then always return -1 since 'token' does not exist within
+ // these invalid bounds.
+ if (endCodePointIndex < startCodePointIndex) {
+ return Value(-1);
+ }
+
if (startByteIndex == 0 && input.empty() && token.empty()) {
// If we are finding the index of "" in the string "", the below loop will not loop, so we
// need a special case for this.