diff options
author | Sara Golemon <sara.golemon@mongodb.com> | 2021-09-30 14:33:25 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-10-05 15:46:53 +0000 |
commit | 07c6bc2544a0b0b30d5b57dece8b3b491802a123 (patch) | |
tree | f24a29736955a935e22505bf024eb1613682c941 | |
parent | d6790e0ebc3a484a83e107536940d11780460d6f (diff) | |
download | mongo-07c6bc2544a0b0b30d5b57dece8b3b491802a123.tar.gz |
SERVER-60342 Clean up OID string handling
-rw-r--r-- | src/mongo/bson/oid.cpp | 28 | ||||
-rw-r--r-- | src/mongo/bson/oid.h | 27 |
2 files changed, 35 insertions, 20 deletions
diff --git a/src/mongo/bson/oid.cpp b/src/mongo/bson/oid.cpp index 37fed3b5831..78850acbba1 100644 --- a/src/mongo/bson/oid.cpp +++ b/src/mongo/bson/oid.cpp @@ -51,6 +51,11 @@ const std::size_t kTimestampOffset = 0; const std::size_t kInstanceUniqueOffset = kTimestampOffset + OID::kTimestampSize; const std::size_t kIncrementOffset = kInstanceUniqueOffset + OID::kInstanceUniqueSize; OID::InstanceUnique _instanceUnique; + +bool isHexit(char c) { + return ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F')); +} + } // namespace MONGO_INITIALIZER_GENERAL(OIDGeneration, (), ("default")) @@ -147,12 +152,29 @@ void OID::initFromTermNumber(int64_t term) { _view().write<BigEndian<int64_t>>(term, kInstanceUniqueOffset); } -void OID::init(const std::string& s) { - verify(s.size() == 24); - std::string blob = hexblob::decode(StringData(s).substr(0, 2 * kOIDSize)); +void OID::init(StringData s) { + verify(s.size() == (2 * kOIDSize)); + std::string blob = hexblob::decode(s.substr(0, 2 * kOIDSize)); std::copy(blob.begin(), blob.end(), _data); } +StatusWith<OID> OID::parse(StringData input) { + if (input.size() != (2 * kOIDSize)) { + return {ErrorCodes::BadValue, + str::stream() << "Invalid string length for parsing to OID, expected " + << (2 * kOIDSize) << " but found " << input.size()}; + } + + for (char c : input) { + if (!isHexit(c)) { + return {ErrorCodes::BadValue, + str::stream() << "Invalid character found in hex string: " << c}; + } + } + + return OID(input); +} + void OID::init(Date_t date, bool max) { setTimestamp(uint32_t(date.toMillisSinceEpoch() / 1000)); uint64_t rest = max ? std::numeric_limits<uint64_t>::max() : 0u; diff --git a/src/mongo/bson/oid.h b/src/mongo/bson/oid.h index 7a5818945f6..afe716e5b17 100644 --- a/src/mongo/bson/oid.h +++ b/src/mongo/bson/oid.h @@ -85,8 +85,8 @@ public: enum { kOIDSize = 12, kTimestampSize = 4, kInstanceUniqueSize = 5, kIncrementSize = 3 }; - /** init from a 24 char hex std::string */ - explicit OID(const std::string& s) { + /** init from a 24 char hex string */ + explicit OID(StringData s) { init(s); } @@ -141,31 +141,24 @@ public: } /** + * This method creates and initializes an OID from a string, + * returning a bad Status on failure. + */ + static StatusWith<OID> parse(StringData input); + + /** * This method creates and initializes an OID from a string, throwing a BadValue exception if * the string is not a valid OID. */ static OID createFromString(StringData input) { - uassert(ErrorCodes::BadValue, - str::stream() << "Invalid string length for parsing to OID, expected 24 but found " - << input.size(), - input.size() == 24); - for (auto digit : input) { - uassert(ErrorCodes::BadValue, - str::stream() << "Invalid character found in hex string: " << digit, - ('0' <= digit && digit <= '9') || ('a' <= digit && digit <= 'f') || - ('A' <= digit && digit <= 'F')); - } - - OID result; - result.init(input.toString()); - return result; + return uassertStatusOK(parse(input)); } /** sets the contents to a new oid / randomized value */ void init(); /** init from a 24 char hex std::string */ - void init(const std::string& s); + void init(StringData s); /** Set to the min/max OID that could be generated at given timestamp. */ void init(Date_t date, bool max = false); |