summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SConscript.client1
-rw-r--r--src/mongo/db/cmdline.cpp10
-rw-r--r--src/mongo/db/cmdline.h2
-rw-r--r--src/mongo/db/dbmessage.h22
-rw-r--r--src/mongo/db/jsobj.cpp36
-rw-r--r--src/mongo/tools/tool.cpp6
-rw-r--r--src/mongo/tools/tool.h2
7 files changed, 39 insertions, 40 deletions
diff --git a/src/SConscript.client b/src/SConscript.client
index 05a4bb85d7b..14403223d28 100644
--- a/src/SConscript.client
+++ b/src/SConscript.client
@@ -26,6 +26,7 @@ clientSource = [
'mongo/base/parse_number.cpp',
'mongo/base/status.cpp',
'mongo/base/string_data.cpp',
+ 'mongo/bson/bson_validate.cpp',
'mongo/bson/oid.cpp',
'mongo/buildinfo.cpp',
"mongo/client/authentication_table_common.cpp",
diff --git a/src/mongo/db/cmdline.cpp b/src/mongo/db/cmdline.cpp
index 56b92d82638..40c57e7daf7 100644
--- a/src/mongo/db/cmdline.cpp
+++ b/src/mongo/db/cmdline.cpp
@@ -79,7 +79,6 @@ namespace {
("port", po::value<int>(&cmdLine.port), portInfoBuilder.str().c_str())
("bind_ip", po::value<string>(&cmdLine.bind_ip), "comma separated list of ip addresses to listen on - all local ips by default")
("maxConns",po::value<int>(), maxConnInfoBuilder.str().c_str())
- ("objcheck", "inspect client data for validity on receipt")
("logpath", po::value<string>() , "log file to send write to instead of stdout - has to be a file, not directory" )
("logappend" , "append to logpath instead of over-writing" )
("pidfilepath", po::value<string>(), "full path to pidfile (if not set, no pidfile is created)")
@@ -110,6 +109,8 @@ namespace {
// Extra hidden options
hidden.add_options()
+ ("objcheck", "inspect client data for validity on receipt (DEFAULT)")
+ ("noobjcheck", "do NOT inspect client data for validity on receipt")
("traceExceptions", "log stack traces for every exception")
("enableExperimentalIndexStatsCmd", po::bool_switch(&cmdLine.experimental.indexStatsCmdEnabled),
"EXPERIMENTAL (UNSUPPORTED). Enable command computing aggregate statistics on indexes.")
@@ -319,6 +320,13 @@ namespace {
if (params.count("objcheck")) {
cmdLine.objcheck = true;
}
+ if (params.count("noobjcheck")) {
+ if (params.count("objcheck")) {
+ out() << "can't have both --objcheck and --noobjcheck" << endl;
+ return false;
+ }
+ cmdLine.objcheck = false;
+ }
if (params.count("bind_ip")) {
// passing in wildcard is the same as default behavior; remove and warn
diff --git a/src/mongo/db/cmdline.h b/src/mongo/db/cmdline.h
index dbb54299e28..bf576fae708 100644
--- a/src/mongo/db/cmdline.h
+++ b/src/mongo/db/cmdline.h
@@ -189,7 +189,7 @@ namespace mongo {
port(DefaultDBPort), rest(false), jsonp(false), indexBuildRetry(true), quiet(false),
noTableScan(false), prealloc(true), preallocj(true), smallfiles(sizeof(int*) == 4),
configsvr(false), quota(false), quotaFiles(8), cpu(false),
- durOptions(0), objcheck(false), oplogSize(0), defaultProfile(0),
+ durOptions(0), objcheck(true), oplogSize(0), defaultProfile(0),
slowMS(100), defaultLocalThresholdMillis(15), pretouch(0), moveParanoia( true ),
syncdelay(60), noUnixSocket(false), doFork(0), socket("/tmp"), maxConns(DEFAULT_MAX_CONN),
logAppend(false), logWithSyslog(false)
diff --git a/src/mongo/db/dbmessage.h b/src/mongo/db/dbmessage.h
index 7b0a802a27f..a582ec1e018 100644
--- a/src/mongo/db/dbmessage.h
+++ b/src/mongo/db/dbmessage.h
@@ -23,6 +23,7 @@
#include "../util/net/message.h"
#include "../client/constants.h"
#include "instance.h"
+#include "mongo/bson/bson_validate.h"
namespace mongo {
@@ -196,14 +197,21 @@ namespace mongo {
nextjsobj += strlen(data) + 1; // skip namespace
massert( 13066 , "Message contains no documents", theEnd > nextjsobj );
}
- massert( 10304 , "Client Error: Remaining data too small for BSON object", theEnd - nextjsobj > 3 );
- BSONObj js(nextjsobj);
- massert( 10305 , "Client Error: Invalid object size", js.objsize() > 3 );
- massert( 10306 , "Client Error: Next object larger than space left in message",
- js.objsize() < ( theEnd - data ) );
- if ( cmdLine.objcheck && !js.valid() ) {
- massert( 10307 , "Client Error: bad object in message", false);
+ massert( 10304,
+ "Client Error: Remaining data too small for BSON object",
+ theEnd - nextjsobj >= 5 );
+
+ if ( cmdLine.objcheck ) {
+ Status status = validateBSON( nextjsobj, theEnd - nextjsobj, NULL );
+ massert( 10307,
+ str::stream() << "Client Error: bad object in message: " << status.reason(),
+ status.isOK() );
}
+
+ BSONObj js(nextjsobj);
+ verify( js.objsize() >= 5 );
+ verify( js.objsize() < ( theEnd - data ) );
+
nextjsobj += js.objsize();
if ( nextjsobj >= theEnd )
nextjsobj = 0;
diff --git a/src/mongo/db/jsobj.cpp b/src/mongo/db/jsobj.cpp
index cd4598cb5bf..a143cc2df1e 100644
--- a/src/mongo/db/jsobj.cpp
+++ b/src/mongo/db/jsobj.cpp
@@ -26,6 +26,7 @@
#include <boost/lexical_cast.hpp>
#include <boost/static_assert.hpp>
+#include "mongo/bson/bson_validate.h"
#include "mongo/bson/oid.h"
#include "mongo/bson/util/atomic_int.h"
#include "mongo/db/jsobjmanipulator.h"
@@ -462,35 +463,12 @@ namespace mongo {
bool BSONObj::valid() const {
int mySize = objsize();
-
- try {
- BSONObjIterator it(*this);
- while( it.moreWithEOO() ) {
- // both throw exception on failure
- BSONElement e = it.next(true);
- if ( e.size() >= mySize )
- return false;
-
- e.validate();
-
- if (e.eoo()) {
- if (it.moreWithEOO())
- return false;
- return true;
- }
- else if (e.isABSONObj()) {
- if(!e.embeddedObject().valid())
- return false;
- }
- else if (e.type() == CodeWScope) {
- if(!e.codeWScopeObject().valid())
- return false;
- }
- }
- }
- catch (...) {
- }
- return false;
+ int otherSize;
+ Status status = validateBSON( objdata(), mySize, &otherSize );
+ if ( ! status.isOK() )
+ return false;
+ verify( mySize == otherSize ); // should be impossible
+ return true;
}
int BSONObj::woCompare(const BSONObj& r, const Ordering &o, bool considerFieldName) const {
diff --git a/src/mongo/tools/tool.cpp b/src/mongo/tools/tool.cpp
index 23f4ccf88c1..90206e8669e 100644
--- a/src/mongo/tools/tool.cpp
+++ b/src/mongo/tools/tool.cpp
@@ -441,13 +441,17 @@ namespace mongo {
add_options()
("objcheck" , "validate object before inserting" )
+ ("noobjcheck" , "validate object before inserting" )
("filter" , po::value<string>() , "filter to apply before inserting" )
;
}
int BSONTool::run() {
- _objcheck = hasParam( "objcheck" );
+ if ( hasParam( "objcheck" ) )
+ _objcheck = true;
+ else if ( hasParam( "noobjcheck" ) )
+ _objcheck = false;
if ( hasParam( "filter" ) )
_matcher.reset( new Matcher( fromjson( getParam( "filter" ) ) ) );
diff --git a/src/mongo/tools/tool.h b/src/mongo/tools/tool.h
index 65765eba940..b91485656f8 100644
--- a/src/mongo/tools/tool.h
+++ b/src/mongo/tools/tool.h
@@ -146,7 +146,7 @@ namespace mongo {
auto_ptr<Matcher> _matcher;
public:
- BSONTool( const char * name , DBAccess access=ALL, bool objcheck = false );
+ BSONTool( const char * name , DBAccess access=ALL, bool objcheck = true );
virtual int doRun() = 0;
virtual void gotObject( const BSONObj& obj ) = 0;