diff options
author | James Wahlin <james.wahlin@10gen.com> | 2017-04-11 10:12:56 -0400 |
---|---|---|
committer | Justin Seyster <justin.seyster@mongodb.com> | 2017-04-28 17:34:37 -0400 |
commit | 858a26bfa16bf0904fe5776e219f8f00b5d864e6 (patch) | |
tree | 27194d2502292291308e37f2bb51e022709591b5 | |
parent | 6487020c8c781ce2e536dc61adf7cd65dc9eb361 (diff) | |
download | mongo-858a26bfa16bf0904fe5776e219f8f00b5d864e6.tar.gz |
SERVER-28271 Improve handling of invalid view pipeline defs
(cherry picked from commit b5e2615f9cf29942783ed554afeb364052dd83a4)
-rw-r--r-- | jstests/core/views/invalid_system_views.js | 34 | ||||
-rw-r--r-- | src/mongo/db/views/view_catalog.cpp | 14 | ||||
-rw-r--r-- | src/mongo/db/views/view_catalog_test.cpp | 10 |
3 files changed, 46 insertions, 12 deletions
diff --git a/jstests/core/views/invalid_system_views.js b/jstests/core/views/invalid_system_views.js index 058a429a2e6..3ba282d2ca1 100644 --- a/jstests/core/views/invalid_system_views.js +++ b/jstests/core/views/invalid_system_views.js @@ -104,15 +104,27 @@ assert.writeOK(viewsDB.system.views.remove(badViewDefinition)); } - let badViews = [ - {_id: "badViewStringPipeline", pipeline: "bad"}, - {_id: "badViewEmptyObjectPipeline", pipeline: {}}, - {_id: "badViewNumericalPipeline", pipeline: 7}, - {_id: "badViewArrayWithIntegerPipeline", pipeline: [1]}, - {_id: "badViewArrayWithEmptyObjectPipeline", pipeline: [{}]}, - {_id: "badViewArrayWithEmptyArrayPipeline", pipeline: [[]]}, - {_id: 7, pipeline: []}, - {_id: "invalid_system_views.embedded\0null", viewOn: "collection", pipeline: []} - ]; - badViews.forEach(runTest); + runTest( + {_id: "invalid_system_views.badViewStringPipeline", viewOn: "collection", pipeline: "bad"}); + runTest({ + _id: "invalid_system_views.badViewEmptyObjectPipeline", + viewOn: "collection", + pipeline: {} + }); + runTest( + {_id: "invalid_system_views.badViewNumericalPipeline", viewOn: "collection", pipeline: 7}); + runTest({ + _id: "invalid_system_views.badViewArrayWithIntegerPipeline", + viewOn: "collection", + pipeline: [1] + }); + runTest({ + _id: "invalid_system_views.badViewArrayWithEmptyArrayPipeline", + viewOn: "collection", + pipeline: [[]] + }); + runTest({_id: 7, viewOn: "collection", pipeline: []}); + runTest({_id: "invalid_system_views.embedded\0null", viewOn: "collection", pipeline: []}); + runTest({_id: "invalidNotFullyQualifiedNs", viewOn: "collection", pipeline: []}); + runTest({_id: "invalid_system_views.missingViewOnField", pipeline: []}); }()); diff --git a/src/mongo/db/views/view_catalog.cpp b/src/mongo/db/views/view_catalog.cpp index e0f3c0beb5e..30cabf24935 100644 --- a/src/mongo/db/views/view_catalog.cpp +++ b/src/mongo/db/views/view_catalog.cpp @@ -89,10 +89,22 @@ Status ViewCatalog::_reloadIfNeeded_inlock(OperationContext* txn) { } NamespaceString viewName(view["_id"].str()); + + auto pipeline = view["pipeline"].Obj(); + for (auto&& stage : pipeline) { + if (BSONType::Object != stage.type()) { + return Status(ErrorCodes::InvalidViewDefinition, + str::stream() << "View 'pipeline' entries must be objects, but " + << viewName.toString() + << " has a pipeline element of type " + << stage.type()); + } + } + _viewMap[viewName.ns()] = std::make_shared<ViewDefinition>(viewName.db(), viewName.coll(), view["viewOn"].str(), - view["pipeline"].Obj(), + pipeline, std::move(collator.getValue())); return Status::OK(); }); diff --git a/src/mongo/db/views/view_catalog_test.cpp b/src/mongo/db/views/view_catalog_test.cpp index b780beb83be..ea9dcf1e1a6 100644 --- a/src/mongo/db/views/view_catalog_test.cpp +++ b/src/mongo/db/views/view_catalog_test.cpp @@ -134,6 +134,16 @@ TEST_F(ViewCatalogFixture, CreateViewOnDifferentDatabase) { viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation)); } +TEST_F(ViewCatalogFixture, CreateViewWithPipelineFailsOnInvalidStageName) { + const NamespaceString viewName("db.view"); + const NamespaceString viewOn("db.coll"); + + auto invalidPipeline = BSON_ARRAY(BSON("INVALID_STAGE_NAME" << 1)); + ASSERT_THROWS( + viewCatalog.createView(opCtx.get(), viewName, viewOn, invalidPipeline, emptyCollation), + UserException); +} + TEST_F(ViewCatalogFixture, CreateViewOnInvalidCollectionName) { const NamespaceString viewName("db.view"); const NamespaceString viewOn("db.$coll"); |