diff options
author | Aaron <aaron@10gen.com> | 2012-07-26 00:04:46 -0700 |
---|---|---|
committer | Aaron <aaron@10gen.com> | 2012-07-26 13:57:44 -0700 |
commit | 6580d32cc4d0792034e470e851a09ade5fd252a9 (patch) | |
tree | e5f605fa7aa57fffd02b80a5d670d615408d9d86 /src/mongo/db/pipeline/field_path.cpp | |
parent | 8e6189095eaa2fd517481f3b1c7b757b8dcbe0ad (diff) | |
download | mongo-6580d32cc4d0792034e470e851a09ade5fd252a9.tar.gz |
SERVER-6592 Improve FieldPath's validation and simplify its invariants.
Diffstat (limited to 'src/mongo/db/pipeline/field_path.cpp')
-rw-r--r--[-rwxr-xr-x] | src/mongo/db/pipeline/field_path.cpp | 61 |
1 files changed, 30 insertions, 31 deletions
diff --git a/src/mongo/db/pipeline/field_path.cpp b/src/mongo/db/pipeline/field_path.cpp index b0a2b0d364b..a21010bb95c 100755..100644 --- a/src/mongo/db/pipeline/field_path.cpp +++ b/src/mongo/db/pipeline/field_path.cpp @@ -24,19 +24,16 @@ namespace mongo { const char FieldPath::prefix[] = "$"; - FieldPath::~FieldPath() { - } - - FieldPath::FieldPath(): - vFieldName() { - } - - FieldPath::FieldPath(const vector<string>& fieldPath): - vFieldName(fieldPath) { + FieldPath::FieldPath(const vector<string>& fieldPath) { + massert(16409, "FieldPath cannot be constructed from an empty vector.", !fieldPath.empty()); + vFieldName.reserve(fieldPath.size()); + for(vector<string>::const_iterator i = fieldPath.begin(); i != fieldPath.end(); ++i) { + pushFieldName(*i); + } + verify(getPathLength() > 0); } - FieldPath::FieldPath(const string &fieldPath): - vFieldName() { + FieldPath::FieldPath(const string& fieldPath) { /* The field path could be using dot notation. Break the field path up by peeling off successive pieces. @@ -48,22 +45,20 @@ namespace mongo { /* if there are no more dots, use the remainder of the string */ if (dotpos == fieldPath.npos) { - vFieldName.push_back(fieldPath.substr(startpos, dotpos)); + string lastFieldName = fieldPath.substr(startpos, dotpos); + pushFieldName(lastFieldName); break; } /* use the string up to the dot */ const size_t length = dotpos - startpos; - uassert(15998, str::stream() << - "field names cannot be zero length (in path \"" << - fieldPath << "\")", - length > 0); - - vFieldName.push_back(fieldPath.substr(startpos, length)); + string nextFieldName = fieldPath.substr(startpos, length); + pushFieldName(nextFieldName); /* next time, search starting one spot after that */ startpos = dotpos + 1; } + verify(getPathLength() > 0); } string FieldPath::getPath(bool fieldPrefix) const { @@ -76,27 +71,31 @@ namespace mongo { if (fieldPrefix) outStream << prefix; - outStream << vFieldName[0]; const size_t n = vFieldName.size(); + + verify(n > 0); + outStream << vFieldName[0]; for(size_t i = 1; i < n; ++i) outStream << '.' << vFieldName[i]; } - FieldPath &FieldPath::operator=(const FieldPath &rRHS) { - if (this != &rRHS) { - vFieldName = rRHS.vFieldName; - } - - return *this; + FieldPath FieldPath::tail() const { + vector<string> allButFirst(vFieldName.begin()+1, vFieldName.end()); + return FieldPath(allButFirst); } - FieldPath FieldPath::tail() const { - verify(!vFieldName.empty()); + void FieldPath::uassertValidFieldName(const string& fieldName) { + uassert(15998, "FieldPath field names may not be empty strings.", fieldName.length() > 0); + uassert(16410, "FieldPath field names may not start with '$'.", fieldName[0] != '$'); + uassert(16411, "FieldPath field names may not contain '\0'.", + fieldName.find('\0') == string::npos); + uassert(16412, "FieldPath field names may not contain '.'.", + !str::contains(fieldName, '.')); + } - FieldPath out; - vector<string> allButFirst(vFieldName.begin()+1, vFieldName.end()); - out.vFieldName.swap(allButFirst); - return out; + void FieldPath::pushFieldName(const string& fieldName) { + uassertValidFieldName(fieldName); + vFieldName.push_back(fieldName); } } |