summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Pasette <dan@10gen.com>2014-05-24 22:50:15 -0400
committerDan Pasette <dan@mongodb.com>2014-05-24 22:50:15 -0400
commitc02fb34f01e88c7f49d3887042f947060a4f4a90 (patch)
tree241a0b498b7fa5bc07a1cc10ce1d06e66b7d136a
parent9a9b2e504d3c9cbbf4d9f58a1ff0e16c53719169 (diff)
downloadmongo-c02fb34f01e88c7f49d3887042f947060a4f4a90.tar.gz
SERVER-13737 CollectionOptions parser skip size/max if non-numeric
(backport 0a0ba030626243e3482830f485a3ecd79da1b7c8)
-rw-r--r--src/mongo/db/catalog/database.cpp14
-rw-r--r--src/mongo/dbtests/pdfiletests.cpp50
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;