From 26bcf4ddd7e86885448e981f86aaf51fba0e2539 Mon Sep 17 00:00:00 2001 From: David Storch Date: Mon, 14 Dec 2015 18:22:01 -0500 Subject: SERVER-21407 explicitly disallow $text/$where extensions during MatchExpression parsing --- src/mongo/db/matcher/SConscript | 1 + src/mongo/db/matcher/expression_algo_test.cpp | 8 +- src/mongo/db/matcher/expression_parser.h | 4 +- .../db/matcher/expression_parser_array_test.cpp | 111 ++-- .../db/matcher/expression_parser_geo_test.cpp | 55 +- .../db/matcher/expression_parser_leaf_test.cpp | 713 ++++++++++++--------- src/mongo/db/matcher/expression_parser_test.cpp | 14 +- .../db/matcher/expression_parser_tree_test.cpp | 31 +- src/mongo/db/matcher/extensions_callback.cpp | 8 - src/mongo/db/matcher/extensions_callback.h | 9 +- .../extensions_callback_disallow_extensions.cpp | 44 ++ .../extensions_callback_disallow_extensions.h | 53 ++ src/mongo/db/matcher/matcher.h | 3 +- 13 files changed, 662 insertions(+), 392 deletions(-) create mode 100644 src/mongo/db/matcher/extensions_callback_disallow_extensions.cpp create mode 100644 src/mongo/db/matcher/extensions_callback_disallow_extensions.h (limited to 'src/mongo/db/matcher') diff --git a/src/mongo/db/matcher/SConscript b/src/mongo/db/matcher/SConscript index d8c4fbd8299..e9353127805 100644 --- a/src/mongo/db/matcher/SConscript +++ b/src/mongo/db/matcher/SConscript @@ -38,6 +38,7 @@ env.Library( 'expression_where_base.cpp', 'expression_where_noop.cpp', 'extensions_callback.cpp', + 'extensions_callback_disallow_extensions.cpp', 'extensions_callback_noop.cpp', 'match_details.cpp', 'matchable.cpp', diff --git a/src/mongo/db/matcher/expression_algo_test.cpp b/src/mongo/db/matcher/expression_algo_test.cpp index e3fb3e504ea..a9765403df6 100644 --- a/src/mongo/db/matcher/expression_algo_test.cpp +++ b/src/mongo/db/matcher/expression_algo_test.cpp @@ -37,6 +37,7 @@ #include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression_algo.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/platform/decimal128.h" namespace mongo { @@ -48,7 +49,8 @@ namespace mongo { class ParsedMatchExpression { public: ParsedMatchExpression(const std::string& str) : _obj(fromjson(str)) { - StatusWithMatchExpression result = MatchExpressionParser::parse(_obj); + StatusWithMatchExpression result = + MatchExpressionParser::parse(_obj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(result.getStatus()); _expr = std::move(result.getValue()); } @@ -66,7 +68,9 @@ TEST(ExpressionAlgoIsSubsetOf, NullAndOmittedField) { // Verify that ComparisonMatchExpression::init() prohibits creating a match expression with // an Undefined type. BSONObj undefined = fromjson("{a: undefined}"); - ASSERT_EQUALS(ErrorCodes::BadValue, MatchExpressionParser::parse(undefined).getStatus()); + ASSERT_EQUALS(ErrorCodes::BadValue, + MatchExpressionParser::parse(undefined, ExtensionsCallbackDisallowExtensions()) + .getStatus()); ParsedMatchExpression empty("{}"); ParsedMatchExpression null("{a: null}"); diff --git a/src/mongo/db/matcher/expression_parser.h b/src/mongo/db/matcher/expression_parser.h index 465928ab184..9fc5d18ccc2 100644 --- a/src/mongo/db/matcher/expression_parser.h +++ b/src/mongo/db/matcher/expression_parser.h @@ -48,8 +48,8 @@ public: * caller has to maintain ownership obj * the tree has views (BSONElement) into obj */ - static StatusWithMatchExpression parse( - const BSONObj& obj, const ExtensionsCallback& extensionsCallback = ExtensionsCallback()) { + static StatusWithMatchExpression parse(const BSONObj& obj, + const ExtensionsCallback& extensionsCallback) { // The 0 initializes the match expression tree depth. return MatchExpressionParser(&extensionsCallback)._parse(obj, 0); } diff --git a/src/mongo/db/matcher/expression_parser_array_test.cpp b/src/mongo/db/matcher/expression_parser_array_test.cpp index 29da1ee21c3..965f5a03a1a 100644 --- a/src/mongo/db/matcher/expression_parser_array_test.cpp +++ b/src/mongo/db/matcher/expression_parser_array_test.cpp @@ -36,6 +36,7 @@ #include "mongo/db/json.h" #include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression_array.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" namespace mongo { @@ -43,7 +44,8 @@ using std::string; TEST(MatchExpressionParserArrayTest, Size1) { BSONObj query = BSON("x" << BSON("$size" << 2)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -55,7 +57,8 @@ TEST(MatchExpressionParserArrayTest, Size1) { TEST(MatchExpressionParserArrayTest, SizeAsString) { BSONObj query = BSON("x" << BSON("$size" << "a")); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -66,7 +69,8 @@ TEST(MatchExpressionParserArrayTest, SizeAsString) { TEST(MatchExpressionParserArrayTest, SizeWithDouble) { BSONObj query = BSON("x" << BSON("$size" << 2.5)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -78,7 +82,8 @@ TEST(MatchExpressionParserArrayTest, SizeWithDouble) { TEST(MatchExpressionParserArrayTest, SizeBad) { BSONObj query = BSON("x" << BSON("$size" << BSONNULL)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -86,7 +91,8 @@ TEST(MatchExpressionParserArrayTest, SizeBad) { TEST(MatchExpressionParserArrayTest, ElemMatchArr1) { BSONObj query = BSON("x" << BSON("$elemMatch" << BSON("x" << 1 << "y" << 2))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -98,7 +104,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchArr1) { TEST(MatchExpressionParserArrayTest, ElemMatchAnd) { BSONObj query = BSON("x" << BSON("$elemMatch" << BSON("$and" << BSON_ARRAY(BSON("x" << 1 << "y" << 2))))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -109,7 +116,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchAnd) { TEST(MatchExpressionParserArrayTest, ElemMatchNor) { BSONObj query = BSON("x" << BSON("$elemMatch" << BSON("$nor" << BSON_ARRAY(BSON("x" << 1))))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -121,7 +129,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchNor) { TEST(MatchExpressionParserArrayTest, ElemMatchOr) { BSONObj query = BSON("x" << BSON("$elemMatch" << BSON("$or" << BSON_ARRAY(BSON("x" << 1 << "y" << 2))))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -132,7 +141,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchOr) { TEST(MatchExpressionParserArrayTest, ElemMatchVal1) { BSONObj query = BSON("x" << BSON("$elemMatch" << BSON("$gt" << 5))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -154,7 +164,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef1) { << "db"); BSONObj query = BSON("x" << BSON("$elemMatch" << BSON("$eq" << match))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << match))); @@ -175,7 +186,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef2) { << "db"); BSONObj query = BSON("x" << BSON("$elemMatch" << match)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << match))); @@ -195,7 +207,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef3) { << "$id" << oidx << "foo" << 12345); BSONObj query = BSON("x" << BSON("$elemMatch" << match)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << match))); @@ -227,7 +240,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef4) { << "db"); BSONObj query = BSON("x" << BSON("$elemMatch" << matchOutOfOrder)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << match))); @@ -250,7 +264,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef5) { << "$id" << oidx << "foo" << 12345); BSONObj query = BSON("x" << BSON("$elemMatch" << matchOutOfOrder)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << match))); @@ -278,7 +293,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef6) { << "$id" << oid << "foo" << 12345); BSONObj query = BSON("x" << BSON("$elemMatch" << matchMissingID)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << match))); @@ -305,7 +321,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef7) { << "$id" << oidx << "foo" << 12345); BSONObj query = BSON("x" << BSON("$elemMatch" << matchMissingRef)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << match))); @@ -337,7 +354,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef8) { << "foo" << 12345); BSONObj query = BSON("x" << BSON("$elemMatch" << matchDBOnly)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << match))); @@ -355,7 +373,8 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef8) { TEST(MatchExpressionParserArrayTest, All1) { BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(1 << 2))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); // Verify that the $all got parsed to AND. @@ -371,7 +390,8 @@ TEST(MatchExpressionParserArrayTest, All1) { TEST(MatchExpressionParserArrayTest, AllNull) { BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(BSONNULL))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); // Verify that the $all got parsed to AND. @@ -385,7 +405,8 @@ TEST(MatchExpressionParserArrayTest, AllNull) { TEST(MatchExpressionParserArrayTest, AllBadArg) { BSONObj query = BSON("x" << BSON("$all" << 1)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -398,7 +419,8 @@ TEST(MatchExpressionParserArrayTest, AllBadRegexArg) { BSONObj query = BSON("x" << operand.obj()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -411,7 +433,8 @@ TEST(MatchExpressionParserArrayTest, AllRegex1) { all.appendArray("$all", allArray.obj()); BSONObj query = BSON("a" << all.obj()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); // Verify that the $all got parsed to AND. @@ -437,7 +460,8 @@ TEST(MatchExpressionParserArrayTest, AllRegex2) { all.appendArray("$all", allArray.obj()); BSONObj query = BSON("a" << all.obj()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); // Verify that the $all got parsed to AND. @@ -454,7 +478,8 @@ TEST(MatchExpressionParserArrayTest, AllRegex2) { TEST(MatchExpressionParserArrayTest, AllNonArray) { BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(5))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); // Verify that the $all got parsed to AND. @@ -470,7 +495,8 @@ TEST(MatchExpressionParserArrayTest, AllNonArray) { TEST(MatchExpressionParserArrayTest, AllElemMatch1) { BSONObj internal = BSON("x" << 1 << "y" << 2); BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(BSON("$elemMatch" << internal)))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); // Verify that the $all got parsed to an AND with a single ELEM_MATCH_OBJECT child. @@ -490,7 +516,8 @@ TEST(MatchExpressionParserArrayTest, AllElemMatch1) { TEST(MatchExpressionParserArrayTest, AllElemMatch2) { BSONObj internal = BSON("z" << 1); BSONObj query = BSON("x.y" << BSON("$all" << BSON_ARRAY(BSON("$elemMatch" << internal)))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); // Verify that the $all got parsed to an AND with a single ELEM_MATCH_OBJECT child. @@ -525,7 +552,8 @@ TEST(MatchExpressionParserArrayTest, AllElemMatch2) { // are correct. TEST(MatchExpressionParserArrayTest, AllElemMatch3) { BSONObj query = fromjson("{x: {$all: [{$elemMatch: {y: 1, z: 1}}]}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); std::unique_ptr expr = std::move(result.getValue()); @@ -560,11 +588,12 @@ TEST(MatchExpressionParserArrayTest, AllElemMatchBad) { BSONObj internal = BSON("x" << 1 << "y" << 2); BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(BSON("$elemMatch" << internal) << 5))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); query = BSON("x" << BSON("$all" << BSON_ARRAY(5 << BSON("$elemMatch" << internal)))); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -572,29 +601,34 @@ TEST(MatchExpressionParserArrayTest, AllElemMatchBad) { TEST(MatchExpressionParserArrayTest, AllElemMatchBadMixed) { // $elemMatch first, equality second. BSONObj bad1 = fromjson("{x: {$all: [{$elemMatch: {y: 1}}, 3]}}"); - StatusWithMatchExpression result1 = MatchExpressionParser::parse(bad1); + StatusWithMatchExpression result1 = + MatchExpressionParser::parse(bad1, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result1.isOK()); // equality first, $elemMatch second BSONObj bad2 = fromjson("{x: {$all: [3, {$elemMatch: {y: 1}}]}}"); - StatusWithMatchExpression result2 = MatchExpressionParser::parse(bad2); + StatusWithMatchExpression result2 = + MatchExpressionParser::parse(bad2, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result1.isOK()); // $elemMatch first, object second BSONObj bad3 = fromjson("{x: {$all: [{$elemMatch: {y: 1}}, {z: 1}]}}"); - StatusWithMatchExpression result3 = MatchExpressionParser::parse(bad3); + StatusWithMatchExpression result3 = + MatchExpressionParser::parse(bad3, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result3.isOK()); // object first, $elemMatch second BSONObj bad4 = fromjson("{x: {$all: [{z: 1}, {$elemMatch: {y: 1}}]}}"); - StatusWithMatchExpression result4 = MatchExpressionParser::parse(bad4); + StatusWithMatchExpression result4 = + MatchExpressionParser::parse(bad4, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result4.isOK()); } // $all with empty string. TEST(MatchExpressionParserArrayTest, AllEmptyString) { BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(""))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" @@ -618,7 +652,8 @@ TEST(MatchExpressionParserArrayTest, AllISODate) { const Date_t& notMatch = notMatchResult.getValue(); BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(match))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << notMatch))); @@ -633,7 +668,8 @@ TEST(MatchExpressionParserArrayTest, AllISODate) { // $all on array element with empty string. TEST(MatchExpressionParserArrayTest, AllDottedEmptyString) { BSONObj query = BSON("x.1" << BSON("$all" << BSON_ARRAY(""))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" @@ -659,7 +695,8 @@ TEST(MatchExpressionParserArrayTest, AllDottedISODate) { const Date_t& notMatch = notMatchResult.getValue(); BSONObj query = BSON("x.1" << BSON("$all" << BSON_ARRAY(match))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << notMatch))); diff --git a/src/mongo/db/matcher/expression_parser_geo_test.cpp b/src/mongo/db/matcher/expression_parser_geo_test.cpp index 7b76a9865ed..b8093f67719 100644 --- a/src/mongo/db/matcher/expression_parser_geo_test.cpp +++ b/src/mongo/db/matcher/expression_parser_geo_test.cpp @@ -36,13 +36,15 @@ #include "mongo/db/json.h" #include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression_geo.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" namespace mongo { TEST(MatchExpressionParserGeo, WithinBox) { BSONObj query = fromjson("{a:{$within:{$box:[{x: 4, y:4},[6,6]]}}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(fromjson("{a: [3,4]}"))); @@ -57,7 +59,8 @@ TEST(MatchExpressionParserGeoNear, ParseNear) { "{loc:{$near:{$maxDistance:100, " "$geometry:{type:\"Point\", coordinates:[0,0]}}}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); MatchExpression* exp = result.getValue().get(); @@ -73,7 +76,8 @@ TEST(MatchExpressionParserGeoNear, ParseNearExtraField) { "{loc:{$near:{$maxDistance:100, " "$geometry:{type:\"Point\", coordinates:[0,0]}}, foo: 1}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -86,7 +90,8 @@ TEST(MatchExpressionParserGeoNear, ParseNearExtraField) { TEST(MatchExpressionParserGeoNear, ParseValidNear) { BSONObj query = fromjson("{loc: {$near: [0,0], $maxDistance: 100, $minDistance: 50}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); MatchExpression* exp = result.getValue().get(); @@ -100,28 +105,33 @@ TEST(MatchExpressionParserGeoNear, ParseValidNear) { TEST(MatchExpressionParserGeoNear, ParseInvalidNear) { { BSONObj query = fromjson("{loc: {$maxDistance: 100, $near: [0,0]}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } { BSONObj query = fromjson("{loc: {$minDistance: 100, $near: [0,0]}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } { BSONObj query = fromjson("{loc: {$near: [0,0], $maxDistance: {}}}"); - ASSERT_THROWS(MatchExpressionParser::parse(query), UserException); + ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()), + UserException); } { BSONObj query = fromjson("{loc: {$near: [0,0], $minDistance: {}}}"); - ASSERT_THROWS(MatchExpressionParser::parse(query), UserException); + ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()), + UserException); } } TEST(MatchExpressionParserGeoNear, ParseValidGeoNear) { BSONObj query = fromjson("{loc: {$geoNear: [0,0], $maxDistance: 100, $minDistance: 50}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); MatchExpression* exp = result.getValue().get(); @@ -135,28 +145,33 @@ TEST(MatchExpressionParserGeoNear, ParseValidGeoNear) { TEST(MatchExpressionParserGeoNear, ParseInvalidGeoNear) { { BSONObj query = fromjson("{loc: {$maxDistance: 100, $geoNear: [0,0]}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } { BSONObj query = fromjson("{loc: {$minDistance: 100, $geoNear: [0,0]}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } { BSONObj query = fromjson("{loc: {$geoNear: [0,0], $maxDistance: {}}}"); - ASSERT_THROWS(MatchExpressionParser::parse(query), UserException); + ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()), + UserException); } { BSONObj query = fromjson("{loc: {$geoNear: [0,0], $minDistance: {}}}"); - ASSERT_THROWS(MatchExpressionParser::parse(query), UserException); + ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()), + UserException); } } TEST(MatchExpressionParserGeoNear, ParseValidNearSphere) { BSONObj query = fromjson("{loc: {$nearSphere: [0,0], $maxDistance: 100, $minDistance: 50}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); MatchExpression* exp = result.getValue().get(); @@ -170,21 +185,25 @@ TEST(MatchExpressionParserGeoNear, ParseValidNearSphere) { TEST(MatchExpressionParserGeoNear, ParseInvalidNearSphere) { { BSONObj query = fromjson("{loc: {$maxDistance: 100, $nearSphere: [0,0]}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } { BSONObj query = fromjson("{loc: {$minDistance: 100, $nearSphere: [0,0]}}"); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } { BSONObj query = fromjson("{loc: {$nearSphere: [0,0], $maxDistance: {}}}"); - ASSERT_THROWS(MatchExpressionParser::parse(query), UserException); + ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()), + UserException); } { BSONObj query = fromjson("{loc: {$nearSphere: [0,0], $minDistance: {}}}"); - ASSERT_THROWS(MatchExpressionParser::parse(query), UserException); + ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()), + UserException); } } diff --git a/src/mongo/db/matcher/expression_parser_leaf_test.cpp b/src/mongo/db/matcher/expression_parser_leaf_test.cpp index c5650c25d67..550f0cf0202 100644 --- a/src/mongo/db/matcher/expression_parser_leaf_test.cpp +++ b/src/mongo/db/matcher/expression_parser_leaf_test.cpp @@ -38,6 +38,7 @@ #include "mongo/db/json.h" #include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression_leaf.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/platform/decimal128.h" #include "mongo/util/log.h" @@ -48,7 +49,8 @@ using std::string; TEST(MatchExpressionParserLeafTest, SimpleEQ2) { BSONObj query = BSON("x" << BSON("$eq" << 2)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -58,13 +60,15 @@ TEST(MatchExpressionParserLeafTest, SimpleEQ2) { TEST(MatchExpressionParserLeafTest, SimpleEQUndefined) { BSONObj query = BSON("x" << BSON("$eq" << BSONUndefined)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } TEST(MatchExpressionParserLeafTest, SimpleGT1) { BSONObj query = BSON("x" << BSON("$gt" << 2)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 2))); @@ -73,7 +77,8 @@ TEST(MatchExpressionParserLeafTest, SimpleGT1) { TEST(MatchExpressionParserLeafTest, SimpleLT1) { BSONObj query = BSON("x" << BSON("$lt" << 2)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 1))); @@ -83,7 +88,8 @@ TEST(MatchExpressionParserLeafTest, SimpleLT1) { TEST(MatchExpressionParserLeafTest, SimpleGTE1) { BSONObj query = BSON("x" << BSON("$gte" << 2)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -93,7 +99,8 @@ TEST(MatchExpressionParserLeafTest, SimpleGTE1) { TEST(MatchExpressionParserLeafTest, SimpleLTE1) { BSONObj query = BSON("x" << BSON("$lte" << 2)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 1))); @@ -103,7 +110,8 @@ TEST(MatchExpressionParserLeafTest, SimpleLTE1) { TEST(MatchExpressionParserLeafTest, SimpleNE1) { BSONObj query = BSON("x" << BSON("$ne" << 2)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 1))); @@ -113,33 +121,35 @@ TEST(MatchExpressionParserLeafTest, SimpleNE1) { TEST(MatchExpressionParserLeafTest, SimpleModBad1) { BSONObj query = BSON("x" << BSON("$mod" << BSON_ARRAY(3 << 2))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); query = BSON("x" << BSON("$mod" << BSON_ARRAY(3))); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(!result.isOK()); query = BSON("x" << BSON("$mod" << BSON_ARRAY(3 << 2 << 4))); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(!result.isOK()); query = BSON("x" << BSON("$mod" << BSON_ARRAY("q" << 2))); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(!result.isOK()); query = BSON("x" << BSON("$mod" << 3)); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(!result.isOK()); query = BSON("x" << BSON("$mod" << BSON("a" << 1 << "b" << 2))); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(!result.isOK()); } TEST(MatchExpressionParserLeafTest, SimpleMod1) { BSONObj query = BSON("x" << BSON("$mod" << BSON_ARRAY(3 << 2))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 5))); @@ -149,7 +159,8 @@ TEST(MatchExpressionParserLeafTest, SimpleMod1) { TEST(MatchExpressionParserLeafTest, SimpleModNotNumber) { BSONObj query = BSON("x" << BSON("$mod" << BSON_ARRAY(2 << "r"))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 2))); @@ -162,7 +173,8 @@ TEST(MatchExpressionParserLeafTest, SimpleModNotNumber) { TEST(MatchExpressionParserLeafTest, SimpleIN1) { BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(2 << 3))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -176,7 +188,8 @@ TEST(MatchExpressionParserLeafTest, INSingleDBRef) { << "coll" << "$id" << oid << "$db" << "db")))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); OID oidx = OID::gen(); @@ -238,7 +251,8 @@ TEST(MatchExpressionParserLeafTest, INMultipleDBRef) { << "coll" << "$id" << oid << "$db" << "db")))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); OID oidx = OID::gen(); @@ -337,7 +351,8 @@ TEST(MatchExpressionParserLeafTest, INDBRefWithOptionalField1) { BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$ref" << "coll" << "$id" << oid << "foo" << 12345)))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); OID oidx = OID::gen(); @@ -362,52 +377,57 @@ TEST(MatchExpressionParserLeafTest, INInvalidDBRefs) { // missing $id BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$ref" << "coll")))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); - result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); // second field is not $id query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$ref" << "coll" << "$foo" << 1)))); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); OID oid = OID::gen(); // missing $ref field query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$id" << oid << "foo" << 3)))); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); // missing $id and $ref field query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$db" << "test" << "foo" << 3)))); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } TEST(MatchExpressionParserLeafTest, INExpressionDocument) { BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$foo" << 1)))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } TEST(MatchExpressionParserLeafTest, INNotArray) { BSONObj query = BSON("x" << BSON("$in" << 5)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } TEST(MatchExpressionParserLeafTest, INUndefined) { BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSONUndefined))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } TEST(MatchExpressionParserLeafTest, INNotElemMatch) { BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$elemMatch" << 1)))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -418,14 +438,16 @@ TEST(MatchExpressionParserLeafTest, INRegexTooLong) { BSONObjBuilder operand; operand.appendArray("$in", inArray.obj()); BSONObj query = BSON("x" << operand.obj()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } TEST(MatchExpressionParserLeafTest, INRegexTooLong2) { string tooLargePattern(50 * 1000, 'z'); BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$regex" << tooLargePattern)))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -438,7 +460,8 @@ TEST(MatchExpressionParserLeafTest, INRegexStuff) { operand.appendArray("$in", inArray.obj()); BSONObj query = BSON("a" << operand.obj()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); BSONObj matchFirst = BSON("a" @@ -463,7 +486,8 @@ TEST(MatchExpressionParserLeafTest, INRegexStuff) { TEST(MatchExpressionParserLeafTest, SimpleNIN1) { BSONObj query = BSON("x" << BSON("$nin" << BSON_ARRAY(2 << 3))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 1))); @@ -473,7 +497,8 @@ TEST(MatchExpressionParserLeafTest, SimpleNIN1) { TEST(MatchExpressionParserLeafTest, NINNotArray) { BSONObj query = BSON("x" << BSON("$nin" << 5)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -482,7 +507,8 @@ TEST(MatchExpressionParserLeafTest, Regex1) { BSONObjBuilder b; b.appendRegex("x", "abc", "i"); BSONObj query = b.obj(); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" @@ -498,7 +524,8 @@ TEST(MatchExpressionParserLeafTest, Regex2) { << "abc" << "$options" << "i")); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" @@ -514,7 +541,8 @@ TEST(MatchExpressionParserLeafTest, Regex3) { << "i" << "$regex" << "abc")); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); log() << "result: " << result.getStatus() << endl; ASSERT_TRUE(result.isOK()); @@ -532,26 +560,27 @@ TEST(MatchExpressionParserLeafTest, RegexBad) { << "abc" << "$optionas" << "i")); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); // $regex does not with numbers query = BSON("x" << BSON("$regex" << 123)); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); query = BSON("x" << BSON("$regex" << BSON_ARRAY("abc"))); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); query = BSON("x" << BSON("$optionas" << "i")); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); query = BSON("x" << BSON("$options" << "i")); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -559,7 +588,8 @@ TEST(MatchExpressionParserLeafTest, ExistsYes1) { BSONObjBuilder b; b.appendBool("$exists", true); BSONObj query = BSON("x" << b.obj()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" @@ -572,7 +602,8 @@ TEST(MatchExpressionParserLeafTest, ExistsNO1) { BSONObjBuilder b; b.appendBool("$exists", false); BSONObj query = BSON("x" << b.obj()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" @@ -583,7 +614,8 @@ TEST(MatchExpressionParserLeafTest, ExistsNO1) { TEST(MatchExpressionParserLeafTest, Type1) { BSONObj query = BSON("x" << BSON("$type" << String)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" @@ -593,7 +625,8 @@ TEST(MatchExpressionParserLeafTest, Type1) { TEST(MatchExpressionParserLeafTest, Type2) { BSONObj query = BSON("x" << BSON("$type" << (double)NumberDouble)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 5.3))); @@ -602,7 +635,8 @@ TEST(MatchExpressionParserLeafTest, Type2) { TEST(MatchExpressionParserLeafTest, TypeDoubleOperator) { BSONObj query = BSON("x" << BSON("$type" << 1.5)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 5.3))); @@ -612,7 +646,8 @@ TEST(MatchExpressionParserLeafTest, TypeDoubleOperator) { TEST(MatchExpressionParserLeafTest, TypeDecimalOperator) { if (Decimal128::enabled) { BSONObj query = BSON("x" << BSON("$type" << mongo::NumberDecimal)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT_FALSE(result.getValue()->matchesBSON(BSON("x" << 5.3))); @@ -622,7 +657,8 @@ TEST(MatchExpressionParserLeafTest, TypeDecimalOperator) { TEST(MatchExpressionParserLeafTest, TypeNull) { BSONObj query = BSON("x" << BSON("$type" << jstNULL)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSONObj())); @@ -636,7 +672,8 @@ TEST(MatchExpressionParserLeafTest, TypeBadType) { BSONObjBuilder b; b.append("$type", (JSTypeMax + 1)); BSONObj query = BSON("x" << b.obj()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 5.3))); @@ -645,22 +682,28 @@ TEST(MatchExpressionParserLeafTest, TypeBadType) { TEST(MatchExpressionParserLeafTest, TypeBad) { BSONObj query = BSON("x" << BSON("$type" << BSON("x" << 1))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } TEST(MatchExpressionParserLeafTest, TypeBadString) { - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: null}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: true}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: {}}}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse( - fromjson("{a: {$type: ObjectId('000000000000000000000000')}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: []}}")).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: null}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: true}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: {}}}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK( + MatchExpressionParser::parse(fromjson("{a: {$type: ObjectId('000000000000000000000000')}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: []}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); } TEST(MatchExpressionParserLeafTest, TypeStringnameDouble) { - StatusWithMatchExpression typeNumberDouble = - MatchExpressionParser::parse(fromjson("{a: {$type: 'double'}}")); + StatusWithMatchExpression typeNumberDouble = MatchExpressionParser::parse( + fromjson("{a: {$type: 'double'}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(typeNumberDouble.getStatus()); TypeMatchExpression* tmeNumberDouble = static_cast(typeNumberDouble.getValue().get()); @@ -671,8 +714,8 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameDouble) { TEST(MatchExpressionParserLeafTest, TypeStringNameNumberDecimal) { if (Decimal128::enabled) { - StatusWithMatchExpression typeNumberDecimal = - MatchExpressionParser::parse(fromjson("{a: {$type: 'decimal'}}")); + StatusWithMatchExpression typeNumberDecimal = MatchExpressionParser::parse( + fromjson("{a: {$type: 'decimal'}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(typeNumberDecimal.getStatus()); TypeMatchExpression* tmeNumberDecimal = static_cast(typeNumberDecimal.getValue().get()); @@ -683,8 +726,8 @@ TEST(MatchExpressionParserLeafTest, TypeStringNameNumberDecimal) { } TEST(MatchExpressionParserLeafTest, TypeStringnameNumberInt) { - StatusWithMatchExpression typeNumberInt = - MatchExpressionParser::parse(fromjson("{a: {$type: 'int'}}")); + StatusWithMatchExpression typeNumberInt = MatchExpressionParser::parse( + fromjson("{a: {$type: 'int'}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(typeNumberInt.getStatus()); TypeMatchExpression* tmeNumberInt = static_cast(typeNumberInt.getValue().get()); @@ -694,8 +737,8 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameNumberInt) { } TEST(MatchExpressionParserLeafTest, TypeStringnameNumberLong) { - StatusWithMatchExpression typeNumberLong = - MatchExpressionParser::parse(fromjson("{a: {$type: 'long'}}")); + StatusWithMatchExpression typeNumberLong = MatchExpressionParser::parse( + fromjson("{a: {$type: 'long'}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(typeNumberLong.getStatus()); TypeMatchExpression* tmeNumberLong = static_cast(typeNumberLong.getValue().get()); @@ -705,8 +748,8 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameNumberLong) { } TEST(MatchExpressionParserLeafTest, TypeStringnameString) { - StatusWithMatchExpression typeString = - MatchExpressionParser::parse(fromjson("{a: {$type: 'string'}}")); + StatusWithMatchExpression typeString = MatchExpressionParser::parse( + fromjson("{a: {$type: 'string'}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(typeString.getStatus()); TypeMatchExpression* tmeString = static_cast(typeString.getValue().get()); ASSERT(tmeString->getType() == String); @@ -715,8 +758,8 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameString) { } TEST(MatchExpressionParserLeafTest, TypeStringnamejstOID) { - StatusWithMatchExpression typejstOID = - MatchExpressionParser::parse(fromjson("{a: {$type: 'objectId'}}")); + StatusWithMatchExpression typejstOID = MatchExpressionParser::parse( + fromjson("{a: {$type: 'objectId'}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(typejstOID.getStatus()); TypeMatchExpression* tmejstOID = static_cast(typejstOID.getValue().get()); ASSERT(tmejstOID->getType() == jstOID); @@ -725,8 +768,8 @@ TEST(MatchExpressionParserLeafTest, TypeStringnamejstOID) { } TEST(MatchExpressionParserLeafTest, TypeStringnamejstNULL) { - StatusWithMatchExpression typejstNULL = - MatchExpressionParser::parse(fromjson("{a: {$type: 'null'}}")); + StatusWithMatchExpression typejstNULL = MatchExpressionParser::parse( + fromjson("{a: {$type: 'null'}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(typejstNULL.getStatus()); TypeMatchExpression* tmejstNULL = static_cast(typejstNULL.getValue().get()); @@ -736,8 +779,8 @@ TEST(MatchExpressionParserLeafTest, TypeStringnamejstNULL) { } TEST(MatchExpressionParserLeafTest, TypeStringnameBool) { - StatusWithMatchExpression typeBool = - MatchExpressionParser::parse(fromjson("{a: {$type: 'bool'}}")); + StatusWithMatchExpression typeBool = MatchExpressionParser::parse( + fromjson("{a: {$type: 'bool'}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(typeBool.getStatus()); TypeMatchExpression* tmeBool = static_cast(typeBool.getValue().get()); ASSERT(tmeBool->getType() == Bool); @@ -746,8 +789,8 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameBool) { } TEST(MatchExpressionParserLeafTest, TypeStringnameObject) { - StatusWithMatchExpression typeObject = - MatchExpressionParser::parse(fromjson("{a: {$type: 'object'}}")); + StatusWithMatchExpression typeObject = MatchExpressionParser::parse( + fromjson("{a: {$type: 'object'}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(typeObject.getStatus()); TypeMatchExpression* tmeObject = static_cast(typeObject.getValue().get()); ASSERT(tmeObject->getType() == Object); @@ -756,8 +799,8 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameObject) { } TEST(MatchExpressionParserLeafTest, TypeStringnameArray) { - StatusWithMatchExpression typeArray = - MatchExpressionParser::parse(fromjson("{a: {$type: 'array'}}")); + StatusWithMatchExpression typeArray = MatchExpressionParser::parse( + fromjson("{a: {$type: 'array'}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(typeArray.getStatus()); TypeMatchExpression* tmeArray = static_cast(typeArray.getValue().get()); ASSERT(tmeArray->getType() == Array); @@ -766,8 +809,8 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameArray) { } TEST(MatchExpressionParserLeafTest, TypeStringnameNumber) { - StatusWithMatchExpression typeNumber = - MatchExpressionParser::parse(fromjson("{a: {$type: 'number'}}")); + StatusWithMatchExpression typeNumber = MatchExpressionParser::parse( + fromjson("{a: {$type: 'number'}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(typeNumber.getStatus()); TypeMatchExpression* tmeNumber = static_cast(typeNumber.getValue().get()); ASSERT_TRUE(tmeNumber->matchesBSON(fromjson("{a: 5.4}"))); @@ -779,41 +822,45 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameNumber) { TEST(MatchExpressionParserTest, BitTestMatchExpressionValidMask) { const double k2Power53 = scalbn(1, 32); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << 54))).getStatus()); - ASSERT_OK( - MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllSet" << std::numeric_limits::max()))).getStatus()); - ASSERT_OK( - MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << k2Power53))).getStatus()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << k2Power53 - 1))) - .getStatus()); - - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << 54))).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << 54)), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllClear" << std::numeric_limits::max()))) - .getStatus()); - ASSERT_OK( - MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << k2Power53))).getStatus()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << k2Power53 - 1))) - .getStatus()); - - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << 54))).getStatus()); - ASSERT_OK( - MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnySet" << std::numeric_limits::max()))).getStatus()); - ASSERT_OK( - MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << k2Power53))).getStatus()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << k2Power53 - 1))) - .getStatus()); - - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << 54))).getStatus()); + BSON("a" << BSON("$bitsAllSet" << std::numeric_limits::max())), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << k2Power53)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << k2Power53 - 1)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << 54)), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnyClear" << std::numeric_limits::max()))) - .getStatus()); - ASSERT_OK( - MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << k2Power53))).getStatus()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << k2Power53 - 1))) - .getStatus()); + BSON("a" << BSON("$bitsAllClear" << std::numeric_limits::max())), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << k2Power53)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << k2Power53 - 1)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << 54)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse( + BSON("a" << BSON("$bitsAnySet" << std::numeric_limits::max())), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << k2Power53)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << k2Power53 - 1)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << 54)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse( + BSON("a" << BSON("$bitsAnyClear" << std::numeric_limits::max())), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << k2Power53)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << k2Power53 - 1)), + ExtensionsCallbackDisallowExtensions()).getStatus()); } TEST(MatchExpressionParserTest, BitTestMatchExpressionValidArray) { @@ -823,271 +870,335 @@ TEST(MatchExpressionParserTest, BitTestMatchExpressionValidArray) { ASSERT_EQ(BSONType::NumberLong, bsonArrayLongLong[2].type()); ASSERT_EQ(BSONType::NumberLong, bsonArrayLongLong[3].type()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(0)))) - .getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(0))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(0 << 1 << 2 << 3)))).getStatus()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << bsonArrayLongLong))) - .getStatus()); + BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(0 << 1 << 2 << 3))), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << bsonArrayLongLong)), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(0)))) - .getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(0))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(0 << 1 << 2 << 3)))).getStatus()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << bsonArrayLongLong))) - .getStatus()); + BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(0 << 1 << 2 << 3))), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << bsonArrayLongLong)), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(0)))) - .getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(0))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(0 << 1 << 2 << 3)))).getStatus()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << bsonArrayLongLong))) - .getStatus()); + BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(0 << 1 << 2 << 3))), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << bsonArrayLongLong)), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(0)))) - .getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(0))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(0 << 1 << 2 << 3)))).getStatus()); - ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << bsonArrayLongLong))) - .getStatus()); + BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(0 << 1 << 2 << 3))), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << bsonArrayLongLong)), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); } TEST(MatchExpressionParserTest, BitTestMatchExpressionValidBinData) { ASSERT_OK( MatchExpressionParser::parse( - fromjson("{a: {$bitsAllSet: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}")) - .getStatus()); + fromjson("{a: {$bitsAllSet: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK( MatchExpressionParser::parse( fromjson( - "{a: {$bitsAllClear: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}")) - .getStatus()); + "{a: {$bitsAllClear: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK( MatchExpressionParser::parse( - fromjson("{a: {$bitsAnySet: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}")) - .getStatus()); + fromjson("{a: {$bitsAnySet: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_OK( MatchExpressionParser::parse( fromjson( - "{a: {$bitsAnyClear: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}")) - .getStatus()); + "{a: {$bitsAnyClear: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); } TEST(MatchExpressionParserTest, BitTestMatchExpressionInvalidMaskType) { - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: null}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: true}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: {}}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: ''}}")).getStatus()); - - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: null}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: true}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: {}}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: ''}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse( - fromjson("{a: {$bitsAllClear: ObjectId('000000000000000000000000')}}")).getStatus()); - - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: null}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: true}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: {}}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: ''}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse( - fromjson("{a: {$bitsAnySet: ObjectId('000000000000000000000000')}}")).getStatus()); - - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: null}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: true}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: {}}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: ''}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse( - fromjson("{a: {$bitsAnyClear: ObjectId('000000000000000000000000')}}")).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: null}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: true}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: {}}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: ''}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: null}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: true}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: {}}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: ''}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse( + fromjson("{a: {$bitsAllClear: ObjectId('000000000000000000000000')}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: null}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: true}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: {}}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: ''}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse( + fromjson("{a: {$bitsAnySet: ObjectId('000000000000000000000000')}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: null}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: true}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: {}}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: ''}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse( + fromjson("{a: {$bitsAnyClear: ObjectId('000000000000000000000000')}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); } TEST(MatchExpressionParserTest, BitTestMatchExpressionInvalidMaskValue) { const double kLongLongMaxAsDouble = scalbn(1, std::numeric_limits::digits); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: NaN}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: -54}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllSet" << std::numeric_limits::max()))).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: NaN}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: -54}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllSet" << kLongLongMaxAsDouble))).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: 2.5}}")).getStatus()); - - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: NaN}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: -54}}")).getStatus()); + BSON("a" << BSON("$bitsAllSet" << std::numeric_limits::max())), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( - MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllClear" << std::numeric_limits::max()))).getStatus()); + MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << kLongLongMaxAsDouble)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: 2.5}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: NaN}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: -54}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllClear" << kLongLongMaxAsDouble))).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: 2.5}}")).getStatus()); - - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: NaN}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: -54}}")).getStatus()); + BSON("a" << BSON("$bitsAllClear" << std::numeric_limits::max())), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( - MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnySet" << std::numeric_limits::max()))).getStatus()); + MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << kLongLongMaxAsDouble)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: 2.5}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: NaN}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: -54}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnySet" << kLongLongMaxAsDouble))).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: 2.5}}")).getStatus()); - - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: NaN}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: -54}}")).getStatus()); + BSON("a" << BSON("$bitsAnySet" << std::numeric_limits::max())), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( - MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnyClear" << std::numeric_limits::max()))).getStatus()); + MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << kLongLongMaxAsDouble)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: 2.5}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: NaN}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: -54}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK(MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnyClear" << kLongLongMaxAsDouble))).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: 2.5}}")).getStatus()); + BSON("a" << BSON("$bitsAnyClear" << std::numeric_limits::max())), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK( + MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << kLongLongMaxAsDouble)), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: 2.5}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); } TEST(MatchExpressionParserTest, BitTestMatchExpressionInvalidArray) { - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [null]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [true]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: ['']}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [{}]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [[]]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [-1]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [2.5]}}")).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [null]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [true]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: ['']}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [{}]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [[]]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [-1]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [2.5]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( fromjson( - "{a: {$bitsAllSet: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}")) - .getStatus()); - - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [null]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [true]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: ['']}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [{}]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [[]]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [-1]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [2.5]}}")).getStatus()); + "{a: {$bitsAllSet: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [null]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [true]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: ['']}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [{}]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [[]]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [-1]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [2.5]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( fromjson( - "{a: {$bitsAllClear: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}")) - .getStatus()); - - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [null]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [true]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: ['']}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [{}]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [[]]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [-1]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [2.5]}}")).getStatus()); + "{a: {$bitsAllClear: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [null]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [true]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: ['']}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [{}]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [[]]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [-1]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [2.5]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( fromjson( - "{a: {$bitsAnySet: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}")) - .getStatus()); - - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [null]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [true]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: ['']}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [{}]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [[]]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [-1]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [2.5]}}")).getStatus()); + "{a: {$bitsAnySet: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [null]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [true]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: ['']}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [{}]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [[]]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [-1]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [2.5]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( fromjson( - "{a: {$bitsAnyClear: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}")) - .getStatus()); + "{a: {$bitsAnyClear: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); } TEST(MatchExpressionParserTest, BitTestMatchExpressionInvalidArrayValue) { - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [-54]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [NaN]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [2.5]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [1e100]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [-1e100]}}")).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [-54]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [NaN]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [2.5]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [1e100]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [-1e100]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits::min())))) - .getStatus()); - - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [-54]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [NaN]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [2.5]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [1e100]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [-1e100]}}")).getStatus()); + BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits::min()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [-54]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [NaN]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [2.5]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [1e100]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [-1e100]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits::min())))) - .getStatus()); - - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [-54]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [NaN]}}")).getStatus()); - ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [2.5]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [1e100]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [-1e100]}}")).getStatus()); + BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits::min()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [-54]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [NaN]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [2.5]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [1e100]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [-1e100]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits::min())))) - .getStatus()); - - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [-54]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [NaN]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [2.5]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [1e100]}}")).getStatus()); - ASSERT_NOT_OK( - MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [-1e100]}}")).getStatus()); + BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits::min()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); + + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [-54]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [NaN]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [2.5]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [1e100]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); + ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [-1e100]}}"), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits::min())))) - .getStatus()); + BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits::min()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); } } diff --git a/src/mongo/db/matcher/expression_parser_test.cpp b/src/mongo/db/matcher/expression_parser_test.cpp index 4927cd29229..8bad5986891 100644 --- a/src/mongo/db/matcher/expression_parser_test.cpp +++ b/src/mongo/db/matcher/expression_parser_test.cpp @@ -36,12 +36,14 @@ #include "mongo/db/json.h" #include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression_leaf.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" namespace mongo { TEST(MatchExpressionParserTest, SimpleEQ1) { BSONObj query = BSON("x" << 2); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 2))); @@ -50,7 +52,8 @@ TEST(MatchExpressionParserTest, SimpleEQ1) { TEST(MatchExpressionParserTest, Multiple1) { BSONObj query = BSON("x" << 5 << "y" << BSON("$gt" << 5 << "$lt" << 8)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 5 << "y" << 7))); @@ -62,15 +65,16 @@ TEST(MatchExpressionParserTest, Multiple1) { TEST(AtomicMatchExpressionTest, Simple1) { BSONObj query = BSON("x" << 5 << "$atomic" << BSON("$gt" << 5 << "$lt" << 8)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); query = BSON("x" << 5 << "$isolated" << 1); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); query = BSON("x" << 5 << "y" << BSON("$isolated" << 1)); - result = MatchExpressionParser::parse(query); + result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } diff --git a/src/mongo/db/matcher/expression_parser_tree_test.cpp b/src/mongo/db/matcher/expression_parser_tree_test.cpp index 6e4530a1a29..a5a3413eec2 100644 --- a/src/mongo/db/matcher/expression_parser_tree_test.cpp +++ b/src/mongo/db/matcher/expression_parser_tree_test.cpp @@ -36,12 +36,14 @@ #include "mongo/db/json.h" #include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression_leaf.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" namespace mongo { TEST(MatchExpressionParserTreeTest, OR1) { BSONObj query = BSON("$or" << BSON_ARRAY(BSON("x" << 1) << BSON("y" << 2))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 1))); @@ -53,7 +55,8 @@ TEST(MatchExpressionParserTreeTest, OR1) { TEST(MatchExpressionParserTreeTest, OREmbedded) { BSONObj query1 = BSON("$or" << BSON_ARRAY(BSON("x" << 1) << BSON("y" << 2))); BSONObj query2 = BSON("$or" << BSON_ARRAY(query1)); - StatusWithMatchExpression result = MatchExpressionParser::parse(query2); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query2, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 1))); @@ -65,7 +68,8 @@ TEST(MatchExpressionParserTreeTest, OREmbedded) { TEST(MatchExpressionParserTreeTest, AND1) { BSONObj query = BSON("$and" << BSON_ARRAY(BSON("x" << 1) << BSON("y" << 2))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -78,7 +82,8 @@ TEST(MatchExpressionParserTreeTest, AND1) { TEST(MatchExpressionParserTreeTest, NOREmbedded) { BSONObj query = BSON("$nor" << BSON_ARRAY(BSON("x" << 1) << BSON("y" << 2))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1))); @@ -89,7 +94,8 @@ TEST(MatchExpressionParserTreeTest, NOREmbedded) { TEST(MatchExpressionParserTreeTest, NOT1) { BSONObj query = BSON("x" << BSON("$not" << BSON("$gt" << 5))); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(result.getValue()->matchesBSON(BSON("x" << 2))); @@ -110,7 +116,8 @@ TEST(MatchExpressionParserTreeTest, MaximumTreeDepthNotExceed) { } BSONObj query = fromjson(ss.str()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT(result.isOK()); } @@ -128,7 +135,8 @@ TEST(MatchExpressionParserTreeTest, MaximumTreeDepthExceed) { } BSONObj query = fromjson(ss.str()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -147,7 +155,8 @@ TEST(MatchExpressionParserTreeTest, MaximumTreeDepthExceededNestedNots) { } BSONObj query = fromjson(ss.str()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -165,7 +174,8 @@ TEST(MatchExpressionParserTreeTest, MaximumTreeDepthExceededNestedElemMatch) { } BSONObj query = fromjson(ss.str()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_FALSE(result.isOK()); } @@ -173,7 +183,8 @@ TEST(MatchExpressionParserLeafTest, NotRegex1) { BSONObjBuilder b; b.appendRegex("$not", "abc", "i"); BSONObj query = BSON("x" << b.obj()); - StatusWithMatchExpression result = MatchExpressionParser::parse(query); + StatusWithMatchExpression result = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(result.isOK()); ASSERT(!result.getValue()->matchesBSON(BSON("x" diff --git a/src/mongo/db/matcher/extensions_callback.cpp b/src/mongo/db/matcher/extensions_callback.cpp index a2fd775865b..197e5d473c1 100644 --- a/src/mongo/db/matcher/extensions_callback.cpp +++ b/src/mongo/db/matcher/extensions_callback.cpp @@ -34,14 +34,6 @@ namespace mongo { -StatusWithMatchExpression ExtensionsCallback::parseWhere(BSONElement where) const { - return {Status(ErrorCodes::NoMatchParseContext, "no context for parsing $where")}; -} - -StatusWithMatchExpression ExtensionsCallback::parseText(BSONElement text) const { - return {Status(ErrorCodes::NoMatchParseContext, "no context for parsing $text")}; -} - StatusWith ExtensionsCallback::extractTextMatchExpressionParams(BSONElement text) { TextMatchExpressionBase::TextParams params; diff --git a/src/mongo/db/matcher/extensions_callback.h b/src/mongo/db/matcher/extensions_callback.h index 869d90ef8f3..a0cab74b652 100644 --- a/src/mongo/db/matcher/extensions_callback.h +++ b/src/mongo/db/matcher/extensions_callback.h @@ -37,17 +37,12 @@ namespace mongo { /** * Certain match clauses (the "extension" clauses, namely $text and $where) require context in * order to perform parsing. This context is captured inside of an ExtensionsCallback object. - * - * The default implementations of parseText() and parseWhere() simply return an error Status. - * Instead of constructing an ExtensionsCallback object directly, an instance of one of the - * derived classes (ExtensionsCallbackReal or ExtensionsCallbackNoop) should generally be used - * instead. */ class ExtensionsCallback { public: - virtual StatusWithMatchExpression parseText(BSONElement text) const; + virtual StatusWithMatchExpression parseText(BSONElement text) const = 0; - virtual StatusWithMatchExpression parseWhere(BSONElement where) const; + virtual StatusWithMatchExpression parseWhere(BSONElement where) const = 0; virtual ~ExtensionsCallback() {} diff --git a/src/mongo/db/matcher/extensions_callback_disallow_extensions.cpp b/src/mongo/db/matcher/extensions_callback_disallow_extensions.cpp new file mode 100644 index 00000000000..2c68c97a23a --- /dev/null +++ b/src/mongo/db/matcher/extensions_callback_disallow_extensions.cpp @@ -0,0 +1,44 @@ +/** + * Copyright (C) 2015 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" + +namespace mongo { + +StatusWithMatchExpression ExtensionsCallbackDisallowExtensions::parseWhere( + BSONElement where) const { + return {Status(ErrorCodes::NoMatchParseContext, "no context for parsing $where")}; +} + +StatusWithMatchExpression ExtensionsCallbackDisallowExtensions::parseText(BSONElement text) const { + return {Status(ErrorCodes::NoMatchParseContext, "no context for parsing $text")}; +} + +} // namespace mongo diff --git a/src/mongo/db/matcher/extensions_callback_disallow_extensions.h b/src/mongo/db/matcher/extensions_callback_disallow_extensions.h new file mode 100644 index 00000000000..c641aecd0d1 --- /dev/null +++ b/src/mongo/db/matcher/extensions_callback_disallow_extensions.h @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2015 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/db/matcher/extensions_callback.h" + +namespace mongo { + +/** + * ExtensionsCallbackDisallowExtensions produces an error during parsing if expressions which + * require context are present. This implementation of ExtensionsCallback should be used if you wish + * to explicitly ban the use of query language "extensions" such as $text and $where. + */ +class ExtensionsCallbackDisallowExtensions : public ExtensionsCallback { +public: + /** + * Always returns an error status. + */ + StatusWithMatchExpression parseText(BSONElement text) const final; + + /** + * Always returns an error status. + */ + StatusWithMatchExpression parseWhere(BSONElement where) const final; +}; + +} // namespace mongo diff --git a/src/mongo/db/matcher/matcher.h b/src/mongo/db/matcher/matcher.h index e49602804a2..7de034a654c 100644 --- a/src/mongo/db/matcher/matcher.h +++ b/src/mongo/db/matcher/matcher.h @@ -48,8 +48,7 @@ class Matcher { MONGO_DISALLOW_COPYING(Matcher); public: - explicit Matcher(const BSONObj& pattern, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + explicit Matcher(const BSONObj& pattern, const ExtensionsCallback& extensionsCallback); bool matches(const BSONObj& doc, MatchDetails* details = NULL) const; -- cgit v1.2.1