diff options
Diffstat (limited to 'src/mongo/db/ops/insert.cpp')
-rw-r--r-- | src/mongo/db/ops/insert.cpp | 292 |
1 files changed, 146 insertions, 146 deletions
diff --git a/src/mongo/db/ops/insert.cpp b/src/mongo/db/ops/insert.cpp index 38a2a478043..827bdc69c39 100644 --- a/src/mongo/db/ops/insert.cpp +++ b/src/mongo/db/ops/insert.cpp @@ -34,174 +34,174 @@ namespace mongo { - using std::string; - - using namespace mongoutils; - - StatusWith<BSONObj> fixDocumentForInsert( const BSONObj& doc ) { - if ( doc.objsize() > BSONObjMaxUserSize ) - return StatusWith<BSONObj>( ErrorCodes::BadValue, - str::stream() - << "object to insert too large" - << ". size in bytes: " << doc.objsize() - << ", max size: " << BSONObjMaxUserSize ); - - bool firstElementIsId = doc.firstElement().fieldNameStringData() == "_id"; - bool hasTimestampToFix = false; - { - BSONObjIterator i( doc ); - while ( i.more() ) { - BSONElement e = i.next(); - - if ( e.type() == bsonTimestamp && e.timestampValue() == 0 ) { - // we replace Timestamp(0,0) at the top level with a correct value - // in the fast pass, we just mark that we want to swap - hasTimestampToFix = true; - } - - const char* fieldName = e.fieldName(); - - if ( fieldName[0] == '$' ) { - return StatusWith<BSONObj>( ErrorCodes::BadValue, - str::stream() - << "Document can't have $ prefixed field names: " - << e.fieldName() ); - } - - // check no regexp for _id (SERVER-9502) - // also, disallow undefined and arrays - if ( str::equals( fieldName, "_id") ) { - if ( e.type() == RegEx ) { - return StatusWith<BSONObj>( ErrorCodes::BadValue, - "can't use a regex for _id" ); - } - if ( e.type() == Undefined ) { - return StatusWith<BSONObj>( ErrorCodes::BadValue, - "can't use a undefined for _id" ); - } - if ( e.type() == Array ) { - return StatusWith<BSONObj>( ErrorCodes::BadValue, - "can't use an array for _id" ); - } - if ( e.type() == Object ) { - BSONObj o = e.Obj(); - Status s = o.storageValidEmbedded(); - if ( !s.isOK() ) - return StatusWith<BSONObj>( s ); - } - } +using std::string; + +using namespace mongoutils; + +StatusWith<BSONObj> fixDocumentForInsert(const BSONObj& doc) { + if (doc.objsize() > BSONObjMaxUserSize) + return StatusWith<BSONObj>(ErrorCodes::BadValue, + str::stream() << "object to insert too large" + << ". size in bytes: " << doc.objsize() + << ", max size: " << BSONObjMaxUserSize); + + bool firstElementIsId = doc.firstElement().fieldNameStringData() == "_id"; + bool hasTimestampToFix = false; + { + BSONObjIterator i(doc); + while (i.more()) { + BSONElement e = i.next(); + if (e.type() == bsonTimestamp && e.timestampValue() == 0) { + // we replace Timestamp(0,0) at the top level with a correct value + // in the fast pass, we just mark that we want to swap + hasTimestampToFix = true; } - } - - if ( firstElementIsId && !hasTimestampToFix ) - return StatusWith<BSONObj>( BSONObj() ); - bool hadId = firstElementIsId; + const char* fieldName = e.fieldName(); - BSONObjIterator i( doc ); - - BSONObjBuilder b( doc.objsize() + 16 ); - if ( firstElementIsId ) { - b.append( doc.firstElement() ); - i.next(); - } - else { - BSONElement e = doc["_id"]; - if ( e.type() ) { - b.append( e ); - hadId = true; + if (fieldName[0] == '$') { + return StatusWith<BSONObj>(ErrorCodes::BadValue, + str::stream() + << "Document can't have $ prefixed field names: " + << e.fieldName()); } - else { - b.appendOID( "_id", NULL, true ); - } - } - while ( i.more() ) { - BSONElement e = i.next(); - if ( hadId && e.fieldNameStringData() == "_id" ) { - // no-op - } - else if ( e.type() == bsonTimestamp && e.timestampValue() == 0 ) { - b.append( e.fieldName(), getNextGlobalTimestamp() ); - } - else { - b.append( e ); + // check no regexp for _id (SERVER-9502) + // also, disallow undefined and arrays + if (str::equals(fieldName, "_id")) { + if (e.type() == RegEx) { + return StatusWith<BSONObj>(ErrorCodes::BadValue, "can't use a regex for _id"); + } + if (e.type() == Undefined) { + return StatusWith<BSONObj>(ErrorCodes::BadValue, + "can't use a undefined for _id"); + } + if (e.type() == Array) { + return StatusWith<BSONObj>(ErrorCodes::BadValue, "can't use an array for _id"); + } + if (e.type() == Object) { + BSONObj o = e.Obj(); + Status s = o.storageValidEmbedded(); + if (!s.isOK()) + return StatusWith<BSONObj>(s); + } } } - return StatusWith<BSONObj>( b.obj() ); } - Status userAllowedWriteNS( StringData ns ) { - return userAllowedWriteNS( nsToDatabaseSubstring( ns ), nsToCollectionSubstring( ns ) ); - } + if (firstElementIsId && !hasTimestampToFix) + return StatusWith<BSONObj>(BSONObj()); - Status userAllowedWriteNS( const NamespaceString& ns ) { - return userAllowedWriteNS( ns.db(), ns.coll() ); - } + bool hadId = firstElementIsId; + + BSONObjIterator i(doc); - Status userAllowedWriteNS( StringData db, StringData coll ) { - if ( coll == "system.profile" ) { - return Status( ErrorCodes::BadValue, - str::stream() << "cannot write to '" << db << ".system.profile'" ); + BSONObjBuilder b(doc.objsize() + 16); + if (firstElementIsId) { + b.append(doc.firstElement()); + i.next(); + } else { + BSONElement e = doc["_id"]; + if (e.type()) { + b.append(e); + hadId = true; + } else { + b.appendOID("_id", NULL, true); } - return userAllowedCreateNS( db, coll ); } - Status userAllowedCreateNS( StringData db, StringData coll ) { - // validity checking - - if ( db.size() == 0 ) - return Status( ErrorCodes::BadValue, "db cannot be blank" ); - - if ( !NamespaceString::validDBName( db ) ) - return Status( ErrorCodes::BadValue, "invalid db name" ); - - if ( coll.size() == 0 ) - return Status( ErrorCodes::BadValue, "collection cannot be blank" ); - - if ( !NamespaceString::validCollectionName( coll ) ) - return Status( ErrorCodes::BadValue, "invalid collection name" ); - - if ( db.size() + 1 /* dot */ + coll.size() > NamespaceString::MaxNsCollectionLen ) - return Status( ErrorCodes::BadValue, - str::stream() - << "fully qualified namespace " << db << '.' << coll << " is too long " - << "(max is " << NamespaceString::MaxNsCollectionLen << " bytes)" ); + while (i.more()) { + BSONElement e = i.next(); + if (hadId && e.fieldNameStringData() == "_id") { + // no-op + } else if (e.type() == bsonTimestamp && e.timestampValue() == 0) { + b.append(e.fieldName(), getNextGlobalTimestamp()); + } else { + b.append(e); + } + } + return StatusWith<BSONObj>(b.obj()); +} - // check spceial areas +Status userAllowedWriteNS(StringData ns) { + return userAllowedWriteNS(nsToDatabaseSubstring(ns), nsToCollectionSubstring(ns)); +} - if ( db == "system" ) - return Status( ErrorCodes::BadValue, "cannot use 'system' database" ); +Status userAllowedWriteNS(const NamespaceString& ns) { + return userAllowedWriteNS(ns.db(), ns.coll()); +} +Status userAllowedWriteNS(StringData db, StringData coll) { + if (coll == "system.profile") { + return Status(ErrorCodes::BadValue, + str::stream() << "cannot write to '" << db << ".system.profile'"); + } + return userAllowedCreateNS(db, coll); +} - if ( coll.startsWith( "system." ) ) { - if ( coll == "system.indexes" ) return Status::OK(); - if ( coll == "system.js" ) return Status::OK(); - if ( coll == "system.profile" ) return Status::OK(); - if ( coll == "system.users" ) return Status::OK(); - if ( db == "admin" ) { - if ( coll == "system.version" ) return Status::OK(); - if ( coll == "system.roles" ) return Status::OK(); - if ( coll == "system.new_users" ) return Status::OK(); - if ( coll == "system.backup_users" ) return Status::OK(); - } - if ( db == "local" ) { - if ( coll == "system.replset" ) return Status::OK(); - } - return Status( ErrorCodes::BadValue, - str::stream() << "cannot write to '" << db << "." << coll << "'" ); +Status userAllowedCreateNS(StringData db, StringData coll) { + // validity checking + + if (db.size() == 0) + return Status(ErrorCodes::BadValue, "db cannot be blank"); + + if (!NamespaceString::validDBName(db)) + return Status(ErrorCodes::BadValue, "invalid db name"); + + if (coll.size() == 0) + return Status(ErrorCodes::BadValue, "collection cannot be blank"); + + if (!NamespaceString::validCollectionName(coll)) + return Status(ErrorCodes::BadValue, "invalid collection name"); + + if (db.size() + 1 /* dot */ + coll.size() > NamespaceString::MaxNsCollectionLen) + return Status(ErrorCodes::BadValue, + str::stream() + << "fully qualified namespace " << db << '.' << coll << " is too long " + << "(max is " << NamespaceString::MaxNsCollectionLen << " bytes)"); + + // check spceial areas + + if (db == "system") + return Status(ErrorCodes::BadValue, "cannot use 'system' database"); + + + if (coll.startsWith("system.")) { + if (coll == "system.indexes") + return Status::OK(); + if (coll == "system.js") + return Status::OK(); + if (coll == "system.profile") + return Status::OK(); + if (coll == "system.users") + return Status::OK(); + if (db == "admin") { + if (coll == "system.version") + return Status::OK(); + if (coll == "system.roles") + return Status::OK(); + if (coll == "system.new_users") + return Status::OK(); + if (coll == "system.backup_users") + return Status::OK(); } - - // some special rules - - if ( coll.find( ".system." ) != string::npos ) { - // this matches old (2.4 and older) behavior, but I'm not sure its a good idea - return Status( ErrorCodes::BadValue, - str::stream() << "cannot write to '" << db << "." << coll << "'" ); + if (db == "local") { + if (coll == "system.replset") + return Status::OK(); } + return Status(ErrorCodes::BadValue, + str::stream() << "cannot write to '" << db << "." << coll << "'"); + } - return Status::OK(); + // some special rules + + if (coll.find(".system.") != string::npos) { + // this matches old (2.4 and older) behavior, but I'm not sure its a good idea + return Status(ErrorCodes::BadValue, + str::stream() << "cannot write to '" << db << "." << coll << "'"); } + return Status::OK(); +} } |