summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSara Golemon <sara.golemon@mongodb.com>2021-09-30 14:33:25 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-10-05 15:46:53 +0000
commit07c6bc2544a0b0b30d5b57dece8b3b491802a123 (patch)
treef24a29736955a935e22505bf024eb1613682c941
parentd6790e0ebc3a484a83e107536940d11780460d6f (diff)
downloadmongo-07c6bc2544a0b0b30d5b57dece8b3b491802a123.tar.gz
SERVER-60342 Clean up OID string handling
-rw-r--r--src/mongo/bson/oid.cpp28
-rw-r--r--src/mongo/bson/oid.h27
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);