diff options
55 files changed, 931 insertions, 526 deletions
diff --git a/src/mongo/db/auth/authz_manager_external_state_mock.cpp b/src/mongo/db/auth/authz_manager_external_state_mock.cpp index 94617a82fbe..5bb10a57f3c 100644 --- a/src/mongo/db/auth/authz_manager_external_state_mock.cpp +++ b/src/mongo/db/auth/authz_manager_external_state_mock.cpp @@ -38,6 +38,7 @@ #include "mongo/db/auth/authz_session_external_state_mock.h" #include "mongo/db/jsobj.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/namespace_string.h" #include "mongo/db/operation_context_noop.h" #include "mongo/db/ops/update_driver.h" @@ -274,7 +275,7 @@ Status AuthzManagerExternalStateMock::_queryVector( const BSONObj& query, std::vector<BSONObjCollection::iterator>* result) { StatusWithMatchExpression parseResult = - MatchExpressionParser::parse(query, ExtensionsCallback()); + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); if (!parseResult.isOK()) { return parseResult.getStatus(); } diff --git a/src/mongo/db/catalog/apply_ops.cpp b/src/mongo/db/catalog/apply_ops.cpp index 6d00127b9af..df7f90cb7b6 100644 --- a/src/mongo/db/catalog/apply_ops.cpp +++ b/src/mongo/db/catalog/apply_ops.cpp @@ -38,6 +38,7 @@ #include "mongo/db/curop.h" #include "mongo/db/db_raii.h" #include "mongo/db/dbdirectclient.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/matcher/matcher.h" #include "mongo/db/op_observer.h" #include "mongo/db/operation_context_impl.h" @@ -76,9 +77,9 @@ Status applyOps(OperationContext* txn, DBDirectClient db(txn); BSONObj realres = db.findOne(f["ns"].String(), f["q"].Obj()); - // Apply-ops would never have a $where matcher, so use the default callback, - // which will throw an error if $where is found. - Matcher m(f["res"].Obj()); + // Apply-ops would never have a $where/$text matcher. Using the "DisallowExtensions" + // callback ensures that parsing will throw an error if $where or $text are found. + Matcher m(f["res"].Obj(), ExtensionsCallbackDisallowExtensions()); if (!m.matches(realres)) { result->append("got", realres); result->append("whatFailed", f); diff --git a/src/mongo/db/catalog/collection.cpp b/src/mongo/db/catalog/collection.cpp index daa74399995..15ea17f585b 100644 --- a/src/mongo/db/catalog/collection.cpp +++ b/src/mongo/db/catalog/collection.cpp @@ -48,6 +48,7 @@ #include "mongo/db/index/index_access_method.h" #include "mongo/db/keypattern.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/op_observer.h" #include "mongo/db/operation_context.h" #include "mongo/db/ops/update_driver.h" @@ -303,7 +304,8 @@ StatusWithMatchExpression Collection::parseValidator(const BSONObj& validator) c return status; } - auto statusWithMatcher = MatchExpressionParser::parse(validator); + auto statusWithMatcher = + MatchExpressionParser::parse(validator, ExtensionsCallbackDisallowExtensions()); if (!statusWithMatcher.isOK()) return statusWithMatcher.getStatus(); diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp index 8662eb0f906..32139f520a8 100644 --- a/src/mongo/db/catalog/index_catalog.cpp +++ b/src/mongo/db/catalog/index_catalog.cpp @@ -55,6 +55,7 @@ #include "mongo/db/jsobj.h" #include "mongo/db/keypattern.h" #include "mongo/db/matcher/expression.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/ops/delete.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/repl/replication_coordinator_global.h" @@ -540,8 +541,8 @@ Status IndexCatalog::_isSpecOk(const BSONObj& spec) const { return Status(ErrorCodes::CannotCreateIndex, "\"partialFilterExpression\" for an index must be a document"); } - StatusWithMatchExpression statusWithMatcher = - MatchExpressionParser::parse(filterElement.Obj()); + StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse( + filterElement.Obj(), ExtensionsCallbackDisallowExtensions()); if (!statusWithMatcher.isOK()) { return statusWithMatcher.getStatus(); } diff --git a/src/mongo/db/catalog/index_catalog_entry.cpp b/src/mongo/db/catalog/index_catalog_entry.cpp index 00d680c43c9..ca304cf0597 100644 --- a/src/mongo/db/catalog/index_catalog_entry.cpp +++ b/src/mongo/db/catalog/index_catalog_entry.cpp @@ -41,6 +41,7 @@ #include "mongo/db/index/index_descriptor.h" #include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" #include "mongo/util/log.h" @@ -103,7 +104,8 @@ void IndexCatalogEntry::init(OperationContext* txn, IndexAccessMethod* accessMet if (filterElement.type()) { invariant(filterElement.isABSONObj()); BSONObj filter = filterElement.Obj(); - StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(filter); + StatusWithMatchExpression statusWithMatcher = + MatchExpressionParser::parse(filter, ExtensionsCallbackDisallowExtensions()); // this should be checked in create, so can blow up here invariantOK(statusWithMatcher.getStatus()); _filterExpression = std::move(statusWithMatcher.getValue()); diff --git a/src/mongo/db/clientlistplugin.cpp b/src/mongo/db/clientlistplugin.cpp index 1c9171e1f0e..f206020b012 100644 --- a/src/mongo/db/clientlistplugin.cpp +++ b/src/mongo/db/clientlistplugin.cpp @@ -36,6 +36,7 @@ #include "mongo/db/curop.h" #include "mongo/db/dbwebserver.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" #include "mongo/db/stats/fill_locker_info.h" @@ -166,8 +167,8 @@ public: BSONObjBuilder& result) { unique_ptr<MatchExpression> filter; if (cmdObj["filter"].isABSONObj()) { - StatusWithMatchExpression statusWithMatcher = - MatchExpressionParser::parse(cmdObj["filter"].Obj()); + StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse( + cmdObj["filter"].Obj(), ExtensionsCallbackDisallowExtensions()); if (!statusWithMatcher.isOK()) { return appendCommandStatus(result, statusWithMatcher.getStatus()); } diff --git a/src/mongo/db/commands/index_filter_commands_test.cpp b/src/mongo/db/commands/index_filter_commands_test.cpp index 5a0d7b6ce07..463f1bb117e 100644 --- a/src/mongo/db/commands/index_filter_commands_test.cpp +++ b/src/mongo/db/commands/index_filter_commands_test.cpp @@ -34,6 +34,7 @@ #include "mongo/db/json.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_noop.h" #include "mongo/db/query/plan_ranker.h" #include "mongo/db/query/query_solution.h" @@ -120,7 +121,8 @@ void addQueryShapeToPlanCache(PlanCache* planCache, BSONObj projectionObj = fromjson(projectionStr); // Create canonical query. - auto statusWithCQ = CanonicalQuery::canonicalize(nss, queryObj, sortObj, projectionObj); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, queryObj, sortObj, projectionObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); @@ -144,7 +146,8 @@ bool planCacheContains(const PlanCache& planCache, BSONObj projectionObj = fromjson(projectionStr); // Create canonical query. - auto statusWithInputQuery = CanonicalQuery::canonicalize(nss, queryObj, sortObj, projectionObj); + auto statusWithInputQuery = CanonicalQuery::canonicalize( + nss, queryObj, sortObj, projectionObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithInputQuery.getStatus()); unique_ptr<CanonicalQuery> inputQuery = std::move(statusWithInputQuery.getValue()); @@ -160,7 +163,11 @@ bool planCacheContains(const PlanCache& planCache, // Alternatively, we could add key to PlanCacheEntry but that would be used in one place // only. auto statusWithCurrentQuery = - CanonicalQuery::canonicalize(nss, entry->query, entry->sort, entry->projection); + CanonicalQuery::canonicalize(nss, + entry->query, + entry->sort, + entry->projection, + ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCurrentQuery.getStatus()); unique_ptr<CanonicalQuery> currentQuery = std::move(statusWithCurrentQuery.getValue()); diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp index 76ccfa77ea5..f467c14b3df 100644 --- a/src/mongo/db/commands/list_collections.cpp +++ b/src/mongo/db/commands/list_collections.cpp @@ -44,6 +44,7 @@ #include "mongo/db/db_raii.h" #include "mongo/db/exec/queued_data_stage.h" #include "mongo/db/exec/working_set.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/query/cursor_response.h" #include "mongo/db/query/find_common.h" #include "mongo/db/service_context.h" @@ -192,8 +193,8 @@ public: return appendCommandStatus( result, Status(ErrorCodes::BadValue, "\"filter\" must be an object")); } - StatusWithMatchExpression statusWithMatcher = - MatchExpressionParser::parse(filterElt.Obj()); + StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse( + filterElt.Obj(), ExtensionsCallbackDisallowExtensions()); if (!statusWithMatcher.isOK()) { return appendCommandStatus(result, statusWithMatcher.getStatus()); } diff --git a/src/mongo/db/commands/plan_cache_commands_test.cpp b/src/mongo/db/commands/plan_cache_commands_test.cpp index 7ffe832473b..7234588fd37 100644 --- a/src/mongo/db/commands/plan_cache_commands_test.cpp +++ b/src/mongo/db/commands/plan_cache_commands_test.cpp @@ -35,6 +35,7 @@ #include <algorithm> #include "mongo/db/json.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_noop.h" #include "mongo/db/query/plan_ranker.h" #include "mongo/db/query/query_solution.h" @@ -125,7 +126,8 @@ TEST(PlanCacheCommandsTest, planCacheListQueryShapesEmpty) { TEST(PlanCacheCommandsTest, planCacheListQueryShapesOneKey) { // Create a canonical query - auto statusWithCQ = CanonicalQuery::canonicalize(nss, fromjson("{a: 1}")); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, fromjson("{a: 1}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); @@ -150,7 +152,8 @@ TEST(PlanCacheCommandsTest, planCacheListQueryShapesOneKey) { TEST(PlanCacheCommandsTest, planCacheClearAllShapes) { // Create a canonical query - auto statusWithCQ = CanonicalQuery::canonicalize(nss, fromjson("{a: 1}")); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, fromjson("{a: 1}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); @@ -266,10 +269,12 @@ TEST(PlanCacheCommandsTest, planCacheClearUnknownKey) { TEST(PlanCacheCommandsTest, planCacheClearOneKey) { // Create 2 canonical queries. - auto statusWithCQA = CanonicalQuery::canonicalize(nss, fromjson("{a: 1}")); + auto statusWithCQA = CanonicalQuery::canonicalize( + nss, fromjson("{a: 1}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQA.getStatus()); unique_ptr<CanonicalQuery> cqA = std::move(statusWithCQA.getValue()); - auto statusWithCQB = CanonicalQuery::canonicalize(nss, fromjson("{b: 1}")); + auto statusWithCQB = CanonicalQuery::canonicalize( + nss, fromjson("{b: 1}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQB.getStatus()); unique_ptr<CanonicalQuery> cqB = std::move(statusWithCQB.getValue()); @@ -388,7 +393,8 @@ TEST(PlanCacheCommandsTest, planCacheListPlansUnknownKey) { TEST(PlanCacheCommandsTest, planCacheListPlansOnlyOneSolutionTrue) { // Create a canonical query - auto statusWithCQ = CanonicalQuery::canonicalize(nss, fromjson("{a: 1}")); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, fromjson("{a: 1}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); @@ -407,7 +413,8 @@ TEST(PlanCacheCommandsTest, planCacheListPlansOnlyOneSolutionTrue) { TEST(PlanCacheCommandsTest, planCacheListPlansOnlyOneSolutionFalse) { // Create a canonical query - auto statusWithCQ = CanonicalQuery::canonicalize(nss, fromjson("{a: 1}")); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, fromjson("{a: 1}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index f73b0a186dd..94c16d61e77 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -71,6 +71,7 @@ #include "mongo/db/json.h" #include "mongo/db/keypattern.h" #include "mongo/db/lasterror.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/namespace_string.h" #include "mongo/db/op_observer.h" #include "mongo/db/ops/insert.h" @@ -603,7 +604,11 @@ public: MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN { auto statusWithCQ = - CanonicalQuery::canonicalize(NamespaceString(ns), query, sort, BSONObj()); + CanonicalQuery::canonicalize(NamespaceString(ns), + query, + sort, + BSONObj(), + ExtensionsCallbackDisallowExtensions()); if (!statusWithCQ.isOK()) { uasserted(17240, "Can't canonicalize query " + query.toString()); return 0; diff --git a/src/mongo/db/exec/projection_exec.h b/src/mongo/db/exec/projection_exec.h index 6558b75fbf3..ad16d5b0678 100644 --- a/src/mongo/db/exec/projection_exec.h +++ b/src/mongo/db/exec/projection_exec.h @@ -66,7 +66,7 @@ public: ProjectionExec(const BSONObj& spec, const MatchExpression* queryExpression, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + const ExtensionsCallback& extensionsCallback); ~ProjectionExec(); /** diff --git a/src/mongo/db/exec/projection_exec_test.cpp b/src/mongo/db/exec/projection_exec_test.cpp index f8118b4f141..a92eb405b58 100644 --- a/src/mongo/db/exec/projection_exec_test.cpp +++ b/src/mongo/db/exec/projection_exec_test.cpp @@ -36,6 +36,7 @@ #include "mongo/db/json.h" #include "mongo/db/exec/working_set_computed_data.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/unittest/unittest.h" using namespace mongo; @@ -48,7 +49,8 @@ using std::unique_ptr; * Utility function to create MatchExpression */ unique_ptr<MatchExpression> parseMatchExpression(const BSONObj& obj) { - StatusWithMatchExpression status = MatchExpressionParser::parse(obj); + StatusWithMatchExpression status = + MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(status.isOK()); return std::move(status.getValue()); } @@ -80,7 +82,7 @@ void testTransform(const char* specStr, BSONObj spec = fromjson(specStr); BSONObj query = fromjson(queryStr); unique_ptr<MatchExpression> queryExpression = parseMatchExpression(query); - ProjectionExec exec(spec, queryExpression.get()); + ProjectionExec exec(spec, queryExpression.get(), ExtensionsCallbackDisallowExtensions()); // Create working set member. WorkingSetMember wsm; @@ -163,7 +165,7 @@ BSONObj transformMetaSortKeyCovered(const BSONObj& sortKey, wsm->addComputed(new SortKeyComputedData(sortKey)); ws.transitionToLocAndIdx(wsid); - ProjectionExec projExec(fromjson(projSpec), nullptr); + ProjectionExec projExec(fromjson(projSpec), nullptr, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(projExec.transform(wsm)); return wsm->obj.value(); 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<MatchExpression> 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<TypeMatchExpression*>(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<TypeMatchExpression*>(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<TypeMatchExpression*>(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<TypeMatchExpression*>(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<TypeMatchExpression*>(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<TypeMatchExpression*>(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<TypeMatchExpression*>(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<TypeMatchExpression*>(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<TypeMatchExpression*>(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<TypeMatchExpression*>(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<TypeMatchExpression*>(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<long long>::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<long long>::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<long long>::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<long long>::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<long long>::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<long long>::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<long long>::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<long long>::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<int>::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits<int>::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<int>::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits<int>::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<int>::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits<int>::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<int>::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits<int>::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<long long>::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<double>::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<double>::max())), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( - MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllClear" << std::numeric_limits<double>::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<double>::max())), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( - MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnySet" << std::numeric_limits<double>::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<double>::max())), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( - MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnyClear" << std::numeric_limits<double>::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<double>::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<long long>::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits<long long>::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits<long long>::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<long long>::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<long long>::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits<long long>::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits<long long>::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<long long>::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<long long>::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits<long long>::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits<long long>::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<long long>::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<long long>::max())))) - .getStatus()); + BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits<long long>::max()))), + ExtensionsCallbackDisallowExtensions()).getStatus()); ASSERT_NOT_OK( MatchExpressionParser::parse( - BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits<long long>::min())))) - .getStatus()); + BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits<long long>::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<TextMatchExpressionBase::TextParams> 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 <http://www.gnu.org/licenses/>. + * + * 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 <http://www.gnu.org/licenses/>. + * + * 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; diff --git a/src/mongo/db/ops/modifier_pull.cpp b/src/mongo/db/ops/modifier_pull.cpp index ac7e5c41e8c..2986af6d86f 100644 --- a/src/mongo/db/ops/modifier_pull.cpp +++ b/src/mongo/db/ops/modifier_pull.cpp @@ -31,6 +31,7 @@ #include "mongo/base/error_codes.h" #include "mongo/bson/mutable/algorithm.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/ops/field_checker.h" #include "mongo/db/ops/log_builder.h" #include "mongo/db/ops/path_support.h" @@ -118,7 +119,7 @@ Status ModifierPull::init(const BSONElement& modExpr, const Options& opts, bool* // Build the matcher around the object we built above. Currently, we do not allow $pull // operations to contain $text/$where clauses, so preserving this behaviour. StatusWithMatchExpression parseResult = - MatchExpressionParser::parse(_exprObj, ExtensionsCallback()); + MatchExpressionParser::parse(_exprObj, ExtensionsCallbackDisallowExtensions()); if (!parseResult.isOK()) { return parseResult.getStatus(); } diff --git a/src/mongo/db/query/canonical_query.h b/src/mongo/db/query/canonical_query.h index 451b81e543e..136c6c1d8f8 100644 --- a/src/mongo/db/query/canonical_query.h +++ b/src/mongo/db/query/canonical_query.h @@ -47,8 +47,7 @@ public: * Used for legacy find through the OP_QUERY message. */ static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize( - const QueryMessage& qm, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + const QueryMessage& qm, const ExtensionsCallback& extensionsCallback); /** * Takes ownership of 'lpq'. @@ -58,8 +57,8 @@ public: * * Used for finds using the find command path. */ - static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize( - LiteParsedQuery* lpq, const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize(LiteParsedQuery* lpq, + const ExtensionsCallback&); /** * For testing or for internal clients to use. @@ -75,32 +74,30 @@ public: static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize( const CanonicalQuery& baseQuery, MatchExpression* root, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + const ExtensionsCallback& extensionsCallback); static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize( - NamespaceString nss, - const BSONObj& query, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + NamespaceString nss, const BSONObj& query, const ExtensionsCallback& extensionsCallback); static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize( NamespaceString nss, const BSONObj& query, bool explain, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + const ExtensionsCallback& extensionsCallback); static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize( NamespaceString nss, const BSONObj& query, long long skip, long long limit, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + const ExtensionsCallback& extensionsCallback); static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize( NamespaceString nss, const BSONObj& query, const BSONObj& sort, const BSONObj& proj, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + const ExtensionsCallback& extensionsCallback); static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize( NamespaceString nss, @@ -109,7 +106,7 @@ public: const BSONObj& proj, long long skip, long long limit, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + const ExtensionsCallback& extensionsCallback); static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize( NamespaceString nss, @@ -119,7 +116,7 @@ public: long long skip, long long limit, const BSONObj& hint, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + const ExtensionsCallback& extensionsCallback); static StatusWith<std::unique_ptr<CanonicalQuery>> canonicalize( NamespaceString nss, @@ -133,7 +130,7 @@ public: const BSONObj& maxObj, bool snapshot, bool explain, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + const ExtensionsCallback& extensionsCallback); /** * Returns true if "query" describes an exact-match query on _id, possibly with diff --git a/src/mongo/db/query/canonical_query_test.cpp b/src/mongo/db/query/canonical_query_test.cpp index ec650b1f1cc..0e9a0a60d04 100644 --- a/src/mongo/db/query/canonical_query_test.cpp +++ b/src/mongo/db/query/canonical_query_test.cpp @@ -29,6 +29,7 @@ #include "mongo/db/query/canonical_query.h" #include "mongo/db/json.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/matcher/extensions_callback_noop.h" #include "mongo/db/namespace_string.h" #include "mongo/unittest/unittest.h" @@ -406,7 +407,8 @@ TEST(CanonicalQueryTest, IsValidSortKeyMetaProjection) { const bool isExplain = false; auto lpq = assertGet(LiteParsedQuery::makeFromFindCommand( nss, fromjson("{find: 'testcoll', projection: {foo: {$meta: 'sortKey'}}}"), isExplain)); - auto cq = CanonicalQuery::canonicalize(lpq.release()); + auto cq = + CanonicalQuery::canonicalize(lpq.release(), ExtensionsCallbackDisallowExtensions()); ASSERT_NOT_OK(cq.getStatus()); } @@ -417,7 +419,8 @@ TEST(CanonicalQueryTest, IsValidSortKeyMetaProjection) { nss, fromjson("{find: 'testcoll', projection: {foo: {$meta: 'sortKey'}}, sort: {bar: 1}}"), isExplain)); - auto cq = CanonicalQuery::canonicalize(lpq.release()); + auto cq = + CanonicalQuery::canonicalize(lpq.release(), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(cq.getStatus()); } } @@ -483,7 +486,8 @@ TEST(CanonicalQueryTest, SortTreeNumChildrenComparison) { */ unique_ptr<CanonicalQuery> canonicalize(const char* queryStr) { BSONObj queryObj = fromjson(queryStr); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, queryObj); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, queryObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); return std::move(statusWithCQ.getValue()); } @@ -494,7 +498,8 @@ std::unique_ptr<CanonicalQuery> canonicalize(const char* queryStr, BSONObj queryObj = fromjson(queryStr); BSONObj sortObj = fromjson(sortStr); BSONObj projObj = fromjson(projStr); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, queryObj, sortObj, projObj); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, queryObj, sortObj, projObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); return std::move(statusWithCQ.getValue()); } @@ -537,10 +542,12 @@ TEST(CanonicalQueryTest, CanonicalizeFromBaseQuery) { const std::string cmdStr = "{find:'bogusns', filter:{$or:[{a:1,b:1},{a:1,c:1}]}, projection:{a:1}, sort:{b:1}}"; auto lpq = assertGet(LiteParsedQuery::makeFromFindCommand(nss, fromjson(cmdStr), isExplain)); - auto baseCq = assertGet(CanonicalQuery::canonicalize(lpq.release())); + auto baseCq = assertGet( + CanonicalQuery::canonicalize(lpq.release(), ExtensionsCallbackDisallowExtensions())); MatchExpression* firstClauseExpr = baseCq->root()->getChild(0); - auto childCq = assertGet(CanonicalQuery::canonicalize(*baseCq, firstClauseExpr)); + auto childCq = assertGet(CanonicalQuery::canonicalize( + *baseCq, firstClauseExpr, ExtensionsCallbackDisallowExtensions())); // Descriptive test. The childCq's filter should be the relevant $or clause, rather than the // entire query predicate. diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp index 592976395ee..dd973bee36f 100644 --- a/src/mongo/db/query/get_executor.cpp +++ b/src/mongo/db/query/get_executor.cpp @@ -53,6 +53,7 @@ #include "mongo/db/exec/update.h" #include "mongo/db/index_names.h" #include "mongo/db/index/index_descriptor.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/matcher/extensions_callback_noop.h" #include "mongo/db/matcher/extensions_callback_real.h" #include "mongo/db/ops/update_lifecycle.h" @@ -596,7 +597,8 @@ StatusWith<unique_ptr<PlanStage>> applyProjection(OperationContext* txn, invariant(!proj.isEmpty()); ParsedProjection* rawParsedProj; - Status ppStatus = ParsedProjection::make(proj.getOwned(), cq->root(), &rawParsedProj); + Status ppStatus = ParsedProjection::make( + proj.getOwned(), cq->root(), &rawParsedProj, ExtensionsCallbackDisallowExtensions()); if (!ppStatus.isOK()) { return ppStatus; } diff --git a/src/mongo/db/query/get_executor_test.cpp b/src/mongo/db/query/get_executor_test.cpp index 5a052c6c301..29c73f6c8b2 100644 --- a/src/mongo/db/query/get_executor_test.cpp +++ b/src/mongo/db/query/get_executor_test.cpp @@ -33,6 +33,7 @@ #include "mongo/db/query/get_executor.h" #include "mongo/db/json.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/query/query_settings.h" #include "mongo/unittest/unittest.h" #include "mongo/util/mongoutils/str.h" @@ -54,7 +55,8 @@ unique_ptr<CanonicalQuery> canonicalize(const char* queryStr, BSONObj queryObj = fromjson(queryStr); BSONObj sortObj = fromjson(sortStr); BSONObj projObj = fromjson(projStr); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, queryObj, sortObj, projObj); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, queryObj, sortObj, projObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); return std::move(statusWithCQ.getValue()); } diff --git a/src/mongo/db/query/index_bounds_builder_test.cpp b/src/mongo/db/query/index_bounds_builder_test.cpp index 3085d5c00b4..43a318523de 100644 --- a/src/mongo/db/query/index_bounds_builder_test.cpp +++ b/src/mongo/db/query/index_bounds_builder_test.cpp @@ -36,6 +36,7 @@ #include <memory> #include "mongo/db/json.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/unittest/unittest.h" using namespace mongo; @@ -57,7 +58,8 @@ double NaN = numeric_limits<double>::quiet_NaN(); * Utility function to create MatchExpression */ MatchExpression* parseMatchExpression(const BSONObj& obj) { - StatusWithMatchExpression status = MatchExpressionParser::parse(obj); + StatusWithMatchExpression status = + MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(status.isOK()); MatchExpression* expr(status.getValue().release()); return expr; diff --git a/src/mongo/db/query/parsed_projection.h b/src/mongo/db/query/parsed_projection.h index 06571199d89..3e7d97e1175 100644 --- a/src/mongo/db/query/parsed_projection.h +++ b/src/mongo/db/query/parsed_projection.h @@ -48,7 +48,7 @@ public: static Status make(const BSONObj& spec, const MatchExpression* const query, ParsedProjection** out, - const ExtensionsCallback& extensionsCallback = ExtensionsCallback()); + const ExtensionsCallback& extensionsCallback); /** * Returns true if the projection requires match details from the query, diff --git a/src/mongo/db/query/parsed_projection_test.cpp b/src/mongo/db/query/parsed_projection_test.cpp index f235f32a15e..6f4066c406b 100644 --- a/src/mongo/db/query/parsed_projection_test.cpp +++ b/src/mongo/db/query/parsed_projection_test.cpp @@ -31,6 +31,7 @@ #include <memory> #include "mongo/db/json.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/unittest/unittest.h" namespace { @@ -46,11 +47,13 @@ using namespace mongo; // unique_ptr<ParsedProjection> createParsedProjection(const BSONObj& query, const BSONObj& projObj) { - StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(query); + StatusWithMatchExpression statusWithMatcher = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT(statusWithMatcher.isOK()); std::unique_ptr<MatchExpression> queryMatchExpr = std::move(statusWithMatcher.getValue()); ParsedProjection* out = NULL; - Status status = ParsedProjection::make(projObj, queryMatchExpr.get(), &out); + Status status = ParsedProjection::make( + projObj, queryMatchExpr.get(), &out, ExtensionsCallbackDisallowExtensions()); if (!status.isOK()) { FAIL(mongoutils::str::stream() << "failed to parse projection " << projObj << " (query: " << query << "): " << status.toString()); @@ -72,11 +75,13 @@ unique_ptr<ParsedProjection> createParsedProjection(const char* queryStr, const void assertInvalidProjection(const char* queryStr, const char* projStr) { BSONObj query = fromjson(queryStr); BSONObj projObj = fromjson(projStr); - StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(query); + StatusWithMatchExpression statusWithMatcher = + MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()); ASSERT(statusWithMatcher.isOK()); std::unique_ptr<MatchExpression> queryMatchExpr = std::move(statusWithMatcher.getValue()); ParsedProjection* out = NULL; - Status status = ParsedProjection::make(projObj, queryMatchExpr.get(), &out); + Status status = ParsedProjection::make( + projObj, queryMatchExpr.get(), &out, ExtensionsCallbackDisallowExtensions()); std::unique_ptr<ParsedProjection> destroy(out); ASSERT(!status.isOK()); } @@ -181,13 +186,15 @@ TEST(ParsedProjectionTest, InvalidPositionalProjectionDefaultPathMatchExpression ParsedProjection* out = NULL; BSONObj projObj = fromjson("{'a.$': 1}"); - Status status = ParsedProjection::make(projObj, queryMatchExpr.get(), &out); + Status status = ParsedProjection::make( + projObj, queryMatchExpr.get(), &out, ExtensionsCallbackDisallowExtensions()); ASSERT(!status.isOK()); std::unique_ptr<ParsedProjection> destroy(out); // Projecting onto empty field should fail. BSONObj emptyFieldProjObj = fromjson("{'.$': 1}"); - status = ParsedProjection::make(emptyFieldProjObj, queryMatchExpr.get(), &out); + status = ParsedProjection::make( + emptyFieldProjObj, queryMatchExpr.get(), &out, ExtensionsCallbackDisallowExtensions()); ASSERT(!status.isOK()); } diff --git a/src/mongo/db/query/plan_cache_indexability_test.cpp b/src/mongo/db/query/plan_cache_indexability_test.cpp index c1bdd0964e9..bef185e8503 100644 --- a/src/mongo/db/query/plan_cache_indexability_test.cpp +++ b/src/mongo/db/query/plan_cache_indexability_test.cpp @@ -27,6 +27,7 @@ */ #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/query/index_entry.h" #include "mongo/db/query/plan_cache_indexability.h" #include "mongo/unittest/unittest.h" @@ -35,7 +36,8 @@ namespace mongo { namespace { std::unique_ptr<MatchExpression> parseMatchExpression(const BSONObj& obj) { - StatusWithMatchExpression status = MatchExpressionParser::parse(obj); + StatusWithMatchExpression status = + MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions()); if (!status.isOK()) { FAIL(str::stream() << "failed to parse query: " << obj.toString() << ". Reason: " << status.getStatus().toString()); diff --git a/src/mongo/db/query/plan_cache_test.cpp b/src/mongo/db/query/plan_cache_test.cpp index 510cfd5064b..663f7b7c3af 100644 --- a/src/mongo/db/query/plan_cache_test.cpp +++ b/src/mongo/db/query/plan_cache_test.cpp @@ -38,6 +38,7 @@ #include "mongo/db/jsobj.h" #include "mongo/db/json.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/query/plan_ranker.h" #include "mongo/db/query/query_knobs.h" #include "mongo/db/query/query_planner.h" @@ -60,7 +61,8 @@ static const NamespaceString nss("test.collection"); * Utility functions to create a CanonicalQuery */ unique_ptr<CanonicalQuery> canonicalize(const BSONObj& queryObj) { - auto statusWithCQ = CanonicalQuery::canonicalize(nss, queryObj); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, queryObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); return std::move(statusWithCQ.getValue()); } @@ -76,7 +78,8 @@ unique_ptr<CanonicalQuery> canonicalize(const char* queryStr, BSONObj queryObj = fromjson(queryStr); BSONObj sortObj = fromjson(sortStr); BSONObj projObj = fromjson(projStr); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, queryObj, sortObj, projObj); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, queryObj, sortObj, projObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); return std::move(statusWithCQ.getValue()); } @@ -104,8 +107,9 @@ unique_ptr<CanonicalQuery> canonicalize(const char* queryStr, hintObj, minObj, maxObj, - false, // snapshot - false); // explain + false, // snapshot + false, // explain + ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); return std::move(statusWithCQ.getValue()); } @@ -126,8 +130,18 @@ unique_ptr<CanonicalQuery> canonicalize(const char* queryStr, BSONObj hintObj = fromjson(hintStr); BSONObj minObj = fromjson(minStr); BSONObj maxObj = fromjson(maxStr); - auto statusWithCQ = CanonicalQuery::canonicalize( - nss, queryObj, sortObj, projObj, skip, limit, hintObj, minObj, maxObj, snapshot, explain); + auto statusWithCQ = CanonicalQuery::canonicalize(nss, + queryObj, + sortObj, + projObj, + skip, + limit, + hintObj, + minObj, + maxObj, + snapshot, + explain, + ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); return std::move(statusWithCQ.getValue()); } @@ -136,7 +150,8 @@ unique_ptr<CanonicalQuery> canonicalize(const char* queryStr, * Utility function to create MatchExpression */ unique_ptr<MatchExpression> parseMatchExpression(const BSONObj& obj) { - StatusWithMatchExpression status = MatchExpressionParser::parse(obj); + StatusWithMatchExpression status = + MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions()); if (!status.isOK()) { str::stream ss; ss << "failed to parse query: " << obj.toString() @@ -506,7 +521,6 @@ protected: solns.clear(); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, query, sort, @@ -517,7 +531,8 @@ protected: minObj, maxObj, snapshot, - false); // explain + false, // explain + ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); Status s = QueryPlanner::plan(*statusWithCQ.getValue(), params, &solns); ASSERT_OK(s); @@ -588,7 +603,8 @@ protected: const BSONObj& sort, const BSONObj& proj, const QuerySolution& soln) const { - auto statusWithCQ = CanonicalQuery::canonicalize(nss, query, sort, proj); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, query, sort, proj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> scopedCq = std::move(statusWithCQ.getValue()); diff --git a/src/mongo/db/query/planner_ixselect_test.cpp b/src/mongo/db/query/planner_ixselect_test.cpp index 3271f2b9b2a..88fb6e44664 100644 --- a/src/mongo/db/query/planner_ixselect_test.cpp +++ b/src/mongo/db/query/planner_ixselect_test.cpp @@ -35,6 +35,7 @@ #include <memory> #include "mongo/db/json.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/query/index_tag.h" #include "mongo/unittest/unittest.h" #include "mongo/util/text.h" @@ -51,7 +52,8 @@ using std::vector; * Utility function to create MatchExpression */ unique_ptr<MatchExpression> parseMatchExpression(const BSONObj& obj) { - StatusWithMatchExpression status = MatchExpressionParser::parse(obj); + StatusWithMatchExpression status = + MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions()); ASSERT_TRUE(status.isOK()); return std::move(status.getValue()); } diff --git a/src/mongo/db/query/query_planner_test.cpp b/src/mongo/db/query/query_planner_test.cpp index 0504fc410b8..8b5e86a0b79 100644 --- a/src/mongo/db/query/query_planner_test.cpp +++ b/src/mongo/db/query/query_planner_test.cpp @@ -34,6 +34,7 @@ #include "mongo/db/jsobj.h" #include "mongo/db/json.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/query/query_planner.h" #include "mongo/db/query/query_planner_test_fixture.h" @@ -4057,8 +4058,8 @@ TEST(BadInputTest, CacheDataFromTaggedTree) { // No relevant index matching the index tag. relevantIndices.push_back(IndexEntry(BSON("a" << 1))); - auto statusWithCQ = - CanonicalQuery::canonicalize(NamespaceString("test.collection"), BSON("a" << 3)); + auto statusWithCQ = CanonicalQuery::canonicalize( + NamespaceString("test.collection"), BSON("a" << 3), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); std::unique_ptr<CanonicalQuery> scopedCq = std::move(statusWithCQ.getValue()); scopedCq->root()->setTag(new IndexTag(1)); @@ -4071,7 +4072,8 @@ TEST(BadInputTest, CacheDataFromTaggedTree) { TEST(BadInputTest, TagAccordingToCache) { const NamespaceString nss("test.collection"); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, BSON("a" << 3)); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, BSON("a" << 3), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); std::unique_ptr<CanonicalQuery> scopedCq = std::move(statusWithCQ.getValue()); @@ -4098,7 +4100,8 @@ TEST(BadInputTest, TagAccordingToCache) { ASSERT_OK(s); // Regenerate canonical query in order to clear tags. - statusWithCQ = CanonicalQuery::canonicalize(nss, BSON("a" << 3)); + statusWithCQ = + CanonicalQuery::canonicalize(nss, BSON("a" << 3), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); scopedCq = std::move(statusWithCQ.getValue()); diff --git a/src/mongo/db/query/query_planner_test_fixture.cpp b/src/mongo/db/query/query_planner_test_fixture.cpp index 4be1ee2f140..3dc9f58c70d 100644 --- a/src/mongo/db/query/query_planner_test_fixture.cpp +++ b/src/mongo/db/query/query_planner_test_fixture.cpp @@ -35,6 +35,7 @@ #include "mongo/db/namespace_string.h" #include "mongo/db/matcher/expression_parser.h" #include "mongo/db/matcher/extensions_callback_noop.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/query/query_knobs.h" #include "mongo/db/query/query_planner.h" #include "mongo/db/query/query_planner_test_lib.h" @@ -336,7 +337,8 @@ void QueryPlannerTest::assertHasOneSolutionOf(const std::vector<std::string>& so } std::unique_ptr<MatchExpression> QueryPlannerTest::parseMatchExpression(const BSONObj& obj) { - StatusWithMatchExpression status = MatchExpressionParser::parse(obj); + StatusWithMatchExpression status = + MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions()); if (!status.isOK()) { FAIL(str::stream() << "failed to parse query: " << obj.toString() << ". Reason: " << status.getStatus().toString()); diff --git a/src/mongo/db/query/query_planner_test_lib.cpp b/src/mongo/db/query/query_planner_test_lib.cpp index e4485738ea7..2ba02902729 100644 --- a/src/mongo/db/query/query_planner_test_lib.cpp +++ b/src/mongo/db/query/query_planner_test_lib.cpp @@ -36,6 +36,7 @@ #include "mongo/db/jsobj.h" #include "mongo/db/json.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/query/query_planner.h" #include "mongo/db/query/query_solution.h" #include "mongo/unittest/unittest.h" @@ -51,7 +52,8 @@ bool filterMatches(const BSONObj& testFilter, const QuerySolutionNode* trueFilte if (NULL == trueFilterNode->filter) { return false; } - StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(testFilter); + StatusWithMatchExpression statusWithMatcher = + MatchExpressionParser::parse(testFilter, ExtensionsCallbackDisallowExtensions()); if (!statusWithMatcher.isOK()) { return false; } diff --git a/src/mongo/db/ttl.cpp b/src/mongo/db/ttl.cpp index e54bc1838e2..9ee42d649a6 100644 --- a/src/mongo/db/ttl.cpp +++ b/src/mongo/db/ttl.cpp @@ -50,6 +50,7 @@ #include "mongo/db/index/index_descriptor.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/ops/insert.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/namespace_string.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/repl/replication_coordinator_global.h" @@ -287,7 +288,8 @@ private: const char* keyFieldName = key.firstElement().fieldName(); BSONObj query = BSON(keyFieldName << BSON("$gte" << kDawnOfTime << "$lte" << expirationTime)); - auto canonicalQuery = CanonicalQuery::canonicalize(nss, query); + auto canonicalQuery = + CanonicalQuery::canonicalize(nss, query, ExtensionsCallbackDisallowExtensions()); invariantOK(canonicalQuery.getStatus()); DeleteStageParams params; diff --git a/src/mongo/dbtests/documentsourcetests.cpp b/src/mongo/dbtests/documentsourcetests.cpp index 395ee11eb1e..f37d61ff7f2 100644 --- a/src/mongo/dbtests/documentsourcetests.cpp +++ b/src/mongo/dbtests/documentsourcetests.cpp @@ -32,6 +32,7 @@ #include "mongo/db/db_raii.h" #include "mongo/db/dbdirectclient.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/pipeline/dependencies.h" #include "mongo/db/pipeline/document_source.h" @@ -85,7 +86,8 @@ protected: _exec.reset(); OldClientWriteContext ctx(&_opCtx, nss.ns()); - auto cq = uassertStatusOK(CanonicalQuery::canonicalize(nss, /*query=*/BSONObj())); + auto cq = uassertStatusOK(CanonicalQuery::canonicalize( + nss, /*query=*/BSONObj(), ExtensionsCallbackDisallowExtensions())); _exec = uassertStatusOK( getExecutor(&_opCtx, ctx.getCollection(), std::move(cq), PlanExecutor::YIELD_MANUAL)); diff --git a/src/mongo/dbtests/executor_registry.cpp b/src/mongo/dbtests/executor_registry.cpp index b71d11c2d90..46735b627b5 100644 --- a/src/mongo/dbtests/executor_registry.cpp +++ b/src/mongo/dbtests/executor_registry.cpp @@ -41,6 +41,7 @@ #include "mongo/db/service_context.h" #include "mongo/db/json.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/query/plan_executor.h" #include "mongo/dbtests/dbtests.h" @@ -74,7 +75,8 @@ public: unique_ptr<CollectionScan> scan(new CollectionScan(&_opCtx, params, ws.get(), NULL)); // Create a plan executor to hold it - auto statusWithCQ = CanonicalQuery::canonicalize(nss, BSONObj()); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, BSONObj(), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); diff --git a/src/mongo/dbtests/matchertests.cpp b/src/mongo/dbtests/matchertests.cpp index f700a6f1ba4..fc2ca4049c6 100644 --- a/src/mongo/dbtests/matchertests.cpp +++ b/src/mongo/dbtests/matchertests.cpp @@ -33,6 +33,7 @@ #include "mongo/db/db_raii.h" #include "mongo/db/json.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/matcher/extensions_callback_real.h" #include "mongo/db/matcher/matcher.h" #include "mongo/db/operation_context_impl.h" @@ -57,7 +58,7 @@ class Basic { public: void run() { BSONObj query = fromjson("{\"a\":\"b\"}"); - M m(query, ExtensionsCallback()); + M m(query, ExtensionsCallbackDisallowExtensions()); ASSERT(m.matches(fromjson("{\"a\":\"b\"}"))); } }; @@ -67,7 +68,7 @@ class DoubleEqual { public: void run() { BSONObj query = fromjson("{\"a\":5}"); - M m(query, ExtensionsCallback()); + M m(query, ExtensionsCallbackDisallowExtensions()); ASSERT(m.matches(fromjson("{\"a\":5}"))); } }; @@ -78,7 +79,7 @@ public: void run() { BSONObjBuilder query; query.append("a", 5); - M m(query.done(), ExtensionsCallback()); + M m(query.done(), ExtensionsCallbackDisallowExtensions()); ASSERT(m.matches(fromjson("{\"a\":5}"))); } }; @@ -88,7 +89,7 @@ class MixedNumericGt { public: void run() { BSONObj query = fromjson("{\"a\":{\"$gt\":4}}"); - M m(query, ExtensionsCallback()); + M m(query, ExtensionsCallbackDisallowExtensions()); BSONObjBuilder b; b.append("a", 5); ASSERT(m.matches(b.done())); @@ -103,7 +104,7 @@ public: ASSERT_EQUALS(4, query["a"].embeddedObject()["$in"].embeddedObject()["0"].number()); ASSERT_EQUALS(NumberInt, query["a"].embeddedObject()["$in"].embeddedObject()["0"].type()); - M m(query, ExtensionsCallback()); + M m(query, ExtensionsCallbackDisallowExtensions()); { BSONObjBuilder b; @@ -130,7 +131,7 @@ template <typename M> class MixedNumericEmbedded { public: void run() { - M m(BSON("a" << BSON("x" << 1)), ExtensionsCallback()); + M m(BSON("a" << BSON("x" << 1)), ExtensionsCallbackDisallowExtensions()); ASSERT(m.matches(BSON("a" << BSON("x" << 1)))); ASSERT(m.matches(BSON("a" << BSON("x" << 1.0)))); } @@ -140,7 +141,7 @@ template <typename M> class Size { public: void run() { - M m(fromjson("{a:{$size:4}}"), ExtensionsCallback()); + M m(fromjson("{a:{$size:4}}"), ExtensionsCallbackDisallowExtensions()); ASSERT(m.matches(fromjson("{a:[1,2,3,4]}"))); ASSERT(!m.matches(fromjson("{a:[1,2,3]}"))); ASSERT(!m.matches(fromjson("{a:[1,2,3,'a','b']}"))); @@ -152,7 +153,8 @@ template <typename M> class WithinBox { public: void run() { - M m(fromjson("{loc:{$within:{$box:[{x: 4, y:4},[6,6]]}}}"), ExtensionsCallback()); + M m(fromjson("{loc:{$within:{$box:[{x: 4, y:4},[6,6]]}}}"), + ExtensionsCallbackDisallowExtensions()); ASSERT(!m.matches(fromjson("{loc: [3,4]}"))); ASSERT(m.matches(fromjson("{loc: [4,4]}"))); ASSERT(m.matches(fromjson("{loc: [5,5]}"))); @@ -166,7 +168,7 @@ class WithinPolygon { public: void run() { M m(fromjson("{loc:{$within:{$polygon:[{x:0,y:0},[0,5],[5,5],[5,0]]}}}"), - ExtensionsCallback()); + ExtensionsCallbackDisallowExtensions()); ASSERT(m.matches(fromjson("{loc: [3,4]}"))); ASSERT(m.matches(fromjson("{loc: [4,4]}"))); ASSERT(m.matches(fromjson("{loc: {x:5,y:5}}"))); @@ -179,7 +181,8 @@ template <typename M> class WithinCenter { public: void run() { - M m(fromjson("{loc:{$within:{$center:[{x:30,y:30},10]}}}"), ExtensionsCallback()); + M m(fromjson("{loc:{$within:{$center:[{x:30,y:30},10]}}}"), + ExtensionsCallbackDisallowExtensions()); ASSERT(!m.matches(fromjson("{loc: [3,4]}"))); ASSERT(m.matches(fromjson("{loc: {x:30,y:30}}"))); ASSERT(m.matches(fromjson("{loc: [20,30]}"))); @@ -195,7 +198,7 @@ template <typename M> class ElemMatchKey { public: void run() { - M matcher(BSON("a.b" << 1), ExtensionsCallback()); + M matcher(BSON("a.b" << 1), ExtensionsCallbackDisallowExtensions()); MatchDetails details; details.requestElemMatchKey(); ASSERT(!details.hasElemMatchKey()); @@ -226,7 +229,7 @@ template <typename M> class TimingBase { public: long dotime(const BSONObj& patt, const BSONObj& obj) { - M m(patt, ExtensionsCallback()); + M m(patt, ExtensionsCallbackDisallowExtensions()); Timer t; for (int i = 0; i < 900000; i++) { if (!m.matches(obj)) { diff --git a/src/mongo/dbtests/oplogstarttests.cpp b/src/mongo/dbtests/oplogstarttests.cpp index 417a0b05c3d..ddb6422fc86 100644 --- a/src/mongo/dbtests/oplogstarttests.cpp +++ b/src/mongo/dbtests/oplogstarttests.cpp @@ -29,6 +29,7 @@ #include "mongo/db/dbdirectclient.h" #include "mongo/db/exec/oplogstart.h" #include "mongo/db/exec/working_set.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/service_context.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/query/canonical_query.h" @@ -75,7 +76,8 @@ protected: } void setupFromQuery(const BSONObj& query) { - auto statusWithCQ = CanonicalQuery::canonicalize(nss, query); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, query, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); _cq = std::move(statusWithCQ.getValue()); _oplogws.reset(new WorkingSet()); diff --git a/src/mongo/dbtests/plan_ranking.cpp b/src/mongo/dbtests/plan_ranking.cpp index 6c853e409e3..33b47fb257e 100644 --- a/src/mongo/dbtests/plan_ranking.cpp +++ b/src/mongo/dbtests/plan_ranking.cpp @@ -40,6 +40,7 @@ #include "mongo/db/exec/multi_plan.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/json.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/query/get_executor.h" #include "mongo/db/query/query_knobs.h" @@ -189,7 +190,8 @@ public: // Run the query {a:4, b:1}. { - auto statusWithCQ = CanonicalQuery::canonicalize(nss, BSON("a" << 100 << "b" << 1)); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, BSON("a" << 100 << "b" << 1), ExtensionsCallbackDisallowExtensions()); verify(statusWithCQ.isOK()); cq = std::move(statusWithCQ.getValue()); ASSERT(cq.get()); @@ -206,7 +208,8 @@ public: // And run the same query again. { - auto statusWithCQ = CanonicalQuery::canonicalize(nss, BSON("a" << 100 << "b" << 1)); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, BSON("a" << 100 << "b" << 1), ExtensionsCallbackDisallowExtensions()); verify(statusWithCQ.isOK()); cq = std::move(statusWithCQ.getValue()); } @@ -239,8 +242,8 @@ public: addIndex(BSON("b" << 1)); // Run the query {a:1, b:{$gt:1}. - auto statusWithCQ = - CanonicalQuery::canonicalize(nss, BSON("a" << 1 << "b" << BSON("$gt" << 1))); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, BSON("a" << 1 << "b" << BSON("$gt" << 1)), ExtensionsCallbackDisallowExtensions()); verify(statusWithCQ.isOK()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(NULL != cq.get()); @@ -278,8 +281,11 @@ public: addIndex(BSON("a" << 1 << "b" << 1)); // Query for a==27 with projection that wants 'a' and 'b'. BSONObj() is for sort. - auto statusWithCQ = CanonicalQuery::canonicalize( - nss, BSON("a" << 27), BSONObj(), BSON("_id" << 0 << "a" << 1 << "b" << 1)); + auto statusWithCQ = CanonicalQuery::canonicalize(nss, + BSON("a" << 27), + BSONObj(), + BSON("_id" << 0 << "a" << 1 << "b" << 1), + ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(NULL != cq.get()); @@ -312,7 +318,8 @@ public: // There is no data that matches this query but we don't know that until EOF. BSONObj queryObj = BSON("a" << 1 << "b" << 1 << "c" << 99); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, queryObj); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, queryObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(NULL != cq.get()); @@ -348,8 +355,11 @@ public: // There is no data that matches this query ({a:2}). Both scans will hit EOF before // returning any data. - auto statusWithCQ = CanonicalQuery::canonicalize( - nss, BSON("a" << 2), BSONObj(), BSON("_id" << 0 << "a" << 1 << "b" << 1)); + auto statusWithCQ = CanonicalQuery::canonicalize(nss, + BSON("a" << 2), + BSONObj(), + BSON("_id" << 0 << "a" << 1 << "b" << 1), + ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(NULL != cq.get()); @@ -380,7 +390,8 @@ public: addIndex(BSON("b" << 1)); // Run the query {a:N+1, b:1}. (No such document.) - auto statusWithCQ = CanonicalQuery::canonicalize(nss, BSON("a" << N + 1 << "b" << 1)); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, BSON("a" << N + 1 << "b" << 1), ExtensionsCallbackDisallowExtensions()); verify(statusWithCQ.isOK()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(NULL != cq.get()); @@ -415,7 +426,9 @@ public: // Run the query {a:N+1, b:1}. (No such document.) auto statusWithCQ = - CanonicalQuery::canonicalize(nss, BSON("a" << BSON("$gte" << N + 1) << "b" << 1)); + CanonicalQuery::canonicalize(nss, + BSON("a" << BSON("$gte" << N + 1) << "b" << 1), + ExtensionsCallbackDisallowExtensions()); verify(statusWithCQ.isOK()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(NULL != cq.get()); @@ -445,7 +458,8 @@ public: BSONObj queryObj = BSON("_id" << BSON("$gte" << 20 << "$lte" << 200)); BSONObj sortObj = BSON("c" << 1); BSONObj projObj = BSONObj(); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, queryObj, sortObj, projObj); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, queryObj, sortObj, projObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); @@ -472,7 +486,8 @@ public: } // Look for A Space Odyssey. - auto statusWithCQ = CanonicalQuery::canonicalize(nss, BSON("foo" << 2001)); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, BSON("foo" << 2001), ExtensionsCallbackDisallowExtensions()); verify(statusWithCQ.isOK()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(NULL != cq.get()); @@ -506,7 +521,8 @@ public: auto statusWithCQ = CanonicalQuery::canonicalize(nss, BSON("a" << 1), BSON("d" << 1), // sort - BSONObj()); // projection + BSONObj(), // projection + ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(NULL != cq.get()); @@ -541,8 +557,8 @@ public: // Solutions using either 'a' or 'b' will take a long time to start producing // results. However, an index scan on 'b' will start producing results sooner // than an index scan on 'a'. - auto statusWithCQ = - CanonicalQuery::canonicalize(nss, fromjson("{a: 1, b: 1, c: {$gte: 5000}}")); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, fromjson("{a: 1, b: 1, c: {$gte: 5000}}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(NULL != cq.get()); @@ -572,8 +588,8 @@ public: addIndex(BSON("b" << 1 << "c" << 1)); addIndex(BSON("a" << 1)); - auto statusWithCQ = - CanonicalQuery::canonicalize(nss, fromjson("{a: 9, b: {$ne: 10}, c: 9}")); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, fromjson("{a: 9, b: {$ne: 10}, c: 9}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(NULL != cq.get()); diff --git a/src/mongo/dbtests/query_plan_executor.cpp b/src/mongo/dbtests/query_plan_executor.cpp index 2b45aaf7c0b..5e8a5f5ee11 100644 --- a/src/mongo/dbtests/query_plan_executor.cpp +++ b/src/mongo/dbtests/query_plan_executor.cpp @@ -40,6 +40,7 @@ #include "mongo/db/exec/working_set_common.h" #include "mongo/db/json.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/pipeline/expression_context.h" #include "mongo/db/pipeline/pipeline.h" @@ -99,7 +100,8 @@ public: unique_ptr<WorkingSet> ws(new WorkingSet()); // Canonicalize the query. - auto statusWithCQ = CanonicalQuery::canonicalize(nss, filterObj); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, filterObj, ExtensionsCallbackDisallowExtensions()); verify(statusWithCQ.isOK()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); verify(NULL != cq.get()); @@ -143,7 +145,8 @@ public: IndexScan* ix = new IndexScan(&_txn, ixparams, ws.get(), NULL); unique_ptr<PlanStage> root(new FetchStage(&_txn, ws.get(), ix, NULL, coll)); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, BSONObj()); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, BSONObj(), ExtensionsCallbackDisallowExtensions()); verify(statusWithCQ.isOK()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); verify(NULL != cq.get()); diff --git a/src/mongo/dbtests/query_stage_cached_plan.cpp b/src/mongo/dbtests/query_stage_cached_plan.cpp index aff0f037bb4..132859afb92 100644 --- a/src/mongo/dbtests/query_stage_cached_plan.cpp +++ b/src/mongo/dbtests/query_stage_cached_plan.cpp @@ -35,6 +35,7 @@ #include "mongo/db/db_raii.h" #include "mongo/db/jsobj.h" #include "mongo/db/json.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/query/canonical_query.h" #include "mongo/db/query/get_executor.h" @@ -111,7 +112,8 @@ public: ASSERT(collection); // Query can be answered by either index on "a" or index on "b". - auto statusWithCQ = CanonicalQuery::canonicalize(nss, fromjson("{a: {$gte: 8}, b: 1}")); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, fromjson("{a: {$gte: 8}, b: 1}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); const std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); @@ -175,7 +177,8 @@ public: ASSERT(collection); // Query can be answered by either index on "a" or index on "b". - auto statusWithCQ = CanonicalQuery::canonicalize(nss, fromjson("{a: {$gte: 8}, b: 1}")); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, fromjson("{a: {$gte: 8}, b: 1}"), ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); const std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); diff --git a/src/mongo/dbtests/query_stage_collscan.cpp b/src/mongo/dbtests/query_stage_collscan.cpp index d4307f54fbf..1cbf7b32d40 100644 --- a/src/mongo/dbtests/query_stage_collscan.cpp +++ b/src/mongo/dbtests/query_stage_collscan.cpp @@ -40,6 +40,7 @@ #include "mongo/db/exec/plan_stage.h" #include "mongo/db/json.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/query/plan_executor.h" #include "mongo/db/storage/record_store.h" @@ -88,7 +89,8 @@ public: params.tailable = false; // Make the filter. - StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(filterObj); + StatusWithMatchExpression statusWithMatcher = + MatchExpressionParser::parse(filterObj, ExtensionsCallbackDisallowExtensions()); verify(statusWithMatcher.isOK()); unique_ptr<MatchExpression> filterExpr = std::move(statusWithMatcher.getValue()); diff --git a/src/mongo/dbtests/query_stage_count.cpp b/src/mongo/dbtests/query_stage_count.cpp index 3dd676a878a..b64a9e7f794 100644 --- a/src/mongo/dbtests/query_stage_count.cpp +++ b/src/mongo/dbtests/query_stage_count.cpp @@ -37,6 +37,7 @@ #include "mongo/db/exec/working_set.h" #include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/dbtests/dbtests.h" @@ -140,8 +141,8 @@ public: unique_ptr<WorkingSet> ws(new WorkingSet); - StatusWithMatchExpression statusWithMatcher = - MatchExpressionParser::parse(request.getQuery()); + StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse( + request.getQuery(), ExtensionsCallbackDisallowExtensions()); ASSERT(statusWithMatcher.isOK()); unique_ptr<MatchExpression> expression = std::move(statusWithMatcher.getValue()); diff --git a/src/mongo/dbtests/query_stage_delete.cpp b/src/mongo/dbtests/query_stage_delete.cpp index 3923070b498..047cbefdb7f 100644 --- a/src/mongo/dbtests/query_stage_delete.cpp +++ b/src/mongo/dbtests/query_stage_delete.cpp @@ -39,6 +39,7 @@ #include "mongo/db/exec/collection_scan.h" #include "mongo/db/exec/delete.h" #include "mongo/db/exec/queued_data_stage.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/query/canonical_query.h" #include "mongo/db/service_context.h" @@ -102,7 +103,8 @@ public: } unique_ptr<CanonicalQuery> canonicalize(const BSONObj& query) { - auto statusWithCQ = CanonicalQuery::canonicalize(nss, query); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, query, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); return std::move(statusWithCQ.getValue()); } diff --git a/src/mongo/dbtests/query_stage_fetch.cpp b/src/mongo/dbtests/query_stage_fetch.cpp index fce4be75848..55bb911347f 100644 --- a/src/mongo/dbtests/query_stage_fetch.cpp +++ b/src/mongo/dbtests/query_stage_fetch.cpp @@ -41,6 +41,7 @@ #include "mongo/db/exec/queued_data_stage.h" #include "mongo/db/json.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/dbtests/dbtests.h" #include "mongo/stdx/memory.h" @@ -192,7 +193,8 @@ public: // Make the filter. BSONObj filterObj = BSON("foo" << 6); - StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(filterObj); + StatusWithMatchExpression statusWithMatcher = + MatchExpressionParser::parse(filterObj, ExtensionsCallbackDisallowExtensions()); verify(statusWithMatcher.isOK()); unique_ptr<MatchExpression> filterExpr = std::move(statusWithMatcher.getValue()); diff --git a/src/mongo/dbtests/query_stage_multiplan.cpp b/src/mongo/dbtests/query_stage_multiplan.cpp index cda5de388cf..2de6a2bb126 100644 --- a/src/mongo/dbtests/query_stage_multiplan.cpp +++ b/src/mongo/dbtests/query_stage_multiplan.cpp @@ -38,6 +38,7 @@ #include "mongo/db/exec/queued_data_stage.h" #include "mongo/db/json.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/query/get_executor.h" #include "mongo/db/query/plan_executor.h" @@ -144,7 +145,8 @@ public: // Make the filter. BSONObj filterObj = BSON("foo" << 7); - StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(filterObj); + StatusWithMatchExpression statusWithMatcher = + MatchExpressionParser::parse(filterObj, ExtensionsCallbackDisallowExtensions()); verify(statusWithMatcher.isOK()); unique_ptr<MatchExpression> filter = std::move(statusWithMatcher.getValue()); // Make the stage. @@ -152,7 +154,8 @@ public: new CollectionScan(&_txn, csparams, sharedWs.get(), filter.get())); // Hand the plans off to the MPS. - auto statusWithCQ = CanonicalQuery::canonicalize(nss, BSON("foo" << 7)); + auto statusWithCQ = CanonicalQuery::canonicalize( + nss, BSON("foo" << 7), ExtensionsCallbackDisallowExtensions()); verify(statusWithCQ.isOK()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); verify(NULL != cq.get()); @@ -209,7 +212,8 @@ public: auto statusWithCQ = CanonicalQuery::canonicalize(nss, BSON("a" << 1 << "b" << 1), // query BSON("b" << 1), // sort - BSONObj()); // proj + BSONObj(), // proj + ExtensionsCallbackDisallowExtensions()); verify(statusWithCQ.isOK()); unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); ASSERT(NULL != cq.get()); @@ -311,7 +315,8 @@ public: AutoGetCollectionForRead ctx(&_txn, nss.ns()); - auto cq = uassertStatusOK(CanonicalQuery::canonicalize(nss, BSON("x" << 1))); + auto cq = uassertStatusOK(CanonicalQuery::canonicalize( + nss, BSON("x" << 1), ExtensionsCallbackDisallowExtensions())); unique_ptr<MultiPlanStage> mps = make_unique<MultiPlanStage>(&_txn, ctx.getCollection(), cq.get()); @@ -385,7 +390,8 @@ public: // Create the executor (Matching all documents). auto queryObj = BSON("foo" << BSON("$gte" << 0)); - auto cq = uassertStatusOK(CanonicalQuery::canonicalize(nss, queryObj)); + auto cq = uassertStatusOK( + CanonicalQuery::canonicalize(nss, queryObj, ExtensionsCallbackDisallowExtensions())); auto exec = uassertStatusOK(getExecutor(&_txn, coll, std::move(cq), PlanExecutor::YIELD_MANUAL)); diff --git a/src/mongo/dbtests/query_stage_subplan.cpp b/src/mongo/dbtests/query_stage_subplan.cpp index 624405619a4..7a61f48a873 100644 --- a/src/mongo/dbtests/query_stage_subplan.cpp +++ b/src/mongo/dbtests/query_stage_subplan.cpp @@ -37,6 +37,7 @@ #include "mongo/db/exec/subplan.h" #include "mongo/db/jsobj.h" #include "mongo/db/json.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/matcher/extensions_callback_noop.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/query/canonical_query.h" @@ -106,7 +107,8 @@ public: "{$or: [{a: {$geoWithin: {$centerSphere: [[0,0],10]}}}," "{a: {$geoWithin: {$centerSphere: [[1,1],10]}}}]}"); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, query); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, query, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); @@ -149,7 +151,8 @@ public: Collection* collection = ctx.getCollection(); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, query); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, query, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); @@ -204,7 +207,8 @@ public: Collection* collection = ctx.getCollection(); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, query); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, query, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); @@ -260,7 +264,8 @@ public: Collection* collection = ctx.getCollection(); - auto statusWithCQ = CanonicalQuery::canonicalize(nss, query); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, query, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue()); @@ -441,7 +446,8 @@ public: // Rewrite (AND (OR a b) e) => (OR (AND a e) (AND b e)) { BSONObj queryObj = fromjson("{$or:[{a:1}, {b:1}], e:1}"); - StatusWithMatchExpression expr = MatchExpressionParser::parse(queryObj); + StatusWithMatchExpression expr = + MatchExpressionParser::parse(queryObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(expr.getStatus()); std::unique_ptr<MatchExpression> rewrittenExpr = SubplanStage::rewriteToRootedOr(std::move(expr.getValue())); @@ -457,7 +463,8 @@ public: // Rewrite (AND (OR a b) e f) => (OR (AND a e f) (AND b e f)) { BSONObj queryObj = fromjson("{$or:[{a:1}, {b:1}], e:1, f:1}"); - StatusWithMatchExpression expr = MatchExpressionParser::parse(queryObj); + StatusWithMatchExpression expr = + MatchExpressionParser::parse(queryObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(expr.getStatus()); std::unique_ptr<MatchExpression> rewrittenExpr = SubplanStage::rewriteToRootedOr(std::move(expr.getValue())); @@ -473,7 +480,8 @@ public: // Rewrite (AND (OR (AND a b) (AND c d) e f) => (OR (AND a b e f) (AND c d e f)) { BSONObj queryObj = fromjson("{$or:[{a:1,b:1}, {c:1,d:1}], e:1,f:1}"); - StatusWithMatchExpression expr = MatchExpressionParser::parse(queryObj); + StatusWithMatchExpression expr = + MatchExpressionParser::parse(queryObj, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(expr.getStatus()); std::unique_ptr<MatchExpression> rewrittenExpr = SubplanStage::rewriteToRootedOr(std::move(expr.getValue())); @@ -507,7 +515,8 @@ public: insert(BSON("_id" << 3 << "a" << 1 << "c" << 3)); insert(BSON("_id" << 4 << "a" << 1 << "c" << 4)); - auto cq = unittest::assertGet(CanonicalQuery::canonicalize(nss, query)); + auto cq = unittest::assertGet( + CanonicalQuery::canonicalize(nss, query, ExtensionsCallbackDisallowExtensions())); Collection* collection = ctx.getCollection(); @@ -566,7 +575,8 @@ public: BSONObj query = fromjson("{$or: [{a: 1}, {a: {$ne:1}}]}"); BSONObj sort = BSON("d" << 1); BSONObj projection; - auto cq = unittest::assertGet(CanonicalQuery::canonicalize(nss, query, sort, projection)); + auto cq = unittest::assertGet(CanonicalQuery::canonicalize( + nss, query, sort, projection, ExtensionsCallbackDisallowExtensions())); Collection* collection = ctx.getCollection(); diff --git a/src/mongo/dbtests/query_stage_tests.cpp b/src/mongo/dbtests/query_stage_tests.cpp index 6898293f858..d18c2880812 100644 --- a/src/mongo/dbtests/query_stage_tests.cpp +++ b/src/mongo/dbtests/query_stage_tests.cpp @@ -35,6 +35,7 @@ #include "mongo/db/exec/plan_stage.h" #include "mongo/db/json.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/query/plan_executor.h" #include "mongo/dbtests/dbtests.h" @@ -77,7 +78,8 @@ public: int countResults(const IndexScanParams& params, BSONObj filterObj = BSONObj()) { AutoGetCollectionForRead ctx(&_txn, ns()); - StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(filterObj); + StatusWithMatchExpression statusWithMatcher = + MatchExpressionParser::parse(filterObj, ExtensionsCallbackDisallowExtensions()); verify(statusWithMatcher.isOK()); unique_ptr<MatchExpression> filterExpr = std::move(statusWithMatcher.getValue()); diff --git a/src/mongo/dbtests/query_stage_update.cpp b/src/mongo/dbtests/query_stage_update.cpp index 9180a0d527d..f4721c7b9f3 100644 --- a/src/mongo/dbtests/query_stage_update.cpp +++ b/src/mongo/dbtests/query_stage_update.cpp @@ -43,6 +43,7 @@ #include "mongo/db/exec/working_set.h" #include "mongo/db/jsobj.h" #include "mongo/db/json.h" +#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/ops/update_driver.h" #include "mongo/db/ops/update_lifecycle_impl.h" @@ -86,7 +87,8 @@ public: } unique_ptr<CanonicalQuery> canonicalize(const BSONObj& query) { - auto statusWithCQ = CanonicalQuery::canonicalize(nss, query); + auto statusWithCQ = + CanonicalQuery::canonicalize(nss, query, ExtensionsCallbackDisallowExtensions()); ASSERT_OK(statusWithCQ.getStatus()); return std::move(statusWithCQ.getValue()); } |