summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/field_parser.cpp3
-rw-r--r--src/mongo/db/field_parser_test.cpp19
-rw-r--r--src/mongo/db/namespace_string-inl.h15
-rw-r--r--src/mongo/db/namespace_string_test.cpp2
4 files changed, 36 insertions, 3 deletions
diff --git a/src/mongo/db/field_parser.cpp b/src/mongo/db/field_parser.cpp
index 7a3a61b3203..3d300db2ead 100644
--- a/src/mongo/db/field_parser.cpp
+++ b/src/mongo/db/field_parser.cpp
@@ -150,7 +150,8 @@ namespace mongo {
}
if (elem.type() == String) {
- *out = elem.valuestr();
+ // Extract everything, including embedded null characters.
+ *out = string(elem.valuestr(), elem.valuestrsize() - 1);
return FIELD_SET;
}
diff --git a/src/mongo/db/field_parser_test.cpp b/src/mongo/db/field_parser_test.cpp
index 1a458c3960e..9e3f974c915 100644
--- a/src/mongo/db/field_parser_test.cpp
+++ b/src/mongo/db/field_parser_test.cpp
@@ -422,4 +422,23 @@ namespace {
ASSERT_NOT_EQUALS(errMsg, "");
}
+ TEST(EdgeCases, EmbeddedNullStrings) {
+
+ // Test extraction of string values with embedded nulls.
+ BSONField<string> field("testStr");
+
+ const char* str = "a\0c";
+ const size_t strSize = 4;
+ BSONObjBuilder doc;
+ doc.append(field(), str, strSize);
+ BSONObj obj(doc.obj());
+
+ string parsed;
+ string errMsg;
+ ASSERT(FieldParser::extract(obj, field, &parsed, &errMsg));
+
+ ASSERT_EQUALS(0, memcmp(parsed.data(), str, strSize));
+ ASSERT_EQUALS(errMsg, "");
+ }
+
} // unnamed namespace
diff --git a/src/mongo/db/namespace_string-inl.h b/src/mongo/db/namespace_string-inl.h
index 5a03f6d9930..597d9a93159 100644
--- a/src/mongo/db/namespace_string-inl.h
+++ b/src/mongo/db/namespace_string-inl.h
@@ -99,8 +99,18 @@ namespace mongo {
if (coll.empty())
return false;
- return coll.find('$') == std::string::npos;
+ for (StringData::const_iterator iter = coll.begin(), end = coll.end();
+ iter != end; ++iter) {
+ switch (*iter) {
+ case '\0':
+ case '$':
+ return false;
+ default:
+ continue;
+ }
+ }
+ return true;
}
inline NamespaceString::NamespaceString() : _ns(), _dotIndex(0) {}
@@ -126,7 +136,8 @@ namespace mongo {
_dotIndex = dbName.size();
dassert(it == _ns.end());
dassert(_ns[_dotIndex] == '.');
- dassert(_ns.find('\0') == std::string::npos);
+ uassert(17295, "namespaces cannot have embedded null characters",
+ _ns.find('\0') == std::string::npos);
}
inline int nsDBHash( const std::string& ns ) {
diff --git a/src/mongo/db/namespace_string_test.cpp b/src/mongo/db/namespace_string_test.cpp
index 74a65b6d70a..e3d6ebf8e36 100644
--- a/src/mongo/db/namespace_string_test.cpp
+++ b/src/mongo/db/namespace_string_test.cpp
@@ -59,6 +59,7 @@ namespace mongo {
ASSERT( !NamespaceString::validDBName( "foo.bar" ) );
ASSERT( !NamespaceString::validDBName( "foo\\bar" ) );
ASSERT( !NamespaceString::validDBName( "foo\"bar" ) );
+ ASSERT( !NamespaceString::validDBName( StringData( "a\0", 4 ) ) );
#ifdef _WIN32
ASSERT( !NamespaceString::validDBName( "foo*bar" ) );
ASSERT( !NamespaceString::validDBName( "foo<bar" ) );
@@ -88,6 +89,7 @@ namespace mongo {
ASSERT( !NamespaceString::validCollectionName( "$a" ) );
ASSERT( !NamespaceString::validCollectionName( "a$b" ) );
ASSERT( !NamespaceString::validCollectionName( "" ) );
+ ASSERT( !NamespaceString::validCollectionName( StringData( "a\0", 4 ) ) );
}
TEST( NamespaceStringTest, DBHash ) {