summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Wahlin <james.wahlin@10gen.com>2017-04-11 10:12:56 -0400
committerJustin Seyster <justin.seyster@mongodb.com>2017-04-28 17:34:37 -0400
commit858a26bfa16bf0904fe5776e219f8f00b5d864e6 (patch)
tree27194d2502292291308e37f2bb51e022709591b5
parent6487020c8c781ce2e536dc61adf7cd65dc9eb361 (diff)
downloadmongo-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.js34
-rw-r--r--src/mongo/db/views/view_catalog.cpp14
-rw-r--r--src/mongo/db/views/view_catalog_test.cpp10
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");