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-03 00:29:41 +0000 |
commit | 038c8e529ff493771af752001093fdba8b566268 (patch) | |
tree | 7c1177578c6dd9c7d546c67ac3976ec5ab7a522d | |
parent | ec0158de27c891599c2d442c0e8c92275b7d23b8 (diff) | |
download | mongo-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.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 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. |