diff options
author | Dan Pasette <dan@10gen.com> | 2014-05-24 22:50:15 -0400 |
---|---|---|
committer | Dan Pasette <dan@mongodb.com> | 2014-05-24 22:50:15 -0400 |
commit | c02fb34f01e88c7f49d3887042f947060a4f4a90 (patch) | |
tree | 241a0b498b7fa5bc07a1cc10ce1d06e66b7d136a | |
parent | 9a9b2e504d3c9cbbf4d9f58a1ff0e16c53719169 (diff) | |
download | mongo-c02fb34f01e88c7f49d3887042f947060a4f4a90.tar.gz |
SERVER-13737 CollectionOptions parser skip size/max if non-numeric
(backport 0a0ba030626243e3482830f485a3ecd79da1b7c8)
-rw-r--r-- | src/mongo/db/catalog/database.cpp | 14 | ||||
-rw-r--r-- | src/mongo/dbtests/pdfiletests.cpp | 50 |
2 files changed, 60 insertions, 4 deletions
diff --git a/src/mongo/db/catalog/database.cpp b/src/mongo/db/catalog/database.cpp index 3c1ce311d77..78bf1aa20a7 100644 --- a/src/mongo/db/catalog/database.cpp +++ b/src/mongo/db/catalog/database.cpp @@ -58,6 +58,8 @@ namespace mongo { Status CollectionOptions::parse( const BSONObj& options ) { reset(); + // During parsing, ignore some validation errors in order to accept options objects that + // were valid in previous versions of the server. SERVER-13737. BSONObjIterator i( options ); while ( i.more() ) { BSONElement e = i.next(); @@ -67,8 +69,10 @@ namespace mongo { capped = e.trueValue(); } else if ( fieldName == "size" ) { - if ( !e.isNumber() ) - return Status( ErrorCodes::BadValue, "size has to be a number" ); + if ( !e.isNumber() ) { + // Ignoring for backwards compatibility. + continue; + } cappedSize = e.numberLong(); if ( cappedSize < 0 ) return Status( ErrorCodes::BadValue, "size has to be >= 0" ); @@ -78,8 +82,10 @@ namespace mongo { cappedSize = Extent::minSize(); } else if ( fieldName == "max" ) { - if ( !e.isNumber() ) - return Status( ErrorCodes::BadValue, "max has to be a number" ); + if ( !options["capped"].trueValue() || !e.isNumber() ) { + // Ignoring for backwards compatibility. + continue; + } cappedMaxDocs = e.numberLong(); if ( !NamespaceDetails::validMaxCappedDocs( &cappedMaxDocs ) ) return Status( ErrorCodes::BadValue, diff --git a/src/mongo/dbtests/pdfiletests.cpp b/src/mongo/dbtests/pdfiletests.cpp index 9d0ea5d54c2..6c72830f830 100644 --- a/src/mongo/dbtests/pdfiletests.cpp +++ b/src/mongo/dbtests/pdfiletests.cpp @@ -223,6 +223,51 @@ namespace PdfileTests { } }; + class CollectionOptionsErrorBadSize { + public: + void run() { + ASSERT_NOT_OK( CollectionOptions().parse( fromjson( "{capped: true, size: -1}" ) ) ); + ASSERT_NOT_OK( CollectionOptions().parse( fromjson( "{capped: false, size: -1}" ) ) ); + } + }; + + class CollectionOptionsErrorBadMax { + public: + void run() { + ASSERT_NOT_OK( CollectionOptions().parse( BSON( "capped" << true << "max" + << ( 1LL << 31 ) ) ) ); + } + }; + + class CollectionOptionsIgnoreSizeWrongType { + public: + void run() { + CollectionOptions options; + ASSERT_OK( options.parse( fromjson( "{size: undefined, capped: undefined}" ) ) ); + ASSERT_EQUALS( options.capped, false ); + ASSERT_EQUALS( options.cappedSize, 0 ); + } + }; + + class CollectionOptionsIgnoreMaxWrongType { + public: + void run() { + CollectionOptions options; + ASSERT_OK( options.parse( fromjson( "{capped: true, size: 4096, max: ''}" ) ) ); + ASSERT_EQUALS( options.capped, true ); + ASSERT_EQUALS( options.cappedSize, 4096 ); + ASSERT_EQUALS( options.cappedMaxDocs, 0 ); + } + }; + + class CollectionOptionsIgnoreUnregisteredFields { + public: + void run() { + ASSERT_OK( CollectionOptions().parse( BSON( "create" << "c" ) ) ); + ASSERT_OK( CollectionOptions().parse( BSON( "foo" << "bar" ) ) ); + } + }; + class All : public Suite { public: All() : Suite( "pdfile" ) {} @@ -234,6 +279,11 @@ namespace PdfileTests { add< Insert::ValidId >(); add< ExtentSizing >(); add< CollectionOptionsRoundTrip >(); + add< CollectionOptionsErrorBadSize >(); + add< CollectionOptionsErrorBadMax >(); + add< CollectionOptionsIgnoreSizeWrongType >(); + add< CollectionOptionsIgnoreMaxWrongType >(); + add< CollectionOptionsIgnoreUnregisteredFields >(); } } myall; |