diff options
author | David Storch <david.storch@mongodb.com> | 2021-06-02 10:52:33 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-06-02 15:11:25 +0000 |
commit | 55c75b382453b4fe9ae83b1e73437a20a028d9dd (patch) | |
tree | 187bf9075c8e3a221f22a384dd744b4fb43fecaf | |
parent | 157d39a0aea2b2c1dab68f2193fb6cad631e4a65 (diff) | |
download | mongo-55c75b382453b4fe9ae83b1e73437a20a028d9dd.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)
-rw-r--r-- | jstests/aggregation/expressions/indexof_codepoints.js | 16 | ||||
-rw-r--r-- | src/mongo/db/pipeline/expression.cpp | 6 |
2 files changed, 21 insertions, 1 deletions
diff --git a/jstests/aggregation/expressions/indexof_codepoints.js b/jstests/aggregation/expressions/indexof_codepoints.js index 56d43547564..29458275233 100644 --- a/jstests/aggregation/expressions/indexof_codepoints.js +++ b/jstests/aggregation/expressions/indexof_codepoints.js @@ -30,7 +30,21 @@ function testExpressionCodePoints(coll, expression, result, shouldTestEquivalenc } } -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 4cee9ba5a3d..e182d82f0b8 100644 --- a/src/mongo/db/pipeline/expression.cpp +++ b/src/mongo/db/pipeline/expression.cpp @@ -3186,6 +3186,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. |