summaryrefslogtreecommitdiff
path: root/src/mongo/bson/bson_validate_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/bson/bson_validate_test.cpp')
-rw-r--r--src/mongo/bson/bson_validate_test.cpp445
1 files changed, 224 insertions, 221 deletions
diff --git a/src/mongo/bson/bson_validate_test.cpp b/src/mongo/bson/bson_validate_test.cpp
index b3965763861..715cddd18c2 100644
--- a/src/mongo/bson/bson_validate_test.cpp
+++ b/src/mongo/bson/bson_validate_test.cpp
@@ -37,274 +37,277 @@
namespace {
- using namespace mongo;
- using std::unique_ptr;
- using std::endl;
-
- void appendInvalidStringElement(const char* fieldName, BufBuilder* bb) {
- // like a BSONObj string, but without a NUL terminator.
- bb->appendChar(String);
- bb->appendStr(fieldName, /*withNUL*/true);
- bb->appendNum(4);
- bb->appendStr("asdf", /*withNUL*/false);
- }
+using namespace mongo;
+using std::unique_ptr;
+using std::endl;
+
+void appendInvalidStringElement(const char* fieldName, BufBuilder* bb) {
+ // like a BSONObj string, but without a NUL terminator.
+ bb->appendChar(String);
+ bb->appendStr(fieldName, /*withNUL*/ true);
+ bb->appendNum(4);
+ bb->appendStr("asdf", /*withNUL*/ false);
+}
- TEST(BSONValidate, Basic) {
- BSONObj x;
- ASSERT_TRUE( x.valid() );
+TEST(BSONValidate, Basic) {
+ BSONObj x;
+ ASSERT_TRUE(x.valid());
- x = BSON( "x" << 1 );
- ASSERT_TRUE( x.valid() );
- }
+ x = BSON("x" << 1);
+ ASSERT_TRUE(x.valid());
+}
- TEST(BSONValidate, RandomData) {
- PseudoRandom r(17);
+TEST(BSONValidate, RandomData) {
+ PseudoRandom r(17);
- int numValid = 0;
- int numToRun = 1000;
- long long jsonSize = 0;
+ int numValid = 0;
+ int numToRun = 1000;
+ long long jsonSize = 0;
- for ( int i=0; i<numToRun; i++ ) {
- int size = 1234;
+ for (int i = 0; i < numToRun; i++) {
+ int size = 1234;
- char* x = new char[size];
- DataView(x).write(tagLittleEndian(size));
+ char* x = new char[size];
+ DataView(x).write(tagLittleEndian(size));
- for ( int i=4; i<size; i++ ) {
- x[i] = r.nextInt32( 255 );
- }
+ for (int i = 4; i < size; i++) {
+ x[i] = r.nextInt32(255);
+ }
- x[size-1] = 0;
+ x[size - 1] = 0;
- BSONObj o( x );
+ BSONObj o(x);
- ASSERT_EQUALS( size, o.objsize() );
+ ASSERT_EQUALS(size, o.objsize());
- if ( o.valid() ) {
- numValid++;
- jsonSize += o.jsonString().size();
- ASSERT_OK( validateBSON( o.objdata(), o.objsize() ) );
- }
- else {
- ASSERT_NOT_OK( validateBSON( o.objdata(), o.objsize() ) );
- }
-
- delete[] x;
+ if (o.valid()) {
+ numValid++;
+ jsonSize += o.jsonString().size();
+ ASSERT_OK(validateBSON(o.objdata(), o.objsize()));
+ } else {
+ ASSERT_NOT_OK(validateBSON(o.objdata(), o.objsize()));
}
- log() << "RandomData: didn't crash valid/total: " << numValid << "/" << numToRun
- << " (want few valid ones)"
- << " jsonSize: " << jsonSize << endl;
+ delete[] x;
}
- TEST(BSONValidate, MuckingData1) {
-
- BSONObj theObject;
+ log() << "RandomData: didn't crash valid/total: " << numValid << "/" << numToRun
+ << " (want few valid ones)"
+ << " jsonSize: " << jsonSize << endl;
+}
- {
- BSONObjBuilder b;
- b.append( "name" , "eliot was here" );
- b.append( "yippee" , "asd" );
- BSONArrayBuilder a( b.subarrayStart( "arr" ) );
- for ( int i=0; i<100; i++ ) {
- a.append( BSON( "x" << i << "who" << "me" << "asd" << "asd" ) );
- }
- a.done();
- b.done();
+TEST(BSONValidate, MuckingData1) {
+ BSONObj theObject;
- theObject = b.obj();
+ {
+ BSONObjBuilder b;
+ b.append("name", "eliot was here");
+ b.append("yippee", "asd");
+ BSONArrayBuilder a(b.subarrayStart("arr"));
+ for (int i = 0; i < 100; i++) {
+ a.append(BSON("x" << i << "who"
+ << "me"
+ << "asd"
+ << "asd"));
}
+ a.done();
+ b.done();
- int numValid = 0;
- int numToRun = 1000;
- long long jsonSize = 0;
+ theObject = b.obj();
+ }
- for ( int i=4; i<theObject.objsize()-1; i++ ) {
- BSONObj mine = theObject.copy();
+ int numValid = 0;
+ int numToRun = 1000;
+ long long jsonSize = 0;
- char* data = const_cast<char*>(mine.objdata());
+ for (int i = 4; i < theObject.objsize() - 1; i++) {
+ BSONObj mine = theObject.copy();
- data[ i ] = 200;
+ char* data = const_cast<char*>(mine.objdata());
- numToRun++;
- if ( mine.valid() ) {
- numValid++;
- jsonSize += mine.jsonString().size();
- ASSERT_OK( validateBSON( mine.objdata(), mine.objsize() ) );
- }
- else {
- ASSERT_NOT_OK( validateBSON( mine.objdata(), mine.objsize() ) );
- }
+ data[i] = 200;
+ numToRun++;
+ if (mine.valid()) {
+ numValid++;
+ jsonSize += mine.jsonString().size();
+ ASSERT_OK(validateBSON(mine.objdata(), mine.objsize()));
+ } else {
+ ASSERT_NOT_OK(validateBSON(mine.objdata(), mine.objsize()));
}
-
- log() << "MuckingData1: didn't crash valid/total: " << numValid << "/" << numToRun
- << " (want few valid ones) "
- << " jsonSize: " << jsonSize << endl;
}
- TEST( BSONValidate, Fuzz ) {
- int64_t seed = time( 0 );
- log() << "BSONValidate Fuzz random seed: " << seed << endl;
- PseudoRandom randomSource( seed );
-
- BSONObj original = BSON( "one" << 3 <<
- "two" << 5 <<
- "three" << BSONObj() <<
- "four" << BSON( "five" << BSON( "six" << 11 ) ) <<
- "seven" << BSON_ARRAY( "a" << "bb" << "ccc" << 5 ) <<
- "eight" << BSONDBRef( "rrr", OID( "01234567890123456789aaaa" ) ) <<
- "_id" << OID( "deadbeefdeadbeefdeadbeef" ) <<
- "nine" << BSONBinData( "\x69\xb7", 2, BinDataGeneral ) <<
- "ten" << Date_t::fromMillisSinceEpoch( 44 ) <<
- "eleven" << BSONRegEx( "foooooo", "i" ) );
-
- int32_t fuzzFrequencies[] = { 2, 10, 20, 100, 1000 };
- for( size_t i = 0; i < sizeof( fuzzFrequencies ) / sizeof( int32_t ); ++i ) {
- int32_t fuzzFrequency = fuzzFrequencies[ i ];
-
- // Copy the 'original' BSONObj to 'buffer'.
- unique_ptr<char[]> buffer( new char[ original.objsize() ] );
- memcpy( buffer.get(), original.objdata(), original.objsize() );
-
- // Randomly flip bits in 'buffer', with probability determined by 'fuzzFrequency'. The
- // first four bytes, representing the size of the object, are excluded from bit
- // flipping.
- for( int32_t byteIdx = 4; byteIdx < original.objsize(); ++byteIdx ) {
- for( int32_t bitIdx = 0; bitIdx < 8; ++bitIdx ) {
- if ( randomSource.nextInt32( fuzzFrequency ) == 0 ) {
- reinterpret_cast<unsigned char&>( buffer[ byteIdx ] ) ^= ( 1U << bitIdx );
- }
+ log() << "MuckingData1: didn't crash valid/total: " << numValid << "/" << numToRun
+ << " (want few valid ones) "
+ << " jsonSize: " << jsonSize << endl;
+}
+
+TEST(BSONValidate, Fuzz) {
+ int64_t seed = time(0);
+ log() << "BSONValidate Fuzz random seed: " << seed << endl;
+ PseudoRandom randomSource(seed);
+
+ BSONObj original =
+ BSON("one" << 3 << "two" << 5 << "three" << BSONObj() << "four"
+ << BSON("five" << BSON("six" << 11)) << "seven" << BSON_ARRAY("a"
+ << "bb"
+ << "ccc" << 5)
+ << "eight" << BSONDBRef("rrr", OID("01234567890123456789aaaa")) << "_id"
+ << OID("deadbeefdeadbeefdeadbeef") << "nine"
+ << BSONBinData("\x69\xb7", 2, BinDataGeneral) << "ten"
+ << Date_t::fromMillisSinceEpoch(44) << "eleven" << BSONRegEx("foooooo", "i"));
+
+ int32_t fuzzFrequencies[] = {2, 10, 20, 100, 1000};
+ for (size_t i = 0; i < sizeof(fuzzFrequencies) / sizeof(int32_t); ++i) {
+ int32_t fuzzFrequency = fuzzFrequencies[i];
+
+ // Copy the 'original' BSONObj to 'buffer'.
+ unique_ptr<char[]> buffer(new char[original.objsize()]);
+ memcpy(buffer.get(), original.objdata(), original.objsize());
+
+ // Randomly flip bits in 'buffer', with probability determined by 'fuzzFrequency'. The
+ // first four bytes, representing the size of the object, are excluded from bit
+ // flipping.
+ for (int32_t byteIdx = 4; byteIdx < original.objsize(); ++byteIdx) {
+ for (int32_t bitIdx = 0; bitIdx < 8; ++bitIdx) {
+ if (randomSource.nextInt32(fuzzFrequency) == 0) {
+ reinterpret_cast<unsigned char&>(buffer[byteIdx]) ^= (1U << bitIdx);
}
}
- BSONObj fuzzed( buffer.get() );
-
- // Check that the two validation implementations agree (and neither crashes).
- ASSERT_EQUALS( fuzzed.valid(),
- validateBSON( fuzzed.objdata(), fuzzed.objsize() ).isOK() );
}
- }
-
- TEST( BSONValidateFast, Empty ) {
- BSONObj x;
- ASSERT_OK( validateBSON( x.objdata(), x.objsize() ) );
- }
+ BSONObj fuzzed(buffer.get());
- TEST( BSONValidateFast, RegEx ) {
- BSONObjBuilder b;
- b.appendRegex( "foo", "i" );
- BSONObj x = b.obj();
- ASSERT_OK( validateBSON( x.objdata(), x.objsize() ) );
+ // Check that the two validation implementations agree (and neither crashes).
+ ASSERT_EQUALS(fuzzed.valid(), validateBSON(fuzzed.objdata(), fuzzed.objsize()).isOK());
}
+}
- TEST(BSONValidateFast, Simple0 ) {
- BSONObj x;
- ASSERT_OK( validateBSON( x.objdata(), x.objsize() ) );
-
- x = BSON( "foo" << 17 << "bar" << "eliot" );
- ASSERT_OK( validateBSON( x.objdata(), x.objsize() ) );
+TEST(BSONValidateFast, Empty) {
+ BSONObj x;
+ ASSERT_OK(validateBSON(x.objdata(), x.objsize()));
+}
- }
+TEST(BSONValidateFast, RegEx) {
+ BSONObjBuilder b;
+ b.appendRegex("foo", "i");
+ BSONObj x = b.obj();
+ ASSERT_OK(validateBSON(x.objdata(), x.objsize()));
+}
- TEST(BSONValidateFast, Simple2 ) {
- char buf[64];
- for ( int i=1; i<=JSTypeMax; i++ ) {
- BSONObjBuilder b;
- sprintf( buf, "foo%d", i );
- b.appendMinForType( buf, i );
- sprintf( buf, "bar%d", i );
- b.appendMaxForType( buf, i );
- BSONObj x = b.obj();
- ASSERT_OK( validateBSON( x.objdata(), x.objsize() ) );
- }
- }
+TEST(BSONValidateFast, Simple0) {
+ BSONObj x;
+ ASSERT_OK(validateBSON(x.objdata(), x.objsize()));
+ x = BSON("foo" << 17 << "bar"
+ << "eliot");
+ ASSERT_OK(validateBSON(x.objdata(), x.objsize()));
+}
- TEST(BSONValidateFast, Simple3 ) {
+TEST(BSONValidateFast, Simple2) {
+ char buf[64];
+ for (int i = 1; i <= JSTypeMax; i++) {
BSONObjBuilder b;
- char buf[64];
- for ( int i=1; i<=JSTypeMax; i++ ) {
- sprintf( buf, "foo%d", i );
- b.appendMinForType( buf, i );
- sprintf( buf, "bar%d", i );
- b.appendMaxForType( buf, i );
- }
+ sprintf(buf, "foo%d", i);
+ b.appendMinForType(buf, i);
+ sprintf(buf, "bar%d", i);
+ b.appendMaxForType(buf, i);
BSONObj x = b.obj();
- ASSERT_OK( validateBSON( x.objdata(), x.objsize() ) );
- }
-
- TEST(BSONValidateFast, NestedObject) {
- BSONObj x = BSON( "a" << 1 << "b" << BSON("c" << 2 << "d" << BSONArrayBuilder().obj() << "e" << BSON_ARRAY("1" << 2 << 3)));
ASSERT_OK(validateBSON(x.objdata(), x.objsize()));
- ASSERT_NOT_OK(validateBSON(x.objdata(), x.objsize() / 2));
}
+}
- TEST(BSONValidateFast, ErrorWithId) {
- BufBuilder bb;
- BSONObjBuilder ob(bb);
- ob.append("_id", 1);
- appendInvalidStringElement("not_id", &bb);
- const BSONObj x = ob.done();
- const Status status = validateBSON(x.objdata(), x.objsize());
- ASSERT_NOT_OK(status);
- ASSERT_EQUALS(status.reason(), "not null terminated string in object with _id: 1");
- }
- TEST(BSONValidateFast, ErrorBeforeId) {
- BufBuilder bb;
- BSONObjBuilder ob(bb);
- appendInvalidStringElement("not_id", &bb);
- ob.append("_id", 1);
- const BSONObj x = ob.done();
- const Status status = validateBSON(x.objdata(), x.objsize());
- ASSERT_NOT_OK(status);
- ASSERT_EQUALS(status.reason(), "not null terminated string in object with unknown _id");
+TEST(BSONValidateFast, Simple3) {
+ BSONObjBuilder b;
+ char buf[64];
+ for (int i = 1; i <= JSTypeMax; i++) {
+ sprintf(buf, "foo%d", i);
+ b.appendMinForType(buf, i);
+ sprintf(buf, "bar%d", i);
+ b.appendMaxForType(buf, i);
}
+ BSONObj x = b.obj();
+ ASSERT_OK(validateBSON(x.objdata(), x.objsize()));
+}
- TEST(BSONValidateFast, ErrorNoId) {
- BufBuilder bb;
- BSONObjBuilder ob(bb);
- appendInvalidStringElement("not_id", &bb);
- const BSONObj x = ob.done();
- const Status status = validateBSON(x.objdata(), x.objsize());
- ASSERT_NOT_OK(status);
- ASSERT_EQUALS(status.reason(), "not null terminated string in object with unknown _id");
- }
+TEST(BSONValidateFast, NestedObject) {
+ BSONObj x = BSON("a" << 1 << "b" << BSON("c" << 2 << "d" << BSONArrayBuilder().obj() << "e"
+ << BSON_ARRAY("1" << 2 << 3)));
+ ASSERT_OK(validateBSON(x.objdata(), x.objsize()));
+ ASSERT_NOT_OK(validateBSON(x.objdata(), x.objsize() / 2));
+}
- TEST(BSONValidateFast, ErrorIsInId) {
- BufBuilder bb;
- BSONObjBuilder ob(bb);
- appendInvalidStringElement("_id", &bb);
- const BSONObj x = ob.done();
- const Status status = validateBSON(x.objdata(), x.objsize());
- ASSERT_NOT_OK(status);
- ASSERT_EQUALS(status.reason(), "not null terminated string in object with unknown _id");
- }
+TEST(BSONValidateFast, ErrorWithId) {
+ BufBuilder bb;
+ BSONObjBuilder ob(bb);
+ ob.append("_id", 1);
+ appendInvalidStringElement("not_id", &bb);
+ const BSONObj x = ob.done();
+ const Status status = validateBSON(x.objdata(), x.objsize());
+ ASSERT_NOT_OK(status);
+ ASSERT_EQUALS(status.reason(), "not null terminated string in object with _id: 1");
+}
- TEST(BSONValidateFast, NonTopLevelId) {
- BufBuilder bb;
- BSONObjBuilder ob(bb);
- ob.append("not_id1", BSON("_id" << "not the real _id"));
- appendInvalidStringElement("not_id2", &bb);
- const BSONObj x = ob.done();
- const Status status = validateBSON(x.objdata(), x.objsize());
- ASSERT_NOT_OK(status);
- ASSERT_EQUALS(status.reason(), "not null terminated string in object with unknown _id");
- }
+TEST(BSONValidateFast, ErrorBeforeId) {
+ BufBuilder bb;
+ BSONObjBuilder ob(bb);
+ appendInvalidStringElement("not_id", &bb);
+ ob.append("_id", 1);
+ const BSONObj x = ob.done();
+ const Status status = validateBSON(x.objdata(), x.objsize());
+ ASSERT_NOT_OK(status);
+ ASSERT_EQUALS(status.reason(), "not null terminated string in object with unknown _id");
+}
- TEST(BSONValidateFast, StringHasSomething) {
- BufBuilder bb;
- BSONObjBuilder ob(bb);
- bb.appendChar(String);
- bb.appendStr("x", /*withNUL*/true);
- bb.appendNum(0);
- const BSONObj x = ob.done();
- ASSERT_EQUALS(5 // overhead
- + 1 // type
- + 2 // name
- + 4 // size
- , x.objsize());
- ASSERT_NOT_OK(validateBSON(x.objdata(), x.objsize()));
- }
+TEST(BSONValidateFast, ErrorNoId) {
+ BufBuilder bb;
+ BSONObjBuilder ob(bb);
+ appendInvalidStringElement("not_id", &bb);
+ const BSONObj x = ob.done();
+ const Status status = validateBSON(x.objdata(), x.objsize());
+ ASSERT_NOT_OK(status);
+ ASSERT_EQUALS(status.reason(), "not null terminated string in object with unknown _id");
+}
+
+TEST(BSONValidateFast, ErrorIsInId) {
+ BufBuilder bb;
+ BSONObjBuilder ob(bb);
+ appendInvalidStringElement("_id", &bb);
+ const BSONObj x = ob.done();
+ const Status status = validateBSON(x.objdata(), x.objsize());
+ ASSERT_NOT_OK(status);
+ ASSERT_EQUALS(status.reason(), "not null terminated string in object with unknown _id");
+}
+TEST(BSONValidateFast, NonTopLevelId) {
+ BufBuilder bb;
+ BSONObjBuilder ob(bb);
+ ob.append("not_id1",
+ BSON("_id"
+ << "not the real _id"));
+ appendInvalidStringElement("not_id2", &bb);
+ const BSONObj x = ob.done();
+ const Status status = validateBSON(x.objdata(), x.objsize());
+ ASSERT_NOT_OK(status);
+ ASSERT_EQUALS(status.reason(), "not null terminated string in object with unknown _id");
+}
+
+TEST(BSONValidateFast, StringHasSomething) {
+ BufBuilder bb;
+ BSONObjBuilder ob(bb);
+ bb.appendChar(String);
+ bb.appendStr("x", /*withNUL*/ true);
+ bb.appendNum(0);
+ const BSONObj x = ob.done();
+ ASSERT_EQUALS(5 // overhead
+ +
+ 1 // type
+ +
+ 2 // name
+ +
+ 4 // size
+ ,
+ x.objsize());
+ ASSERT_NOT_OK(validateBSON(x.objdata(), x.objsize()));
+}
}