diff options
-rw-r--r-- | jstests/core/regex_error.js | 15 | ||||
-rw-r--r-- | jstests/core/regex_limit.js | 7 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_leaf.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_leaf.h | 1 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_leaf_test.cpp | 22 |
5 files changed, 35 insertions, 18 deletions
diff --git a/jstests/core/regex_error.js b/jstests/core/regex_error.js new file mode 100644 index 00000000000..a6deb56c460 --- /dev/null +++ b/jstests/core/regex_error.js @@ -0,0 +1,15 @@ +/** + * Test that the server errors when given an invalid regex. + */ +(function() { + const coll = db.regex_error; + coll.drop(); + + // Run some invalid regexes. + assert.commandFailedWithCode(coll.runCommand("find", {filter: {a: {$regex: "[)"}}}), 51091); + assert.commandFailedWithCode(coll.runCommand("find", {filter: {a: {$regex: "ab\0c"}}}), + ErrorCodes.BadValue); + assert.commandFailedWithCode( + coll.runCommand("find", {filter: {a: {$regex: "ab", $options: "\0i"}}}), + ErrorCodes.BadValue); +})(); diff --git a/jstests/core/regex_limit.js b/jstests/core/regex_limit.js index ebe54097971..71a8c4e915c 100644 --- a/jstests/core/regex_limit.js +++ b/jstests/core/regex_limit.js @@ -7,7 +7,7 @@ const coll = db.regex_limit; coll.drop(); - const kMaxRegexPatternLen = 32764; + const kMaxRegexPatternLen = 32761; // Populate the collection with a document containing a very long string. assert.commandWorked(coll.insert({z: "c".repeat(100000)})); @@ -20,8 +20,7 @@ // Test that a regex pattern exceeding the limit fails. const patternTooLong = "c".repeat(kMaxRegexPatternLen + 1); assert.commandFailedWithCode(coll.runCommand("find", {filter: {z: {$regex: patternTooLong}}}), - ErrorCodes.BadValue); + 51091); assert.commandFailedWithCode( - coll.runCommand("find", {filter: {z: {$in: [new RegExp(patternTooLong)]}}}), - ErrorCodes.BadValue); + coll.runCommand("find", {filter: {z: {$in: [new RegExp(patternTooLong)]}}}), 51091); }()); diff --git a/src/mongo/db/matcher/expression_leaf.cpp b/src/mongo/db/matcher/expression_leaf.cpp index 52d19d188c9..1a0c7934495 100644 --- a/src/mongo/db/matcher/expression_leaf.cpp +++ b/src/mongo/db/matcher/expression_leaf.cpp @@ -217,7 +217,6 @@ inline pcrecpp::RE_Options flags2options(const char* flags) { } const std::set<char> RegexMatchExpression::kValidRegexFlags = {'i', 'm', 's', 'x'}; -constexpr size_t RegexMatchExpression::kMaxPatternSize; RegexMatchExpression::RegexMatchExpression(StringData path, const BSONElement& e) : LeafMatchExpression(REGEX, path), @@ -237,9 +236,6 @@ RegexMatchExpression::RegexMatchExpression(StringData path, StringData regex, St } void RegexMatchExpression::_init() { - uassert( - ErrorCodes::BadValue, "Regular expression is too long", _regex.size() <= kMaxPatternSize); - uassert(ErrorCodes::BadValue, "Regular expression cannot contain an embedded null byte", _regex.find('\0') == std::string::npos); @@ -247,6 +243,10 @@ void RegexMatchExpression::_init() { uassert(ErrorCodes::BadValue, "Regular expression options string cannot contain an embedded null byte", _flags.find('\0') == std::string::npos); + + uassert(51091, + str::stream() << "Regular expression is invalid: " << _re->error(), + _re->error().empty()); } RegexMatchExpression::~RegexMatchExpression() {} diff --git a/src/mongo/db/matcher/expression_leaf.h b/src/mongo/db/matcher/expression_leaf.h index 66c25dcf1c8..8da9948044b 100644 --- a/src/mongo/db/matcher/expression_leaf.h +++ b/src/mongo/db/matcher/expression_leaf.h @@ -282,7 +282,6 @@ public: class RegexMatchExpression : public LeafMatchExpression { public: - static constexpr size_t kMaxPatternSize = 32764; static const std::set<char> kValidRegexFlags; RegexMatchExpression(StringData path, const BSONElement& e); diff --git a/src/mongo/db/matcher/expression_leaf_test.cpp b/src/mongo/db/matcher/expression_leaf_test.cpp index 2b8a7dc816a..be0b2aa9445 100644 --- a/src/mongo/db/matcher/expression_leaf_test.cpp +++ b/src/mongo/db/matcher/expression_leaf_test.cpp @@ -716,8 +716,7 @@ TEST(RegexMatchExpression, MatchesElementExact) { TEST(RegexMatchExpression, TooLargePattern) { string tooLargePattern(50 * 1000, 'z'); - ASSERT_THROWS_CODE( - RegexMatchExpression("a", tooLargePattern, ""), AssertionException, ErrorCodes::BadValue); + ASSERT_THROWS_CODE(RegexMatchExpression("a", tooLargePattern, ""), AssertionException, 51091); } TEST(RegexMatchExpression, MatchesElementSimplePrefix) { @@ -976,15 +975,20 @@ TEST(RegexMatchExpression, RegexOptionsStringCannotContainEmbeddedNullByte) { } } -TEST(RegexMatchExpression, MalformedRegexAcceptedButMatchesNothing) { - RegexMatchExpression regex("a", "[(*ACCEPT)", ""); - ASSERT_FALSE(regex.matchesBSON(BSON("a" - << ""))); - ASSERT_FALSE(regex.matchesBSON(BSON("a" - << "["))); +TEST(RegexMatchExpression, MalformedRegexNotAccepted) { + ASSERT_THROWS_CODE(RegexMatchExpression("a", // path + "[", // regex + "" // options + ), + AssertionException, + 51091); } -TEST(RegexMatchExpression, RegexAcceptsUCPOption) { +TEST(RegexMatchExpression, MalformedRegexWithStartOptionNotAccepted) { + ASSERT_THROWS_CODE(RegexMatchExpression("a", "[(*ACCEPT)", ""), AssertionException, 51091); +} + +TEST(RegexMatchExpression, RegexAcceptsUCPStartOption) { RegexMatchExpression regex("a", "(*UCP)(\\w|\u304C)", ""); ASSERT(regex.matchesBSON(BSON("a" << "k"))); |