summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Kneiser <matt.kneiser@mongodb.com>2022-01-13 00:22:12 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-01-13 06:29:13 +0000
commitfd6b2a875f8942a4ba7fea916b4c52a913e14f49 (patch)
tree8e18dd580f8d03a42f27ed7af357cae38a2ff745
parent47c77eedf3bb0b4305f2ca1d8e362b27d599008f (diff)
downloadmongo-fd6b2a875f8942a4ba7fea916b4c52a913e14f49.tar.gz
SERVER-27209 Eliminate dangerous BSONElement string extraction methods
- Fix: Change return type of BSONObj::getStringField to include size (StringData vs. char*). A char* only contains the data with an ending NULL termination. Whereas a StringData contains data + size so caller knows how to interpret data if there are embedded NULLs. - Cleanup: Remove old tag - CachedSizeTag - that disambiguated BSONElement ctors. A dangling reference to 'maxLen' in a comment led me to this historical issue. $ git log -S'maxLen' -- src/mongo/bson/bsonelement.h commit 0d38ef5 Author: Mathias Stearn mathias@10gen.com Date: Tue Dec 19 14:23:08 2017 -0500 SERVER-32302 Compute BSONElement sizes eagerly - Test: Add tests for NULL bytes being returned by getStringField - $ ninja -j400 +bson_obj_test - Cleanup: Move BSONElement::valuestr() from public to private - Cleanup: Remove BSONElement::valuestrsafe() - Cleanup: Remove all external callers of valuestr/valuestrsafe and cleanup their callsites with better alternatives. - Cleanup: Make multi-line BSONElement & BSONObj public API comments conform to style guidelines - Nit: Fix spelling in a comment
-rw-r--r--src/mongo/bson/bson_obj_test.cpp39
-rw-r--r--src/mongo/bson/bson_validate.cpp3
-rw-r--r--src/mongo/bson/bsonelement.cpp24
-rw-r--r--src/mongo/bson/bsonelement.h320
-rw-r--r--src/mongo/bson/bsonobj.cpp4
-rw-r--r--src/mongo/bson/bsonobj.h261
-rw-r--r--src/mongo/bson/mutable/document.cpp3
-rw-r--r--src/mongo/bson/mutable/element.h5
-rw-r--r--src/mongo/bson/util/bsoncolumn.cpp7
-rw-r--r--src/mongo/bson/util/bsoncolumnbuilder.cpp2
-rw-r--r--src/mongo/client/authenticate.cpp2
-rw-r--r--src/mongo/client/dbclient_base.cpp3
-rw-r--r--src/mongo/client/replica_set_monitor_integration_test.cpp2
-rw-r--r--src/mongo/client/sdam/sdam_json_test_runner.cpp2
-rw-r--r--src/mongo/client/sdam/server_description.cpp2
-rw-r--r--src/mongo/client/sdam/server_selection_json_test_runner.cpp6
-rw-r--r--src/mongo/db/auth/authorization_manager_impl.cpp4
-rw-r--r--src/mongo/db/catalog/commit_quorum_options.cpp2
-rw-r--r--src/mongo/db/catalog/index_build_block.cpp2
-rw-r--r--src/mongo/db/catalog/index_catalog_impl.cpp2
-rw-r--r--src/mongo/db/catalog/index_key_validate.cpp5
-rw-r--r--src/mongo/db/commands/distinct.cpp2
-rw-r--r--src/mongo/db/commands/oplog_application_checks.cpp6
-rw-r--r--src/mongo/db/commands/parameters.cpp2
-rw-r--r--src/mongo/db/exec/sbe/stages/makeobj.cpp3
-rw-r--r--src/mongo/db/field_parser.cpp2
-rw-r--r--src/mongo/db/fts/fts_element_iterator.cpp3
-rw-r--r--src/mongo/db/fts/fts_index_format_test.cpp4
-rw-r--r--src/mongo/db/fts/fts_spec.cpp6
-rw-r--r--src/mongo/db/fts/fts_spec_legacy.cpp10
-rw-r--r--src/mongo/db/global_settings.cpp2
-rw-r--r--src/mongo/db/index/expression_keys_private.cpp4
-rw-r--r--src/mongo/db/index/expression_params.cpp2
-rw-r--r--src/mongo/db/index/index_build_interceptor.cpp5
-rw-r--r--src/mongo/db/index_builds_coordinator.cpp10
-rw-r--r--src/mongo/db/matcher/expression_leaf.cpp3
-rw-r--r--src/mongo/db/operation_context.cpp2
-rw-r--r--src/mongo/db/pipeline/expression.cpp2
-rw-r--r--src/mongo/db/query/query_request_helper.cpp2
-rw-r--r--src/mongo/db/repl/apply_ops.cpp2
-rw-r--r--src/mongo/db/repl/apply_ops_command_info.cpp2
-rw-r--r--src/mongo/db/repl/collection_cloner.cpp3
-rw-r--r--src/mongo/db/repl/repl_set_commands.cpp2
-rw-r--r--src/mongo/db/repl/rollback_impl.cpp2
-rw-r--r--src/mongo/db/repl/rs_rollback.cpp6
-rw-r--r--src/mongo/db/repl_index_build_state.cpp2
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager_shard_operations.cpp2
-rw-r--r--src/mongo/db/storage/bson_collection_catalog_entry.cpp2
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_sorted_impl.cpp2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp2
-rw-r--r--src/mongo/db/timeseries/bucket_catalog.cpp3
-rw-r--r--src/mongo/db/timeseries/flat_bson.cpp2
-rw-r--r--src/mongo/db/write_concern_options.cpp2
-rw-r--r--src/mongo/dbtests/commandtests.cpp4
-rw-r--r--src/mongo/dbtests/jsobjtests.cpp7
-rw-r--r--src/mongo/dbtests/jsontests.cpp2
-rw-r--r--src/mongo/dbtests/jstests.cpp8
-rw-r--r--src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp2
-rw-r--r--src/mongo/idl/basic_types.h2
-rw-r--r--src/mongo/rpc/op_msg_integration_test.cpp2
-rw-r--r--src/mongo/s/request_types/add_shard_request_type.cpp2
-rw-r--r--src/mongo/s/transaction_router_test.cpp8
-rw-r--r--src/mongo/scripting/engine.cpp8
-rw-r--r--src/mongo/scripting/utils.cpp4
-rw-r--r--src/mongo/shell/shell_utils.cpp6
-rw-r--r--src/mongo/shell/shell_utils_extended.cpp16
-rw-r--r--src/mongo/shell/shell_utils_launcher.cpp10
-rw-r--r--src/mongo/util/fail_point.cpp2
68 files changed, 535 insertions, 352 deletions
diff --git a/src/mongo/bson/bson_obj_test.cpp b/src/mongo/bson/bson_obj_test.cpp
index f9581d03c80..049fab19d52 100644
--- a/src/mongo/bson/bson_obj_test.cpp
+++ b/src/mongo/bson/bson_obj_test.cpp
@@ -764,4 +764,43 @@ TEST(BSONObj, sizeChecks) {
ErrorCodes::BSONObjectTooLarge);
}
+TEST(BSONObj, nullByteInStringBasic) {
+ const size_t size = 3;
+ StringData str("b\0c", size);
+
+ // { "a": "b\0c" }
+ BSONObjBuilder b;
+ b.append("a"_sd, str);
+ BSONObj obj{b.obj()};
+
+ ASSERT_EQ(str.size(), obj.getStringField("a").size());
+ ASSERT_EQ(str, obj.getStringField("a"));
+}
+
+TEST(BSONObj, nullByteInStringMulti) {
+ const size_t size = 5;
+ StringData str("b\0c\0d", size);
+
+ // { "a": "b\0c\0d" }
+ BSONObjBuilder b;
+ b.append("a"_sd, str);
+ BSONObj obj{b.obj()};
+
+ ASSERT_EQ(str.size(), obj.getStringField("a").size());
+ ASSERT_EQ(str, obj.getStringField("a"));
+}
+
+TEST(BSONObj, nullByteInStringFull) {
+ const size_t size = 9;
+ StringData str("\0\0\0\0\0\0\0\0\0", size);
+
+ // { "a": "\0\0\0\0\0\0\0\0\0" }
+ BSONObjBuilder b;
+ b.append("a"_sd, str);
+ BSONObj obj{b.obj()};
+
+ ASSERT_EQ(str.size(), obj.getStringField("a").size());
+ ASSERT_EQ(str, obj.getStringField("a"));
+}
+
} // unnamed namespace
diff --git a/src/mongo/bson/bson_validate.cpp b/src/mongo/bson/bson_validate.cpp
index e37d09cba20..08659efecd1 100644
--- a/src/mongo/bson/bson_validate.cpp
+++ b/src/mongo/bson/bson_validate.cpp
@@ -171,8 +171,7 @@ private:
if constexpr (precise) {
auto nameLen = obj - _currElem;
- _currFrame->elem =
- BSONElement(_currElem, nameLen, nameLen + len, BSONElement::CachedSizeTag());
+ _currFrame->elem = BSONElement(_currElem, nameLen, nameLen + len);
}
return cursor.ptr;
}
diff --git a/src/mongo/bson/bsonelement.cpp b/src/mongo/bson/bsonelement.cpp
index e02dfd07f33..c6cf2437be2 100644
--- a/src/mongo/bson/bsonelement.cpp
+++ b/src/mongo/bson/bsonelement.cpp
@@ -132,10 +132,10 @@ BSONObj BSONElement::_jsonStringGenerator(const Generator& g,
switch (type()) {
case mongo::String:
- g.writeString(buffer, StringData(valuestr(), valuestrsize() - 1));
+ g.writeString(buffer, valueStringData());
break;
case Symbol:
- g.writeSymbol(buffer, StringData(valuestr(), valuestrsize() - 1));
+ g.writeSymbol(buffer, valueStringData());
break;
case NumberLong:
g.writeInt64(buffer, _numberLong());
@@ -182,9 +182,7 @@ BSONObj BSONElement::_jsonStringGenerator(const Generator& g,
}
case DBRef:
// valuestrsize() returns the size including the null terminator
- g.writeDBRef(buffer,
- StringData(valuestr(), valuestrsize() - 1),
- OID::from(valuestr() + valuestrsize()));
+ g.writeDBRef(buffer, valueStringData(), OID::from(valuestr() + valuestrsize()));
break;
case jstOID:
g.writeOID(buffer, __oid());
@@ -273,15 +271,7 @@ namespace {
// Compares two string elements using a simple binary compare.
int compareElementStringValues(const BSONElement& leftStr, const BSONElement& rightStr) {
- // we use memcmp as we allow zeros in UTF8 strings
- int lsz = leftStr.valuestrsize();
- int rsz = rightStr.valuestrsize();
- int common = std::min(lsz, rsz);
- int res = memcmp(leftStr.valuestr(), rightStr.valuestr(), common);
- if (res)
- return res;
- // longer std::string is the greater one
- return lsz - rsz;
+ return leftStr.valueStringData().compare(rightStr.valueStringData());
}
} // namespace
@@ -650,8 +640,8 @@ BSONElement BSONElement::operator[](StringData field) const {
namespace {
MONGO_COMPILER_NOINLINE void msgAssertedBadType [[noreturn]] (const char* data) {
// We intentionally read memory that may be out of the allocated memory's boundary, so do not
- // do this when the adress sanitizer is enabled. We do this in an attempt to log as much context
- // about the failure, even if that risks undefined behavior or a segmentation fault.
+ // do this when the address sanitizer is enabled. We do this in an attempt to log as much
+ // context about the failure, even if that risks undefined behavior or a segmentation fault.
#if !__has_feature(address_sanitizer)
bool logMemory = true;
#else
@@ -908,7 +898,7 @@ std::string BSONElement::_asCode() const {
switch (type()) {
case mongo::String:
case Code:
- return std::string(valuestr(), valuestrsize() - 1);
+ return valueStringData().toString();
case CodeWScope:
return std::string(codeWScopeCode(),
ConstDataView(valuestr()).read<LittleEndian<int>>() - 1);
diff --git a/src/mongo/bson/bsonelement.h b/src/mongo/bson/bsonelement.h
index c99623c7e80..722ea0937b3 100644
--- a/src/mongo/bson/bsonelement.h
+++ b/src/mongo/bson/bsonelement.h
@@ -62,7 +62,8 @@ typedef BSONElement be;
typedef BSONObj bo;
typedef BSONObjBuilder bob;
-/** BSONElement represents an "element" in a BSONObj. So for the object { a : 3, b : "abc" },
+/**
+ BSONElement represents an "element" in a BSONObj. So for the object { a : 3, b : "abc" },
'a : 3' is the first element (key+value).
The BSONElement object points into the BSONObj's data. Thus the BSONObj must stay in scope
@@ -105,11 +106,12 @@ public:
const StringData::ComparatorInterface* comparator);
- /** These functions, which start with a capital letter, throw if the
- element is not of the required type. Example:
-
- std::string foo = obj["foo"].String(); // std::exception if not a std::string type or DNE
- */
+ /**
+ * These functions, which start with a capital letter, throw if the
+ * element is not of the required type. Example:
+ *
+ * std::string foo = obj["foo"].String(); // std::exception if not a std::string type or DNE
+ */
std::string String() const {
return chk(mongo::String).str();
}
@@ -146,17 +148,19 @@ public:
return chk(jstOID).__oid();
}
- /** @return the embedded object associated with this field.
- Note the returned object is a reference to within the parent bson object. If that
- object is out of scope, this pointer will no longer be valid. Call getOwned() on the
- returned BSONObj if you need your own copy.
- throws AssertionException if the element is not of type object.
- */
+ /**
+ * @return the embedded object associated with this field.
+ * Note the returned object is a reference to within the parent bson object. If that
+ * object is out of scope, this pointer will no longer be valid. Call getOwned() on the
+ * returned BSONObj if you need your own copy.
+ * throws AssertionException if the element is not of type object.
+ */
BSONObj Obj() const;
- /** populate v with the value of the element. If type does not match, throw exception.
- useful in templates -- see also BSONObj::Vals().
- */
+ /**
+ * populate v with the value of the element. If type does not match, throw exception.
+ * useful in templates -- see also BSONObj::Vals().
+ */
void Val(Date_t& v) const {
v = Date();
}
@@ -183,9 +187,10 @@ public:
v = String();
}
- /** Use ok() to check if a value is assigned:
- if( myObj["foo"].ok() ) ...
- */
+ /**
+ * Use ok() to check if a value is assigned:
+ * if( myObj["foo"].ok() ) ...
+ */
bool ok() const {
return !eoo();
}
@@ -249,25 +254,31 @@ public:
return toString();
}
- /** Returns the type of the element */
+ /**
+ * Returns the type of the element
+ */
BSONType type() const {
const signed char typeByte = ConstDataView(data).read<signed char>();
return static_cast<BSONType>(typeByte);
}
- /** retrieve a field within this element
- throws exception if *this is not an embedded object
- */
+ /**
+ * retrieve a field within this element
+ * throws exception if *this is not an embedded object
+ */
BSONElement operator[](StringData field) const;
- /** See canonicalizeBSONType in bsontypes.h */
+ /**
+ * See canonicalizeBSONType in bsontypes.h
+ */
int canonicalType() const {
return canonicalizeBSONType(type());
}
- /** Indicates if it is the end-of-object element, which is present at the end of
- every BSON object.
- */
+ /**
+ * Indicates if it is the end-of-object element, which is present at the end of
+ * every BSON object.
+ */
bool eoo() const {
return type() == EOO;
}
@@ -279,16 +290,21 @@ public:
return totalSize;
}
- /** Wrap this element up as a singleton object. */
+ /**
+ * Wrap this element up as a singleton object.
+ */
BSONObj wrap() const;
- /** Wrap this element up as a singleton object with a new name. */
+ /**
+ * Wrap this element up as a singleton object with a new name.
+ */
BSONObj wrap(StringData newName) const;
- /** field name of the element. e.g., for
- name : "Joe"
- "name" is the fieldname
- */
+ /**
+ * field name of the element. e.g., for
+ * name : "Joe"
+ * "name" is the fieldname
+ */
const char* fieldName() const {
if (eoo())
return ""; // no fieldname for it.
@@ -306,11 +322,15 @@ public:
return StringData(fieldName(), eoo() ? 0 : fieldNameSize() - 1);
}
- /** raw data of the element's value (so be careful). */
+ /**
+ * raw data of the element's value (so be careful).
+ */
const char* value() const {
return (data + fieldNameSize() + 1);
}
- /** size in bytes of the element's value (when applicable). */
+ /**
+ * size in bytes of the element's value (when applicable).
+ */
int valuesize() const {
return size() - fieldNameSize() - 1;
}
@@ -319,9 +339,11 @@ public:
return type() == mongo::Bool;
}
- /** @return value of a boolean element.
- You must assure element is a boolean before
- calling. */
+ /**
+ * @return value of a boolean element.
+ * You must assure element is a boolean before
+ * calling.
+ */
bool boolean() const {
return *value() ? true : false;
}
@@ -330,40 +352,52 @@ public:
return isBoolean() && boolean();
}
- /** Retrieve a java style date value from the element.
- Ensure element is of type Date before calling.
- @see Bool(), trueValue()
- */
+ /**
+ * Retrieve a java style date value from the element.
+ * Ensure element is of type Date before calling.
+ * @see Bool(), trueValue()
+ */
Date_t date() const {
return Date_t::fromMillisSinceEpoch(ConstDataView(value()).read<LittleEndian<long long>>());
}
- /** Convert the value to boolean, regardless of its type, in a javascript-like fashion
- (i.e., treats zero and null and eoo as false).
- */
+ /**
+ * Convert the value to boolean, regardless of its type, in a javascript-like fashion
+ * (i.e., treats zero and null and eoo as false).
+ */
bool trueValue() const;
- /** True if element is of a numeric type. */
+ /**
+ * True if element is of a numeric type.
+ */
bool isNumber() const;
- /** Return double value for this field. MUST be NumberDouble type. */
+ /**
+ * Return double value for this field. MUST be NumberDouble type.
+ */
double _numberDouble() const {
return ConstDataView(value()).read<LittleEndian<double>>();
}
- /** Return int value for this field. MUST be NumberInt type. */
+ /**
+ * Return int value for this field. MUST be NumberInt type.
+ */
int _numberInt() const {
return ConstDataView(value()).read<LittleEndian<int>>();
}
- /** Return decimal128 value for this field. MUST be NumberDecimal type. */
+ /**
+ * Return decimal128 value for this field. MUST be NumberDecimal type.
+ */
Decimal128 _numberDecimal() const {
uint64_t low = ConstDataView(value()).read<LittleEndian<long long>>();
uint64_t high = ConstDataView(value() + sizeof(long long)).read<LittleEndian<long long>>();
return Decimal128(Decimal128::Value({low, high}));
}
- /** Return long long value for this field. MUST be NumberLong type. */
+ /**
+ * Return long long value for this field. MUST be NumberLong type.
+ */
long long _numberLong() const {
return ConstDataView(value()).read<LittleEndian<long long>>();
}
@@ -378,11 +412,13 @@ public:
*/
int numberInt() const;
- /** Like numberInt() but with well-defined behavior for doubles that
- * are NaNs, or too large/small to be represented as int.
- * NaNs -> 0
- * very large doubles -> INT_MAX
- * very small doubles -> INT_MIN */
+ /**
+ * Like numberInt() but with well-defined behavior for doubles that
+ * are NaNs, or too large/small to be represented as int.
+ * NaNs -> 0
+ * very large doubles -> INT_MAX
+ * very small doubles -> INT_MIN
+ */
int safeNumberInt() const;
/**
@@ -395,19 +431,23 @@ public:
*/
long long numberLong() const;
- /** Like numberLong() but with well-defined behavior for doubles that
- * are NaNs, or too large/small to be represented as long longs.
- * NaNs -> 0
- * very large doubles -> LLONG_MAX
- * very small doubles -> LLONG_MIN */
+ /**
+ * Like numberLong() but with well-defined behavior for doubles that
+ * are NaNs, or too large/small to be represented as long longs.
+ * NaNs -> 0
+ * very large doubles -> LLONG_MAX
+ * very small doubles -> LLONG_MIN
+ */
long long safeNumberLong() const;
- /** This safeNumberLongForHash() function does the same thing as safeNumberLong, but it
- * preserves edge-case behavior from older versions.
+ /**
+ * This safeNumberLongForHash() function does the same thing as safeNumberLong, but it
+ * preserves edge-case behavior from older versions.
*/
long long safeNumberLongForHash() const;
- /** Convert a numeric field to long long, and uassert the conversion is exact.
+ /**
+ * Convert a numeric field to long long, and uassert the conversion is exact.
*/
long long exactNumberLong() const;
@@ -452,67 +492,75 @@ public:
*/
StatusWith<int> parseIntegerElementToInt() const;
- /** Retrieve decimal value for the element safely. */
+ /**
+ * Retrieve decimal value for the element safely.
+ */
Decimal128 numberDecimal() const;
- /** Retrieve the numeric value of the element. If not of a numeric type, returns 0.
- Note: casts to double, data loss may occur with large (>52 bit) NumberLong values.
- */
+ /**
+ * Retrieve the numeric value of the element. If not of a numeric type, returns 0.
+ * Note: casts to double, data loss may occur with large (>52 bit) NumberLong values.
+ */
double numberDouble() const;
- /** Retrieve the numeric value of the element. If not of a numeric type, returns 0.
- Note: casts to double, data loss may occur with large (>52 bit) NumberLong values.
- */
+ /**
+ * Retrieve the numeric value of the element. If not of a numeric type, returns 0.
+ * Note: casts to double, data loss may occur with large (>52 bit) NumberLong values.
+ */
double number() const {
return numberDouble();
}
- /** Like numberDouble() but with well-defined behavior for doubles that
- * are NaNs, or too large/small to be represented as doubles.
- * NaNs -> 0
- * very large decimals -> DOUBLE_MAX
- * very small decimals -> DOUBLE_MIN */
+ /**
+ * Like numberDouble() but with well-defined behavior for doubles that
+ * are NaNs, or too large/small to be represented as doubles.
+ * NaNs -> 0
+ * very large decimals -> DOUBLE_MAX
+ * very small decimals -> DOUBLE_MIN
+ */
double safeNumberDouble() const;
- /** Retrieve the object ID stored in the object.
- You must ensure the element is of type jstOID first. */
+ /**
+ * Retrieve the object ID stored in the object.
+ * You must ensure the element is of type jstOID first.
+ */
mongo::OID __oid() const {
return OID::from(value());
}
- /** True if element is null. */
+ /**
+ * True if element is null.
+ */
bool isNull() const {
return type() == jstNULL;
}
- /** Size of a BSON String element.
- Requires that type() == mongo::String.
- @return String size including its null-termination.
- */
+ /**
+ * Size of a BSON String element.
+ * Requires that type() == mongo::String.
+ * @return String size including its null-termination.
+ */
int valuestrsize() const {
return ConstDataView(value()).read<LittleEndian<int>>();
}
- // for objects the size *includes* the size of the size field
+ /**
+ * for objects the size *includes* the size of the size field
+ */
size_t objsize() const {
return ConstDataView(value()).read<LittleEndian<uint32_t>>();
}
- /** Get a string's value. Also gives you start of the real data for an embedded object.
- You must assure data is of an appropriate type first -- see also valuestrsafe().
- */
- const char* valuestr() const {
- return value() + 4;
- }
-
- /** Like valuestr, but returns a valid empty string if `type() != mongo::String`. */
- const char* valuestrsafe() const {
- return type() == mongo::String ? valuestr() : "";
- }
- /** Like valuestrsafe, but returns StringData. */
+ /**
+ * Get a string's value. Returns a valid empty string if
+ * `type() != mongo::String`.
+ */
StringData valueStringDataSafe() const {
return type() == mongo::String ? StringData(valuestr(), valuestrsize() - 1) : StringData();
}
- /** Like valuestrsafe, but returns std::string. */
+
+ /**
+ * Like valueStringDataSafe, but returns std::string.
+ */
std::string str() const {
return valueStringDataSafe().toString();
}
@@ -525,41 +573,54 @@ public:
return StringData(valuestr(), valuestrsize() - 1);
}
- /** Get javascript code of a CodeWScope data element. */
+ /**
+ * Get javascript code of a CodeWScope data element.
+ */
const char* codeWScopeCode() const {
massert(16177, "not codeWScope", type() == CodeWScope);
return value() + 4 + 4; // two ints precede code (see BSON spec)
}
- /** Get length of the code part of the CodeWScope object
- * This INCLUDES the null char at the end */
+ /**
+ * Get length of the code part of the CodeWScope object
+ * This INCLUDES the null char at the end
+ */
int codeWScopeCodeLen() const {
massert(16178, "not codeWScope", type() == CodeWScope);
return ConstDataView(value() + 4).read<LittleEndian<int>>();
}
- /* Get the scope SavedContext of a CodeWScope data element.
+ /**
+ * Get the scope SavedContext of a CodeWScope data element.
*/
const char* codeWScopeScopeData() const {
return codeWScopeCode() + codeWScopeCodeLen();
}
- /** Get the embedded object this element holds. */
+ /**
+ * Get the embedded object this element holds.
+ */
BSONObj embeddedObject() const;
- /* uasserts if not an object */
+ /**
+ * uasserts if not an object
+ */
BSONObj embeddedObjectUserCheck() const;
BSONObj codeWScopeObject() const;
- /** Get raw binary data. Element must be of type BinData. Doesn't handle type 2 specially */
+ /**
+ * Get raw binary data. Element must be of type BinData. Doesn't handle type 2 specially
+ */
const char* binData(int& len) const {
// BinData: <int len> <byte subtype> <byte[len] data>
verify(type() == BinData);
len = valuestrsize();
return value() + 5;
}
- /** Get binary data. Element must be of type BinData. Handles type 2 */
+ /**
+ * Get binary data. Element must be of type BinData. Handles type 2
+ */
const char* binDataClean(int& len) const {
// BinData: <int len> <byte subtype> <byte[len] data>
if (binDataType() != ByteArrayDeprecated) {
@@ -586,13 +647,17 @@ public:
return {first, last};
}
- /** Retrieve the regex std::string for a Regex element */
+ /**
+ * Retrieve the regex std::string for a Regex element
+ */
const char* regex() const {
verify(type() == RegEx);
return value();
}
- /** Retrieve the regex flags (options) for a Regex element */
+ /**
+ * Retrieve the regex flags (options) for a Regex element
+ */
const char* regexFlags() const {
const char* p = regex();
return p + strlen(p) + 1;
@@ -663,10 +728,14 @@ public:
return data;
}
- /** Constructs an empty element */
+ /**
+ * Constructs an empty element
+ */
BSONElement();
- /** True if this element may contain subobjects. */
+ /**
+ * True if this element may contain subobjects.
+ */
bool mayEncapsulate() const {
switch (type()) {
case Object:
@@ -678,7 +747,9 @@ public:
}
}
- /** True if this element can be a BSONObj */
+ /**
+ * True if this element can be a BSONObj
+ */
bool isABSONObj() const {
switch (type()) {
case Object:
@@ -751,7 +822,6 @@ public:
return mongo::OID::from(start);
}
- // @param maxLen don't scan more than maxLen bytes
explicit BSONElement(const char* d) : data(d) {
// While we should skip the type, and add 1 for the terminating null byte, just include
// the type byte in the strlen call: the extra byte cancels out. As an extra bonus, this
@@ -761,14 +831,12 @@ public:
totalSize = computeSize(type, d, fieldNameSize_);
}
- struct CachedSizeTag {}; // Opts in to next constructor.
-
/**
* Construct a BSONElement where you already know the length of the name and/or the total size
* of the element. fieldNameSize includes the null terminator. You may pass -1 for either or
* both sizes to indicate that they are unknown and should be computed.
*/
- BSONElement(const char* d, int fieldNameSize, int totalSize, CachedSizeTag) : data(d) {
+ BSONElement(const char* d, int fieldNameSize, int totalSize) : data(d) {
if (eoo()) {
fieldNameSize_ = 0;
this->totalSize = 1;
@@ -832,6 +900,18 @@ public:
static const long long kSmallestSafeLongLongAsDouble;
private:
+ /**
+ * Get a string's value. Also gives you start of the real data for an embedded object.
+ * You must assure data is of an appropriate type first, like the type check in
+ * valueStringDataSafe(). You should use the string's size when performing any operations
+ * on the data to disambiguate between potential embedded null's and the terminating null.
+ * This function is only used in limited forms internally. Not to be exposed publicly.
+ * If a char* is desired use valueStringDataSafe().rawData().
+ */
+ const char* valuestr() const {
+ return value() + 4;
+ }
+
template <typename Generator>
BSONObj _jsonStringGenerator(const Generator& g,
bool includeSeparator,
@@ -885,7 +965,9 @@ inline bool BSONElement::trueValue() const {
}
}
-/** @return true if element is of a numeric type. */
+/**
+ * @return true if element is of a numeric type.
+ */
inline bool BSONElement::isNumber() const {
switch (type()) {
case NumberLong:
@@ -1003,11 +1085,13 @@ inline long long BSONElement::numberLong() const {
}
}
-/** Like numberLong() but with well-defined behavior for doubles and decimals that
- * are NaNs, or too large/small to be represented as long longs.
- * NaNs -> 0
- * very large values -> LLONG_MAX
- * very small values -> LLONG_MIN */
+/**
+ * Like numberLong() but with well-defined behavior for doubles and decimals that
+ * are NaNs, or too large/small to be represented as long longs.
+ * NaNs -> 0
+ * very large values -> LLONG_MAX
+ * very small values -> LLONG_MIN
+ */
inline long long BSONElement::safeNumberLong() const {
switch (type()) {
case NumberDouble: {
diff --git a/src/mongo/bson/bsonobj.cpp b/src/mongo/bson/bsonobj.cpp
index a2f6e120ea4..73f824735ed 100644
--- a/src/mongo/bson/bsonobj.cpp
+++ b/src/mongo/bson/bsonobj.cpp
@@ -601,9 +601,9 @@ bool BSONObj::getBoolField(StringData name) const {
return e.type() == Bool ? e.boolean() : false;
}
-const char* BSONObj::getStringField(StringData name) const {
+StringData BSONObj::getStringField(StringData name) const {
BSONElement e = getField(name);
- return e.type() == String ? e.valuestr() : "";
+ return e.valueStringDataSafe();
}
bool BSONObj::getObjectID(BSONElement& e) const {
diff --git a/src/mongo/bson/bsonobj.h b/src/mongo/bson/bsonobj.h
index c7c484ec9c5..10c6483e70d 100644
--- a/src/mongo/bson/bsonobj.h
+++ b/src/mongo/bson/bsonobj.h
@@ -124,7 +124,9 @@ public:
static constexpr char kMinBSONLength = 5;
- /** Construct an empty BSONObj -- that is, {}. */
+ /**
+ * Construct an empty BSONObj -- that is, {}.
+ */
BSONObj() {
// Little endian ordering here, but that is ok regardless as BSON is spec'd to be
// little endian external to the system. (i.e. the rest of the implementation of
@@ -132,7 +134,8 @@ public:
_objdata = kEmptyObjectPrototype;
}
- /** Construct a BSONObj from data in the proper format.
+ /**
+ * Construct a BSONObj from data in the proper format.
* Use this constructor when something else owns bsonData's buffer
*/
template <typename Traits = DefaultSizeTrait>
@@ -144,7 +147,9 @@ public:
: _objdata(ownedBuffer.get() ? ownedBuffer.get() : BSONObj().objdata()),
_ownedBuffer(std::move(ownedBuffer)) {}
- /** Move construct a BSONObj */
+ /**
+ * Move construct a BSONObj
+ */
BSONObj(BSONObj&& other) noexcept
: _objdata(std::move(other._objdata)), _ownedBuffer(std::move(other._ownedBuffer)) {
other._objdata = BSONObj()._objdata; // To return to an empty state.
@@ -154,18 +159,23 @@ public:
// The explicit move constructor above will inhibit generation of the copy ctor, so
// explicitly request the default implementation.
- /** Copy construct a BSONObj. */
+ /**
+ * Copy construct a BSONObj.
+ */
BSONObj(const BSONObj&) = default;
- /** Provide assignment semantics. We use the value taking form so that we can use copy
- * and swap, and consume both lvalue and rvalue references.
+ /**
+ * Provide assignment semantics. We use the value taking form so that we can use copy
+ * and swap, and consume both lvalue and rvalue references.
*/
BSONObj& operator=(BSONObj otherCopy) noexcept {
this->swap(otherCopy);
return *this;
}
- /** Swap this BSONObj with 'other' */
+ /**
+ * Swap this BSONObj with 'other'
+ */
void swap(BSONObj& other) noexcept {
using std::swap;
swap(_objdata, other._objdata);
@@ -238,23 +248,31 @@ public:
return std::move(sink._ownedBuffer);
}
- /** If the data buffer is under the control of this BSONObj, return it.
- Else return an owned copy.
- */
+ /**
+ * If the data buffer is under the control of this BSONObj, return it.
+ * Else return an owned copy.
+ */
BSONObj getOwned() const;
- /** Returns an owned copy of the given BSON object. */
+ /**
+ * Returns an owned copy of the given BSON object.
+ */
static BSONObj getOwned(const BSONObj& obj);
- /** @return a new full (and owned) copy of the object. */
+ /**
+ * @return a new full (and owned) copy of the object.
+ */
BSONObj copy() const;
- /** @return a new full (and owned) redacted copy of the object. */
+ /**
+ * @return a new full (and owned) redacted copy of the object.
+ */
BSONObj redact() const;
- /** Readable representation of a BSON object in an extended JSON-style notation.
- This is an abbreviated representation which might be used for logging.
- */
+ /**
+ * Readable representation of a BSON object in an extended JSON-style notation.
+ * This is an abbreviated representation which might be used for logging.
+ */
enum { maxToStringRecursionDepth = 100 };
std::string toString(bool redactValues = false) const;
@@ -264,9 +282,10 @@ public:
bool redactValues = false,
int depth = 0) const;
- /** Properly formatted JSON string.
- @param pretty if true we try to add some lf's and indentation
- */
+ /**
+ * Properly formatted JSON string.
+ * @param pretty if true we try to add some lf's and indentation
+ */
std::string jsonString(JsonStringFormat format = ExtendedCanonicalV2_0_0,
int pretty = 0,
bool isArray = false,
@@ -313,8 +332,9 @@ public:
BSONObj addFields(const BSONObj& from,
const boost::optional<StringDataSet>& fields = boost::none) const;
- /** remove specified field and return a new object with the remaining fields.
- slowish as builds a full new object
+ /**
+ * Remove specified field and return a new object with the remaining fields.
+ * slowish as builds a full new object
*/
BSONObj removeField(StringData name) const;
@@ -324,9 +344,10 @@ public:
BSONObj removeFields(const std::set<std::string>& fields) const;
BSONObj removeFields(const StringDataSet& fields) const;
- /** returns # of top level fields in the object
- note: iterates to count the fields
- */
+ /**
+ * Returns # of top level fields in the object
+ * note: iterates to count the fields
+ */
int nFields() const;
/**
@@ -335,18 +356,19 @@ public:
template <class Container>
Container getFieldNames() const;
- /** Get the field of the specified name. eoo() is true on the returned
- element if not found.
- */
+ /**
+ * Get the field of the specified name. eoo() is true on the returned
+ * element if not found.
+ */
BSONElement getField(StringData name) const;
- /** Get several fields at once. This is faster than separate getField() calls as the size of
- elements iterated can then be calculated only once each.
- @param n number of fieldNames, and number of elements in the fields array
- @param fields if a field is found its element is stored in its corresponding position in
- this array. if not found the array element is unchanged.
+ /**
+ * Get several fields at once. This is faster than separate getField() calls as the size of
+ * elements iterated can then be calculated only once each.
+ * @param n number of fieldNames, and number of elements in the fields array
+ * @param fields if a field is found its element is stored in its corresponding position in
+ * this array. if not found the array element is unchanged.
*/
-
void getFields(unsigned n, const char** fieldNames, BSONElement* fields) const;
/**
@@ -358,9 +380,10 @@ public:
std::array<BSONElement, N>* fields) const;
- /** Get the field of the specified name. eoo() is true on the returned
- element if not found.
- */
+ /**
+ * Get the field of the specified name. eoo() is true on the returned
+ * element if not found.
+ */
BSONElement operator[](StringData field) const {
return getField(field);
}
@@ -372,40 +395,52 @@ public:
return getField(s.c_str());
}
- /** @return true if field exists */
+ /**
+ * @return true if field exists
+ */
bool hasField(StringData name) const {
return !getField(name).eoo();
}
- /** @return true if field exists */
+ /**
+ * @return true if field exists
+ */
bool hasElement(StringData name) const {
return hasField(name);
}
- /** @return "" if DNE or wrong type */
- const char* getStringField(StringData name) const;
+ /**
+ * Looks up the element with the given 'name'. If the element is a string,
+ * returns it as a StringData. Otherwise returns an empty StringData.
+ */
+ StringData getStringField(StringData name) const;
- /** @return subobject of the given name */
+ /**
+ * @return subobject of the given name
+ */
BSONObj getObjectField(StringData name) const;
- /** @return INT_MIN if not present - does some type conversions */
+ /**
+ * @return INT_MIN if not present - does some type conversions
+ */
int getIntField(StringData name) const;
- /** @return false if not present
- @see BSONElement::trueValue()
+ /**
+ * @return false if not present
+ * @see BSONElement::trueValue()
*/
bool getBoolField(StringData name) const;
- /** @param pattern a BSON obj indicating a set of (un-dotted) field
- * names. Element values are ignored.
- * @return a BSON obj constructed by taking the elements of this obj
- * that correspond to the fields in pattern. Field names of the
- * returned object are replaced with the empty string. If field in
- * pattern is missing, it is omitted from the returned object.
- *
- * Example: if this = {a : 4 , b : 5 , c : 6})
- * this.extractFieldsUnDotted({a : 1 , c : 1}) -> {"" : 4 , "" : 6 }
- * this.extractFieldsUnDotted({b : "blah"}) -> {"" : 5}
+ /**
+ * @param pattern a BSON obj indicating a set of (un-dotted) field
+ * names. Element values are ignored.
+ * @return a BSON obj constructed by taking the elements of this obj
+ * that correspond to the fields in pattern. Field names of the
+ * returned object are replaced with the empty string. If field in
+ * pattern is missing, it is omitted from the returned object.
*
+ * Example: if this = {a : 4 , b : 5 , c : 6})
+ * this.extractFieldsUnDotted({a : 1 , c : 1}) -> {"" : 4 , "" : 6 }
+ * this.extractFieldsUnDotted({b : "blah"}) -> {"" : 5}
*/
BSONObj extractFieldsUndotted(const BSONObj& pattern) const;
void extractFieldsUndotted(BSONObjBuilder* b, const BSONObj& pattern) const;
@@ -415,22 +450,29 @@ public:
BSONElement getFieldUsingIndexNames(StringData fieldName, const BSONObj& indexKey) const;
- /** arrays are bson objects with numeric and increasing field names
- @return true if field names are numeric and increasing
+ /**
+ * arrays are bson objects with numeric and increasing field names
+ * @return true if field names are numeric and increasing
*/
bool couldBeArray() const;
- /** @return the raw data of the object */
+ /**
+ * @return the raw data of the object
+ */
const char* objdata() const {
return _objdata;
}
- /** @return total size of the BSON object in bytes */
+ /**
+ * @return total size of the BSON object in bytes
+ */
int objsize() const {
return ConstDataView(objdata()).read<LittleEndian<int>>();
}
- /** performs a cursory check on the object's size only. */
+ /**
+ * performs a cursory check on the object's size only.
+ */
template <typename Traits = DefaultSizeTrait>
bool isValid() const {
static_assert(Traits::MaxSize > 0 && Traits::MaxSize <= std::numeric_limits<int>::max(),
@@ -445,19 +487,23 @@ public:
*/
Status storageValidEmbedded() const;
- /** @return true if object is empty -- i.e., {} */
+ /**
+ * @return true if object is empty -- i.e., {}
+ */
bool isEmpty() const {
return objsize() <= kMinBSONLength;
}
- /*
+ /**
* Whether this BSONObj is the "empty prototype" special case.
*/
bool isEmptyPrototype() const {
return _objdata == kEmptyObjectPrototype;
}
- /** Alternative output format */
+ /**
+ * Alternative output format
+ */
std::string hexDump() const;
//
@@ -528,9 +574,10 @@ public:
*/
bool isFieldNamePrefixOf(const BSONObj& otherObj) const;
- /** This is "shallow equality" -- ints and doubles won't match. for a
- deep equality test use woCompare (which is slower).
- */
+ /**
+ * This is "shallow equality" -- ints and doubles won't match. for a
+ * deep equality test use woCompare (which is slower).
+ */
bool binaryEqual(const BSONObj& r) const {
int os = objsize();
if (os == r.objsize()) {
@@ -539,12 +586,15 @@ public:
return false;
}
- /** @return first field of the object */
+ /**
+ * @return first field of the object
+ */
BSONElement firstElement() const {
return BSONElement(objdata() + 4);
}
- /** faster than firstElement().fieldName() - for the first element we can easily find the
+ /**
+ * faster than firstElement().fieldName() - for the first element we can easily find the
* fieldname without computing the element size.
*/
const char* firstElementFieldName() const {
@@ -561,21 +611,26 @@ public:
return (BSONType)*p;
}
- /** Get the _id field from the object. For good performance drivers should
- assure that _id is the first element of the object; however, correct operation
- is assured regardless.
- @return true if found
- */
+ /**
+ * Get the _id field from the object. For good performance drivers should
+ * assure that _id is the first element of the object; however, correct operation
+ * is assured regardless.
+ * @return true if found
+ */
bool getObjectID(BSONElement& e) const;
- // Return a version of this object where top level elements of types
- // that are not part of the bson wire protocol are replaced with
- // std::string identifier equivalents.
- // TODO Support conversion of element types other than min and max.
+ /**
+ * Return a version of this object where top level elements of types
+ * that are not part of the bson wire protocol are replaced with
+ * std::string identifier equivalents.
+ * TODO Support conversion of element types other than min and max.
+ */
BSONObj clientReadable() const;
- /** Return new object with the field names replaced by those in the
- passed object. */
+ /**
+ * Return new object with the field names replaced by those in the
+ * passed object.
+ */
BSONObj replaceFieldNames(const BSONObj& obj) const;
static BSONObj stripFieldNames(const BSONObj& obj);
@@ -587,9 +642,13 @@ public:
*/
bool valid() const;
- /** add all elements of the object to the specified vector */
+ /**
+ * add all elements of the object to the specified vector
+ */
void elems(std::vector<BSONElement>&) const;
- /** add all elements of the object to the specified list */
+ /**
+ * add all elements of the object to the specified list
+ */
void elems(std::list<BSONElement>&) const;
friend class BSONObjIterator;
@@ -709,14 +768,18 @@ public:
return BSONObjStlIterator(eooElem);
}
- /** pre-increment */
+ /**
+ * pre-increment
+ */
BSONObjStlIterator& operator++() {
dassert(!_cur.eoo());
*this = BSONObjStlIterator(BSONElement(_cur.rawdata() + _cur.size()));
return *this;
}
- /** post-increment */
+ /**
+ * post-increment
+ */
BSONObjStlIterator operator++(int) {
BSONObjStlIterator oldPos = *this;
++*this;
@@ -755,7 +818,8 @@ private:
*/
class BSONObjIterator {
public:
- /** Create an iterator for a BSON object.
+ /**
+ * Create an iterator for a BSON object.
*/
explicit BSONObjIterator(const BSONObj& jso) {
int sz = jso.objsize();
@@ -772,7 +836,7 @@ public:
_theend = end - 1;
}
- /*
+ /**
* Advance '_pos' by currentElement.size(). The element passed in must be equivalent to the
* current element '_pos' is at.
*/
@@ -791,13 +855,17 @@ public:
return sz <= (_theend - _pos) && memcmp(otherElement.rawdata(), _pos, sz) == 0;
}
- /** @return true if more elements exist to be enumerated. */
+ /**
+ * @return true if more elements exist to be enumerated.
+ */
bool more() const {
return _pos < _theend;
}
- /** @return true if more elements exist to be enumerated INCLUDING the EOO element which is
- * always at the end. */
+ /**
+ * @return true if more elements exist to be enumerated INCLUDING the EOO element which is
+ * always at the end.
+ */
bool moreWithEOO() const {
return _pos <= _theend;
}
@@ -809,13 +877,17 @@ public:
return e;
}
- /** pre-increment */
+ /**
+ * pre-increment
+ */
BSONObjIterator& operator++() {
next();
return *this;
}
- /** post-increment */
+ /**
+ * post-increment
+ */
BSONObjIterator operator++(int) {
BSONObjIterator oldPos = *this;
next();
@@ -841,7 +913,9 @@ private:
const char* _theend;
};
-/** Base class implementing ordered iteration through BSONElements. */
+/**
+ * Base class implementing ordered iteration through BSONElements.
+ */
class BSONIteratorSorted {
BSONIteratorSorted(const BSONIteratorSorted&) = delete;
BSONIteratorSorted& operator=(const BSONIteratorSorted&) = delete;
@@ -861,8 +935,7 @@ public:
const auto& element = _fields[_cur++];
return BSONElement(element.fieldName.rawData() - 1, // Include type byte
element.fieldName.size() + 1, // Add null terminator
- element.totalSize,
- BSONElement::CachedSizeTag{});
+ element.totalSize);
}
return BSONElement();
@@ -882,7 +955,9 @@ private:
int _cur;
};
-/** Provides iteration of a BSONObj's BSONElements in lexical field order. */
+/**
+ * Provides iteration of a BSONObj's BSONElements in lexical field order.
+ */
class BSONObjIteratorSorted : public BSONIteratorSorted {
public:
BSONObjIteratorSorted(const BSONObj& object);
diff --git a/src/mongo/bson/mutable/document.cpp b/src/mongo/bson/mutable/document.cpp
index 56fa36d11f5..db1dabe62b4 100644
--- a/src/mongo/bson/mutable/document.cpp
+++ b/src/mongo/bson/mutable/document.cpp
@@ -481,8 +481,7 @@ struct ElementRep {
BSONElement toSerializedElement(const BSONObj& holder) const {
return BSONElement(holder.objdata() + offset, //
_fieldNameSize,
- _totalSize,
- BSONElement::CachedSizeTag());
+ _totalSize);
}
private:
diff --git a/src/mongo/bson/mutable/element.h b/src/mongo/bson/mutable/element.h
index c60bd4ea589..a0312c31b12 100644
--- a/src/mongo/bson/mutable/element.h
+++ b/src/mongo/bson/mutable/element.h
@@ -760,10 +760,7 @@ inline Element::Element(Document* doc, RepIdx repIdx) : _doc(doc), _repIdx(repId
}
inline StringData Element::getValueStringOrSymbol() const {
- const BSONElement value = getValue();
- const char* str = value.valuestr();
- const size_t size = value.valuestrsize() - 1;
- return StringData(str, size);
+ return getValue().valueStringData();
}
inline bool operator==(const Element& l, const Element& r) {
diff --git a/src/mongo/bson/util/bsoncolumn.cpp b/src/mongo/bson/util/bsoncolumn.cpp
index ce288893f2d..c681ba3ddae 100644
--- a/src/mongo/bson/util/bsoncolumn.cpp
+++ b/src/mongo/bson/util/bsoncolumn.cpp
@@ -117,10 +117,7 @@ int BSONColumn::ElementStorage::Element::size() const {
}
BSONElement BSONColumn::ElementStorage::Element::element() const {
- return {_buffer,
- _nameSize + 1,
- _valueSize + _nameSize + kElementValueOffset,
- BSONElement::CachedSizeTag{}};
+ return {_buffer, _nameSize + 1, _valueSize + _nameSize + kElementValueOffset};
}
BSONColumn::ElementStorage::ContiguousBlock::ContiguousBlock(ElementStorage& storage)
@@ -575,7 +572,7 @@ BSONColumn::Iterator::DecodingState::_loadControl(BSONColumn& column,
if (_isLiteral(control)) {
// Load BSONElement from the literal and set last encoded in case we need to calculate
// deltas from this literal
- BSONElement literalElem(buffer, 1, -1, BSONElement::CachedSizeTag{});
+ BSONElement literalElem(buffer, 1, -1);
_loadLiteral(literalElem);
_decoder64 = boost::none;
diff --git a/src/mongo/bson/util/bsoncolumnbuilder.cpp b/src/mongo/bson/util/bsoncolumnbuilder.cpp
index 139a7adf747..7e9dd840676 100644
--- a/src/mongo/bson/util/bsoncolumnbuilder.cpp
+++ b/src/mongo/bson/util/bsoncolumnbuilder.cpp
@@ -766,7 +766,7 @@ bool BSONColumnBuilder::EncodingState::_appendDouble(double value, double previo
}
BSONElement BSONColumnBuilder::EncodingState::_previous() const {
- return {_prev.get(), 1, _prevSize, BSONElement::CachedSizeTag{}};
+ return {_prev.get(), 1, _prevSize};
}
diff --git a/src/mongo/client/authenticate.cpp b/src/mongo/client/authenticate.cpp
index 2c26e03953e..3c1b7ad6535 100644
--- a/src/mongo/client/authenticate.cpp
+++ b/src/mongo/client/authenticate.cpp
@@ -112,7 +112,7 @@ StatusWith<OpMsgRequest> createX509AuthCmd(const BSONObj& params, StringData cli
if (username != clientName.toString()) {
StringBuilder message;
message << "Username \"";
- message << params[saslCommandUserFieldName].valuestr();
+ message << params[saslCommandUserFieldName].valueStringData();
message << "\" does not match the provided client certificate user \"";
message << clientName.toString() << "\"";
return {ErrorCodes::AuthenticationFailed, message.str()};
diff --git a/src/mongo/client/dbclient_base.cpp b/src/mongo/client/dbclient_base.cpp
index c4b38ddb3e3..98c49806f40 100644
--- a/src/mongo/client/dbclient_base.cpp
+++ b/src/mongo/client/dbclient_base.cpp
@@ -97,7 +97,8 @@ bool DBClientBase::isOk(const BSONObj& o) {
bool DBClientBase::isNotPrimaryErrorString(const BSONElement& e) {
return e.type() == String &&
- (str::contains(e.valuestr(), "not primary") || str::contains(e.valuestr(), "not master"));
+ (str::contains(e.valueStringData(), "not primary") ||
+ str::contains(e.valueStringData(), "not master"));
}
void DBClientBase::setRequestMetadataWriter(rpc::RequestMetadataWriter writer) {
diff --git a/src/mongo/client/replica_set_monitor_integration_test.cpp b/src/mongo/client/replica_set_monitor_integration_test.cpp
index 3f2af0e8ce4..383411d0d61 100644
--- a/src/mongo/client/replica_set_monitor_integration_test.cpp
+++ b/src/mongo/client/replica_set_monitor_integration_test.cpp
@@ -141,7 +141,7 @@ public:
ASSERT_OK(cmdStatus);
const auto shards = res.data["shards"].Array();
ASSERT_FALSE(shards.empty());
- return shards.front().embeddedObject().getStringField("host");
+ return shards.front().embeddedObject().getStringField("host").toString();
}
protected:
diff --git a/src/mongo/client/sdam/sdam_json_test_runner.cpp b/src/mongo/client/sdam/sdam_json_test_runner.cpp
index 749585cf01c..b3fdcba09f0 100644
--- a/src/mongo/client/sdam/sdam_json_test_runner.cpp
+++ b/src/mongo/client/sdam/sdam_json_test_runner.cpp
@@ -486,7 +486,7 @@ private:
_jsonTest = fromjson(json.str());
}
- _testName = _jsonTest.getStringField("description");
+ _testName = _jsonTest.getStringField("description").toString();
_testUri = uassertStatusOK(mongo::MongoURI::parse(_jsonTest["uri"].String()));
_replicaSetName = _testUri.getOption("replicaSet");
diff --git a/src/mongo/client/sdam/server_description.cpp b/src/mongo/client/sdam/server_description.cpp
index 042ad352c28..babe5d1a777 100644
--- a/src/mongo/client/sdam/server_description.cpp
+++ b/src/mongo/client/sdam/server_description.cpp
@@ -129,7 +129,7 @@ void ServerDescription::saveHosts(const BSONObj response) {
void ServerDescription::saveTags(BSONObj tagsObj) {
const auto keys = tagsObj.getFieldNames<std::set<std::string>>();
for (const auto& key : keys) {
- _tags[key] = tagsObj.getStringField(key);
+ _tags[key] = tagsObj.getStringField(key).toString();
}
}
diff --git a/src/mongo/client/sdam/server_selection_json_test_runner.cpp b/src/mongo/client/sdam/server_selection_json_test_runner.cpp
index 72379e27165..a8ebedef4c7 100644
--- a/src/mongo/client/sdam/server_selection_json_test_runner.cpp
+++ b/src/mongo/client/sdam/server_selection_json_test_runner.cpp
@@ -162,7 +162,7 @@ private:
// Only create the initial server description if the original avg rtt is not "NULL". If it
// is, the test case is meant to mimic creating the first ServerDescription which we will do
// above.
- std::string origRttAsString = _jsonTest.getStringField("avg_rtt_ms");
+ std::string origRttAsString = _jsonTest.getStringField("avg_rtt_ms").toString();
if (origRttAsString.compare("NULL") != 0) {
auto serverDescription = ServerDescriptionBuilder()
.withAddress(HostAndPort("dummy"))
@@ -286,7 +286,7 @@ private:
// lowercased keywords. Also, change the key "tags_set" to "tags".
// This can throw for test cases that have invalid read preferences.
auto readPrefObj = _jsonTest.getObjectField("read_preference");
- std::string mode = readPrefObj.getStringField("mode");
+ std::string mode = readPrefObj.getStringField("mode").toString();
mode[0] = ctype::toLower(mode[0]);
auto tagSetsObj = readPrefObj["tag_sets"];
auto tags = tagSetsObj ? BSONArray(readPrefObj["tag_sets"].Obj()) : BSONArray();
@@ -364,7 +364,7 @@ private:
auto tagsObj = server.getObjectField("tags");
const auto keys = tagsObj.getFieldNames<std::set<std::string>>();
for (const auto& key : keys) {
- serverDescription.withTag(key, tagsObj.getStringField(key));
+ serverDescription.withTag(key, tagsObj.getStringField(key).toString());
}
serverDescriptions.push_back(serverDescription.instance());
diff --git a/src/mongo/db/auth/authorization_manager_impl.cpp b/src/mongo/db/auth/authorization_manager_impl.cpp
index a733e5bf058..0f9f7ff2e47 100644
--- a/src/mongo/db/auth/authorization_manager_impl.cpp
+++ b/src/mongo/db/auth/authorization_manager_impl.cpp
@@ -138,7 +138,7 @@ public:
Status set(const BSONElement& newValueElement) {
if (newValueElement.type() == String) {
- return setFromString(newValueElement.valuestrsafe());
+ return setFromString(newValueElement.str());
} else if (newValueElement.type() == Array) {
auto array = static_cast<BSONArray>(newValueElement.embeddedObject());
std::vector<UserName> out;
@@ -244,7 +244,7 @@ bool loggedCommandOperatesOnAuthzData(const NamespaceString& nss, const BSONObj&
return true;
} else if (cmdName == "renameCollection") {
const NamespaceString fromNamespace(cmdObj.firstElement().valueStringDataSafe());
- const NamespaceString toNamespace(cmdObj["to"].valueStringDataSafe());
+ const NamespaceString toNamespace(cmdObj.getStringField("to"));
if (fromNamespace.isAdminDB() || toNamespace.isAdminDB()) {
return isAuthzCollection(fromNamespace.coll()) || isAuthzCollection(toNamespace.coll());
diff --git a/src/mongo/db/catalog/commit_quorum_options.cpp b/src/mongo/db/catalog/commit_quorum_options.cpp
index 0a85a812b56..dba101c94e8 100644
--- a/src/mongo/db/catalog/commit_quorum_options.cpp
+++ b/src/mongo/db/catalog/commit_quorum_options.cpp
@@ -77,7 +77,7 @@ Status CommitQuorumOptions::parse(const BSONElement& commitQuorumElement) {
}
numNodes = static_cast<decltype(numNodes)>(cNumNodes);
} else if (commitQuorumElement.type() == String) {
- mode = commitQuorumElement.valuestrsafe();
+ mode = commitQuorumElement.str();
if (mode.empty()) {
return Status(ErrorCodes::FailedToParse,
str::stream() << "commitQuorum can't be an empty string");
diff --git a/src/mongo/db/catalog/index_build_block.cpp b/src/mongo/db/catalog/index_build_block.cpp
index 9773f85af46..9afe74f4b77 100644
--- a/src/mongo/db/catalog/index_build_block.cpp
+++ b/src/mongo/db/catalog/index_build_block.cpp
@@ -89,7 +89,7 @@ Status IndexBuildBlock::initForResume(OperationContext* opCtx,
const IndexStateInfo& stateInfo,
IndexBuildPhaseEnum phase) {
- _indexName = _spec.getStringField("name");
+ _indexName = _spec.getStringField("name").toString();
auto descriptor = collection->getIndexCatalog()->findIndexByName(
opCtx, _indexName, true /* includeUnfinishedIndexes */);
diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp
index 976e79f350f..09ae09ed303 100644
--- a/src/mongo/db/catalog/index_catalog_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_impl.cpp
@@ -893,7 +893,7 @@ Status IndexCatalogImpl::_doesSpecConflictWithExisting(OperationContext* opCtx,
const CollectionPtr& collection,
const BSONObj& spec,
const bool includeUnfinishedIndexes) const {
- const char* name = spec.getStringField(IndexDescriptor::kIndexNameFieldName);
+ StringData name = spec.getStringField(IndexDescriptor::kIndexNameFieldName);
invariant(name[0]);
const BSONObj key = spec.getObjectField(IndexDescriptor::kKeyPatternFieldName);
diff --git a/src/mongo/db/catalog/index_key_validate.cpp b/src/mongo/db/catalog/index_key_validate.cpp
index cabb38f8b1b..caa209fd3c3 100644
--- a/src/mongo/db/catalog/index_key_validate.cpp
+++ b/src/mongo/db/catalog/index_key_validate.cpp
@@ -224,11 +224,10 @@ Status validateKeyPattern(const BSONObj& key, IndexDescriptor::IndexVersion inde
// "$**" is acceptable for a text index or wildcard index.
if ((keyElement.fieldNameStringData() == "$**") &&
- ((keyElement.isNumber()) || (keyElement.valuestrsafe() == IndexNames::TEXT)))
+ ((keyElement.isNumber()) || (keyElement.str() == IndexNames::TEXT)))
continue;
- if ((keyElement.fieldNameStringData() == "_fts") &&
- keyElement.valuestrsafe() != IndexNames::TEXT) {
+ if ((keyElement.fieldNameStringData() == "_fts") && keyElement.str() != IndexNames::TEXT) {
return Status(code, "Index key contains an illegal field name: '_fts'");
}
diff --git a/src/mongo/db/commands/distinct.cpp b/src/mongo/db/commands/distinct.cpp
index 96054086f0f..931441118d3 100644
--- a/src/mongo/db/commands/distinct.cpp
+++ b/src/mongo/db/commands/distinct.cpp
@@ -246,7 +246,7 @@ public:
executor.getValue()->getPlanExplainer().getPlanSummary());
}
- const auto key = cmdObj[ParsedDistinct::kKeyField].valuestrsafe();
+ const auto key = cmdObj.getStringField(ParsedDistinct::kKeyField);
std::vector<BSONObj> distinctValueHolder;
BSONElementSet values(executor.getValue()->getCanonicalQuery()->getCollator());
diff --git a/src/mongo/db/commands/oplog_application_checks.cpp b/src/mongo/db/commands/oplog_application_checks.cpp
index bd6198ea3a5..80e0e8720e3 100644
--- a/src/mongo/db/commands/oplog_application_checks.cpp
+++ b/src/mongo/db/commands/oplog_application_checks.cpp
@@ -177,8 +177,8 @@ Status OplogApplicationChecks::checkOperation(const BSONElement& e) {
str::stream() << "\"op\" field is not a string: " << e.fieldName()};
}
// operation type -- see logOp() comments for types
- const char* opType = opElement.valuestrsafe();
- if (*opType == '\0') {
+ StringData opType = opElement.valueStringDataSafe();
+ if (opType.empty()) {
return {ErrorCodes::IllegalOperation,
str::stream() << "\"op\" field value cannot be empty: " << e.fieldName()};
}
@@ -198,7 +198,7 @@ Status OplogApplicationChecks::checkOperation(const BSONElement& e) {
return {ErrorCodes::IllegalOperation,
str::stream() << "namespaces cannot have embedded null characters"};
}
- if (*opType != 'n' && nsElement.String().empty()) {
+ if (opType != "n"_sd && nsElement.String().empty()) {
return {ErrorCodes::IllegalOperation,
str::stream() << "\"ns\" field value cannot be empty when op type is not 'n': "
<< e.fieldName()};
diff --git a/src/mongo/db/commands/parameters.cpp b/src/mongo/db/commands/parameters.cpp
index 5a7840e655f..aaff8b03898 100644
--- a/src/mongo/db/commands/parameters.cpp
+++ b/src/mongo/db/commands/parameters.cpp
@@ -222,7 +222,7 @@ public:
const BSONObj& cmdObj,
string& errmsg,
BSONObjBuilder& result) {
- bool all = *cmdObj.firstElement().valuestrsafe() == '*';
+ bool all = cmdObj.firstElement().str() == "*";
int before = result.len();
diff --git a/src/mongo/db/exec/sbe/stages/makeobj.cpp b/src/mongo/db/exec/sbe/stages/makeobj.cpp
index 54e1ce05e89..e1c9cd6320e 100644
--- a/src/mongo/db/exec/sbe/stages/makeobj.cpp
+++ b/src/mongo/db/exec/sbe/stages/makeobj.cpp
@@ -258,8 +258,7 @@ void MakeObjStageBase<MakeObjOutputType::bsonObject>::produceObject() {
auto nextBe = bson::advance(be, sv.size());
if (!isFieldProjectedOrRestricted(key)) {
- bob.append(BSONElement(
- be, sv.size() + 1, nextBe - be, BSONElement::CachedSizeTag{}));
+ bob.append(BSONElement(be, sv.size() + 1, nextBe - be));
--nFieldsNeededIfInclusion;
}
diff --git a/src/mongo/db/field_parser.cpp b/src/mongo/db/field_parser.cpp
index 94207bf7d22..0afde43f427 100644
--- a/src/mongo/db/field_parser.cpp
+++ b/src/mongo/db/field_parser.cpp
@@ -206,7 +206,7 @@ FieldParser::FieldState FieldParser::extract(BSONElement elem,
if (elem.type() == String) {
// Extract everything, including embedded null characters.
- *out = string(elem.valuestr(), elem.valuestrsize() - 1);
+ *out = elem.str();
return FIELD_SET;
}
diff --git a/src/mongo/db/fts/fts_element_iterator.cpp b/src/mongo/db/fts/fts_element_iterator.cpp
index 00c0dd39134..689964f58d6 100644
--- a/src/mongo/db/fts/fts_element_iterator.cpp
+++ b/src/mongo/db/fts/fts_element_iterator.cpp
@@ -149,7 +149,8 @@ FTSIteratorValue FTSElementIterator::advance() {
case String:
// Only index strings on exact match or wildcard.
if (exactMatch || _spec.wildcard()) {
- return FTSIteratorValue(elem.valuestr(), _frame._language, weight);
+ return FTSIteratorValue(
+ elem.valueStringData().rawData(), _frame._language, weight);
}
break;
diff --git a/src/mongo/db/fts/fts_index_format_test.cpp b/src/mongo/db/fts/fts_index_format_test.cpp
index 7d5dd4a3eae..9c40895de01 100644
--- a/src/mongo/db/fts/fts_index_format_test.cpp
+++ b/src/mongo/db/fts/fts_index_format_test.cpp
@@ -87,7 +87,7 @@ TEST(FTSIndexFormat, ExtraBack1) {
auto key = KeyString::toBson(*keys.begin(), Ordering::make(BSONObj()));
ASSERT_EQUALS(3, key.nFields());
BSONObjIterator i(key);
- ASSERT_EQUALS(StringData("cat"), i.next().valuestr());
+ ASSERT_EQUALS(StringData("cat"), i.next().valueStringDataSafe());
ASSERT(i.next().numberDouble() > 0);
ASSERT_EQUALS(5, i.next().numberInt());
}
@@ -111,7 +111,7 @@ TEST(FTSIndexFormat, ExtraFront1) {
ASSERT_EQUALS(3, key.nFields());
BSONObjIterator i(key);
ASSERT_EQUALS(5, i.next().numberInt());
- ASSERT_EQUALS(StringData("cat"), i.next().valuestr());
+ ASSERT_EQUALS(StringData("cat"), i.next().valueStringDataSafe());
ASSERT(i.next().numberDouble() > 0);
}
diff --git a/src/mongo/db/fts/fts_spec.cpp b/src/mongo/db/fts/fts_spec.cpp
index 04d36348511..64b333d5c25 100644
--- a/src/mongo/db/fts/fts_spec.cpp
+++ b/src/mongo/db/fts/fts_spec.cpp
@@ -109,7 +109,7 @@ FTSSpec::FTSSpec(const BSONObj& indexInfo) {
" correct options.");
}
- _languageOverrideField = indexInfo["language_override"].valuestrsafe();
+ _languageOverrideField = indexInfo.getStringField("language_override").toString();
_wildcard = false;
@@ -290,7 +290,7 @@ StatusWith<BSONObj> FTSSpec::fixSpec(const BSONObj& spec) {
while (i.more()) {
BSONElement e = i.next();
if (e.fieldNameStringData() == "_fts") {
- if (INDEX_NAME != e.valuestrsafe()) {
+ if (INDEX_NAME != e.str()) {
return {ErrorCodes::CannotCreateIndex, "expecting _fts:\"text\""};
}
addedFtsStuff = true;
@@ -300,7 +300,7 @@ StatusWith<BSONObj> FTSSpec::fixSpec(const BSONObj& spec) {
return {ErrorCodes::CannotCreateIndex, "expecting _ftsx:1"};
}
b.append(e);
- } else if (e.type() == String && INDEX_NAME == e.valuestr()) {
+ } else if (e.type() == String && INDEX_NAME == e.str()) {
if (!addedFtsStuff) {
_addFTSStuff(&b);
addedFtsStuff = true;
diff --git a/src/mongo/db/fts/fts_spec_legacy.cpp b/src/mongo/db/fts/fts_spec_legacy.cpp
index 06ed2e17088..8d88f9a772a 100644
--- a/src/mongo/db/fts/fts_spec_legacy.cpp
+++ b/src/mongo/db/fts/fts_spec_legacy.cpp
@@ -53,8 +53,8 @@ void _addFTSStuff(BSONObjBuilder* b) {
const FTSLanguage& FTSSpec::_getLanguageToUseV1(const BSONObj& userDoc) const {
BSONElement e = userDoc[_languageOverrideField];
if (e.type() == String) {
- const char* x = e.valuestrsafe();
- if (strlen(x) > 0) {
+ StringData x = e.valueStringData();
+ if (e.size() > 0) {
// make() w/ TEXT_INDEX_VERSION_1 guaranteed to not fail.
return FTSLanguage::make(x, TEXT_INDEX_VERSION_1);
}
@@ -144,7 +144,7 @@ void FTSSpec::_scoreRecurseV1(const Tools& tools,
if (x.type() == String) {
double w = 1;
_weightV1(x.fieldName(), &w);
- _scoreStringV1(tools, x.valuestr(), term_freqs, w);
+ _scoreStringV1(tools, x.valueStringData(), term_freqs, w);
} else if (x.isABSONObj()) {
_scoreRecurseV1(tools, x.Obj(), term_freqs);
}
@@ -181,10 +181,10 @@ void FTSSpec::_scoreDocumentV1(const BSONObj& obj, TermFrequencyMap* term_freqs)
if (leftOverName[0] && x.isABSONObj())
x = dps::extractElementAtPath(x.Obj(), leftOverName);
if (x.type() == String)
- _scoreStringV1(tools, x.valuestr(), term_freqs, weight);
+ _scoreStringV1(tools, x.valueStringData(), term_freqs, weight);
}
} else if (e.type() == String) {
- _scoreStringV1(tools, e.valuestr(), term_freqs, weight);
+ _scoreStringV1(tools, e.valueStringData(), term_freqs, weight);
}
}
}
diff --git a/src/mongo/db/global_settings.cpp b/src/mongo/db/global_settings.cpp
index 57485100d81..02508cbb5de 100644
--- a/src/mongo/db/global_settings.cpp
+++ b/src/mongo/db/global_settings.cpp
@@ -86,7 +86,7 @@ Status AllowListedClusterNetworkSetting::set(const mongo::BSONElement& e) {
if (sub.type() != mongo::String) {
return {ErrorCodes::BadValue, "Expected array of strings"};
}
- allowlistedClusterNetwork->push_back(sub.valuestr());
+ allowlistedClusterNetwork->push_back(sub.str());
}
} else {
return {ErrorCodes::BadValue, "Expected array or null"};
diff --git a/src/mongo/db/index/expression_keys_private.cpp b/src/mongo/db/index/expression_keys_private.cpp
index 336a154151b..f2e3648c971 100644
--- a/src/mongo/db/index/expression_keys_private.cpp
+++ b/src/mongo/db/index/expression_keys_private.cpp
@@ -697,7 +697,7 @@ void ExpressionKeysPrivate::getS2Keys(SharedBufferFragmentBuilder& pooledBufferB
bool lastPathComponentCausesIndexToBeMultikey;
std::vector<KeyString::HeapBuilder> updatedKeysToAdd;
- if (IndexNames::GEO_2DSPHERE_BUCKET == keyElem.valuestr()) {
+ if (IndexNames::GEO_2DSPHERE_BUCKET == keyElem.str()) {
timeseries::dotted_path_support::extractAllElementsAlongBucketPath(
obj,
keyElem.fieldName(),
@@ -738,7 +738,7 @@ void ExpressionKeysPrivate::getS2Keys(SharedBufferFragmentBuilder& pooledBufferB
expandArrayOnTrailingField,
arrayComponents);
- if (IndexNames::GEO_2DSPHERE == keyElem.valuestr()) {
+ if (IndexNames::GEO_2DSPHERE == keyElem.str()) {
if (params.indexVersion >= S2_INDEX_VERSION_2) {
// For >= V2,
// geo: null,
diff --git a/src/mongo/db/index/expression_params.cpp b/src/mongo/db/index/expression_params.cpp
index 5b4223facd6..ddd7a500056 100644
--- a/src/mongo/db/index/expression_params.cpp
+++ b/src/mongo/db/index/expression_params.cpp
@@ -47,7 +47,7 @@ void ExpressionParams::parseTwoDParams(const BSONObj& infoObj, TwoDIndexingParam
while (i.more()) {
BSONElement e = i.next();
- if (e.type() == String && IndexNames::GEO_2D == e.valuestr()) {
+ if (e.type() == String && IndexNames::GEO_2D == e.str()) {
uassert(16800, "can't have 2 geo fields", out->geo.empty());
uassert(16801, "2d has to be first in index", out->other.empty());
out->geo = e.fieldName();
diff --git a/src/mongo/db/index/index_build_interceptor.cpp b/src/mongo/db/index/index_build_interceptor.cpp
index 051d2bdb7f7..a2734b76bad 100644
--- a/src/mongo/db/index/index_build_interceptor.cpp
+++ b/src/mongo/db/index/index_build_interceptor.cpp
@@ -287,8 +287,7 @@ Status IndexBuildInterceptor::_applyWrite(OperationContext* opCtx,
reader,
_indexCatalogEntry->accessMethod()->getSortedDataInterface()->getKeyStringVersion());
- const Op opType =
- (strcmp(operation.getStringField("op"), "i") == 0) ? Op::kInsert : Op::kDelete;
+ const Op opType = operation.getStringField("op") == "i"_sd ? Op::kInsert : Op::kDelete;
const KeyStringSet keySet{keyString};
const RecordId opRecordId = [&]() {
@@ -328,7 +327,7 @@ Status IndexBuildInterceptor::_applyWrite(OperationContext* opCtx,
} else {
invariant(opType == Op::kDelete);
if (kDebugBuild)
- invariant(strcmp(operation.getStringField("op"), "d") == 0);
+ invariant(operation.getStringField("op") == "d"_sd);
int64_t numDeleted;
Status s = accessMethod->removeKeys(
diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp
index a8b60a314d6..4ed1c74f021 100644
--- a/src/mongo/db/index_builds_coordinator.cpp
+++ b/src/mongo/db/index_builds_coordinator.cpp
@@ -496,7 +496,7 @@ std::vector<std::string> IndexBuildsCoordinator::extractIndexNames(
const std::vector<BSONObj>& specs) {
std::vector<std::string> indexNames;
for (const auto& spec : specs) {
- std::string name = spec.getStringField(IndexDescriptor::kIndexNameFieldName);
+ std::string name = spec.getStringField(IndexDescriptor::kIndexNameFieldName).toString();
invariant(!name.empty(),
str::stream() << "Bad spec passed into ReplIndexBuildState constructor, missing '"
<< IndexDescriptor::kIndexNameFieldName << "' field: " << spec);
@@ -533,7 +533,7 @@ Status IndexBuildsCoordinator::_startIndexBuildForRecovery(OperationContext* opC
std::vector<std::string> indexNames;
for (auto& spec : specs) {
- std::string name = spec.getStringField(IndexDescriptor::kIndexNameFieldName);
+ std::string name = spec.getStringField(IndexDescriptor::kIndexNameFieldName).toString();
if (name.empty()) {
return Status(ErrorCodes::CannotCreateIndex,
str::stream()
@@ -661,7 +661,8 @@ Status IndexBuildsCoordinator::_setUpResumeIndexBuild(OperationContext* opCtx,
auto durableCatalog = DurableCatalog::get(opCtx);
for (auto spec : specs) {
- std::string indexName = spec.getStringField(IndexDescriptor::kIndexNameFieldName);
+ std::string indexName =
+ spec.getStringField(IndexDescriptor::kIndexNameFieldName).toString();
if (indexName.empty()) {
return Status(ErrorCodes::CannotCreateIndex,
str::stream()
@@ -859,7 +860,8 @@ void IndexBuildsCoordinator::applyStartIndexBuild(OperationContext* opCtx,
const bool includeUnfinished = false;
for (const auto& spec : oplogEntry.indexSpecs) {
- std::string name = spec.getStringField(IndexDescriptor::kIndexNameFieldName);
+ std::string name =
+ spec.getStringField(IndexDescriptor::kIndexNameFieldName).toString();
uassert(ErrorCodes::BadValue,
str::stream() << "Index spec is missing the 'name' field " << spec,
!name.empty());
diff --git a/src/mongo/db/matcher/expression_leaf.cpp b/src/mongo/db/matcher/expression_leaf.cpp
index 9ecd363b421..9c97567aeca 100644
--- a/src/mongo/db/matcher/expression_leaf.cpp
+++ b/src/mongo/db/matcher/expression_leaf.cpp
@@ -267,7 +267,8 @@ bool RegexMatchExpression::matchesSingleElement(const BSONElement& e, MatchDetai
// String values stored in documents can contain embedded NUL bytes. We construct a
// pcrecpp::StringPiece instance using the full length of the string to avoid truncating
// 'data' early.
- pcrecpp::StringPiece data(e.valuestr(), e.valuestrsize() - 1);
+ auto stringData = e.valueStringData();
+ pcrecpp::StringPiece data{stringData.rawData(), static_cast<int>(stringData.size())};
return _re->PartialMatch(data);
}
case RegEx:
diff --git a/src/mongo/db/operation_context.cpp b/src/mongo/db/operation_context.cpp
index 41881288b9a..d39cb440260 100644
--- a/src/mongo/db/operation_context.cpp
+++ b/src/mongo/db/operation_context.cpp
@@ -203,7 +203,7 @@ namespace {
// specified in the fail point info.
bool opShouldFail(Client* client, const BSONObj& failPointInfo) {
// Only target the client with the specified connection number.
- if (client->desc() != failPointInfo["threadName"].valuestrsafe()) {
+ if (client->desc() != failPointInfo.getStringField("threadName")) {
return false;
}
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index a41f610db04..5e24100be98 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -246,7 +246,7 @@ intrusive_ptr<Expression> Expression::parseOperand(ExpressionContext* const expC
const VariablesParseState& vps) {
BSONType type = exprElement.type();
- if (type == String && exprElement.valuestr()[0] == '$') {
+ if (type == String && exprElement.valueStringData()[0] == '$') {
/* if we got here, this is a field path expression */
return ExpressionFieldPath::parse(expCtx, exprElement.str(), vps);
} else if (type == Object) {
diff --git a/src/mongo/db/query/query_request_helper.cpp b/src/mongo/db/query/query_request_helper.cpp
index 27b0cf5c969..1a602bfb0cd 100644
--- a/src/mongo/db/query/query_request_helper.cpp
+++ b/src/mongo/db/query/query_request_helper.cpp
@@ -204,7 +204,7 @@ bool isTextScoreMeta(BSONElement elt) {
if (mongo::String != metaElt.type()) {
return false;
}
- if (StringData{metaElt.valuestr()} != metaTextScore) {
+ if (metaElt.valueStringData() != metaTextScore) {
return false;
}
// must have exactly 1 element
diff --git a/src/mongo/db/repl/apply_ops.cpp b/src/mongo/db/repl/apply_ops.cpp
index 65b533ba218..8cd9fb586b3 100644
--- a/src/mongo/db/repl/apply_ops.cpp
+++ b/src/mongo/db/repl/apply_ops.cpp
@@ -87,7 +87,7 @@ Status _applyOps(OperationContext* opCtx,
// Apply each op in the given 'applyOps' command object.
for (const auto& opObj : ops) {
// Ignore 'n' operations.
- const char* opType = opObj["op"].valuestrsafe();
+ const char* opType = opObj.getStringField("op").rawData();
if (*opType == 'n')
continue;
diff --git a/src/mongo/db/repl/apply_ops_command_info.cpp b/src/mongo/db/repl/apply_ops_command_info.cpp
index 57144240cdb..97b9e90976e 100644
--- a/src/mongo/db/repl/apply_ops_command_info.cpp
+++ b/src/mongo/db/repl/apply_ops_command_info.cpp
@@ -47,7 +47,7 @@ namespace {
*/
bool _parseAreOpsCrudOnly(const BSONObj& applyOpCmd) {
for (const auto& elem : applyOpCmd.firstElement().Obj()) {
- const char* opType = elem.Obj().getField("op").valuestrsafe();
+ const char* opType = elem.Obj().getStringField("op").rawData();
// All atomic ops have an opType of length 1.
if (opType[0] == '\0' || opType[1] != '\0')
diff --git a/src/mongo/db/repl/collection_cloner.cpp b/src/mongo/db/repl/collection_cloner.cpp
index f38cb4e64c6..530b0773edb 100644
--- a/src/mongo/db/repl/collection_cloner.cpp
+++ b/src/mongo/db/repl/collection_cloner.cpp
@@ -276,7 +276,8 @@ BaseCloner::AfterStageBehavior CollectionCloner::setupIndexBuildersForUnfinished
std::vector<std::string> indexNames;
std::vector<BSONObj> indexSpecs;
for (const auto& indexSpec : groupedIndexSpec.second) {
- std::string indexName = indexSpec.getStringField(IndexDescriptor::kIndexNameFieldName);
+ std::string indexName =
+ indexSpec.getStringField(IndexDescriptor::kIndexNameFieldName).toString();
indexNames.push_back(indexName);
indexSpecs.push_back(indexSpec.getOwned());
}
diff --git a/src/mongo/db/repl/repl_set_commands.cpp b/src/mongo/db/repl/repl_set_commands.cpp
index 7299875254e..fcaedea011c 100644
--- a/src/mongo/db/repl/repl_set_commands.cpp
+++ b/src/mongo/db/repl/repl_set_commands.cpp
@@ -643,7 +643,7 @@ public:
uassertStatusOK(status);
HostAndPort targetHostAndPort;
- status = targetHostAndPort.initialize(cmdObj["replSetSyncFrom"].valuestrsafe());
+ status = targetHostAndPort.initialize(cmdObj.getStringField("replSetSyncFrom"));
uassertStatusOK(status);
uassertStatusOK(ReplicationCoordinator::get(opCtx)->processReplSetSyncFrom(
diff --git a/src/mongo/db/repl/rollback_impl.cpp b/src/mongo/db/repl/rollback_impl.cpp
index 87ce469669e..b4dad5b54ba 100644
--- a/src/mongo/db/repl/rollback_impl.cpp
+++ b/src/mongo/db/repl/rollback_impl.cpp
@@ -412,7 +412,7 @@ StatusWith<std::set<NamespaceString>> RollbackImpl::_namespacesForOp(const Oplog
switch (oplogEntry.getCommandType()) {
case OplogEntry::CommandType::kRenameCollection: {
// Add both the 'from' and 'to' namespaces.
- namespaces.insert(NamespaceString(firstElem.valuestrsafe()));
+ namespaces.insert(NamespaceString(firstElem.valueStringDataSafe()));
namespaces.insert(NamespaceString(obj.getStringField("to")));
break;
}
diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp
index 2bdf56d833f..f76bb325ee5 100644
--- a/src/mongo/db/repl/rs_rollback.cpp
+++ b/src/mongo/db/repl/rs_rollback.cpp
@@ -367,7 +367,7 @@ Status rollback_internal::updateFixUpInfoFromLocalOplogEntry(OperationContext* o
// }
// ...
// }
- NamespaceString collectionNamespace(nss.getSisterNS(first.valuestr()));
+ NamespaceString collectionNamespace(nss.getSisterNS(first.valueStringDataSafe()));
// Registers the collection to be removed from the drop pending collection
// reaper and to be renamed from its drop pending namespace to original namespace.
@@ -388,7 +388,7 @@ Status rollback_internal::updateFixUpInfoFromLocalOplogEntry(OperationContext* o
// ns: "foo.x"
// }
- string ns = nss.db().toString() + '.' + first.valuestr();
+ string ns = nss.db().toString() + '.' + first.str();
string indexName;
auto status = bsonExtractStringField(obj, "index", &indexName);
@@ -607,7 +607,7 @@ Status rollback_internal::updateFixUpInfoFromLocalOplogEntry(OperationContext* o
BSONObj cmd = obj;
- std::string ns = first.valuestrsafe();
+ std::string ns = first.str();
if (ns.empty()) {
static constexpr char message[] = "Collection name missing from oplog entry";
LOGV2(21667, message, "oplogEntry"_attr = redact(obj));
diff --git a/src/mongo/db/repl_index_build_state.cpp b/src/mongo/db/repl_index_build_state.cpp
index 9048112a6dd..d636bd93093 100644
--- a/src/mongo/db/repl_index_build_state.cpp
+++ b/src/mongo/db/repl_index_build_state.cpp
@@ -47,7 +47,7 @@ namespace {
std::vector<std::string> extractIndexNames(const std::vector<BSONObj>& specs) {
std::vector<std::string> indexNames;
for (const auto& spec : specs) {
- std::string name = spec.getStringField(IndexDescriptor::kIndexNameFieldName);
+ std::string name = spec.getStringField(IndexDescriptor::kIndexNameFieldName).toString();
invariant(!name.empty(),
str::stream() << "Bad spec passed into ReplIndexBuildState constructor, missing '"
<< IndexDescriptor::kIndexNameFieldName << "' field: " << spec);
diff --git a/src/mongo/db/s/config/sharding_catalog_manager_shard_operations.cpp b/src/mongo/db/s/config/sharding_catalog_manager_shard_operations.cpp
index ed00416ef5d..9c8f449399c 100644
--- a/src/mongo/db/s/config/sharding_catalog_manager_shard_operations.cpp
+++ b/src/mongo/db/s/config/sharding_catalog_manager_shard_operations.cpp
@@ -327,7 +327,7 @@ StatusWith<ShardType> ShardingCatalogManager::_validateHostAsShard(
auto resIsMaster = std::move(swCommandResponse.getValue().response);
// Fail if the node being added is a mongos.
- const std::string msg = resIsMaster.getStringField("msg");
+ const std::string msg = resIsMaster.getStringField("msg").toString();
if (msg == "isdbgrid") {
return {ErrorCodes::IllegalOperation, "cannot add a mongos as a shard"};
}
diff --git a/src/mongo/db/storage/bson_collection_catalog_entry.cpp b/src/mongo/db/storage/bson_collection_catalog_entry.cpp
index fca3b271332..b5527947067 100644
--- a/src/mongo/db/storage/bson_collection_catalog_entry.cpp
+++ b/src/mongo/db/storage/bson_collection_catalog_entry.cpp
@@ -238,7 +238,7 @@ BSONObj BSONCollectionCatalogEntry::MetaData::toBSON(bool hasExclusiveAccess) co
}
void BSONCollectionCatalogEntry::MetaData::parse(const BSONObj& obj) {
- ns = obj["ns"].valuestrsafe();
+ ns = obj.getStringField("ns").toString();
if (obj["options"].isABSONObj()) {
options = uassertStatusOK(
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_sorted_impl.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_sorted_impl.cpp
index 0c89471b5bd..76c659b4f7a 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_sorted_impl.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_sorted_impl.cpp
@@ -450,7 +450,7 @@ BSONObj createObjFromRadixKey(const std::string& radixKey,
auto it = BSONObjIterator(bsonObj);
++it; // We want the second part
KeyString::Builder ks(version);
- ks.resetFromBuffer((*it).valuestr(), (*it).valuestrsize());
+ ks.resetFromBuffer((*it).valueStringDataSafe().rawData(), (*it).valueStringDataSafe().size());
return KeyString::toBsonSafe(ks.getBuffer(), ks.getSize(), order, typeBits);
}
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
index a4046d08846..150d27ef2cf 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
@@ -1567,7 +1567,7 @@ Status WiredTigerKVEngine::createSortedDataInterface(OperationContext* opCtx,
if (auto storageEngineOptions = collOptions.indexOptionDefaults.getStorageEngine()) {
collIndexOptions =
dps::extractElementAtPath(*storageEngineOptions, _canonicalName + ".configString")
- .valuestrsafe();
+ .str();
}
// Some unittests use a OperationContextNoop that can't support such lookups.
auto ns = collOptions.uuid
diff --git a/src/mongo/db/timeseries/bucket_catalog.cpp b/src/mongo/db/timeseries/bucket_catalog.cpp
index 3c0c3b37ec7..9b06cdbdc33 100644
--- a/src/mongo/db/timeseries/bucket_catalog.cpp
+++ b/src/mongo/db/timeseries/bucket_catalog.cpp
@@ -88,8 +88,7 @@ void normalizeObject(BSONObjBuilder* builder, const BSONObj& obj) {
BSONElement element() const {
return BSONElement(fieldName.rawData() - 1, // Include type byte before field name
fieldName.size() + 1, // Include null terminator after field name
- totalSize,
- BSONElement::CachedSizeTag{});
+ totalSize);
}
bool operator<(const Field& rhs) const {
return fieldName < rhs.fieldName;
diff --git a/src/mongo/db/timeseries/flat_bson.cpp b/src/mongo/db/timeseries/flat_bson.cpp
index 595dde0942f..e5b15133b1e 100644
--- a/src/mongo/db/timeseries/flat_bson.cpp
+++ b/src/mongo/db/timeseries/flat_bson.cpp
@@ -673,7 +673,7 @@ void FlatBSON<Derived, Element, Value>::_setTypeArray(
}
BSONElement BSONElementValue::get() const {
- return BSONElement(_buffer.get(), 1, _size, BSONElement::CachedSizeTag{});
+ return BSONElement(_buffer.get(), 1, _size);
}
void BSONElementValue::set(const BSONElement& elem) {
diff --git a/src/mongo/db/write_concern_options.cpp b/src/mongo/db/write_concern_options.cpp
index baf56a1a669..53883d0cba0 100644
--- a/src/mongo/db/write_concern_options.cpp
+++ b/src/mongo/db/write_concern_options.cpp
@@ -179,7 +179,7 @@ StatusWith<WriteConcernOptions> WriteConcernOptions::parse(const BSONObj& obj) {
writeConcern.notExplicitWValue = false;
} else if (wEl.type() == String) {
writeConcern.wNumNodes = 0;
- writeConcern.wMode = wEl.valuestrsafe();
+ writeConcern.wMode = wEl.str();
writeConcern.notExplicitWValue = false;
} else if (wEl.eoo() || wEl.type() == jstNULL || wEl.type() == Undefined) {
writeConcern.wNumNodes = 1;
diff --git a/src/mongo/dbtests/commandtests.cpp b/src/mongo/dbtests/commandtests.cpp
index 2e354795911..5f0518c2776 100644
--- a/src/mongo/dbtests/commandtests.cpp
+++ b/src/mongo/dbtests/commandtests.cpp
@@ -135,7 +135,7 @@ struct Type0 : Base {
BSONObj result;
ASSERT(db.runCommand("test", BSON("filemd5" << 0), result));
- ASSERT_EQUALS(string("5eb63bbbe01eeed093cb22bb8f5acdc3"), result["md5"].valuestr());
+ ASSERT_EQUALS(string("5eb63bbbe01eeed093cb22bb8f5acdc3"), result.getStringField("md5"));
}
};
struct Type2 : Base {
@@ -159,7 +159,7 @@ struct Type2 : Base {
BSONObj result;
ASSERT(db.runCommand("test", BSON("filemd5" << 0), result));
- ASSERT_EQUALS(string("5eb63bbbe01eeed093cb22bb8f5acdc3"), result["md5"].valuestr());
+ ASSERT_EQUALS(string("5eb63bbbe01eeed093cb22bb8f5acdc3"), result.getStringField("md5"));
}
};
} // namespace FileMD5
diff --git a/src/mongo/dbtests/jsobjtests.cpp b/src/mongo/dbtests/jsobjtests.cpp
index 99f984e0c87..0c20c6f0f9b 100644
--- a/src/mongo/dbtests/jsobjtests.cpp
+++ b/src/mongo/dbtests/jsobjtests.cpp
@@ -843,9 +843,10 @@ class WrongStringSize : public Base {
}
BSONObj invalid() const {
BSONObj ret = valid();
- ASSERT_EQUALS(ret.firstElement().valuestr()[0], 'b');
- ASSERT_EQUALS(ret.firstElement().valuestr()[1], 0);
- ((char*)ret.firstElement().valuestr())[1] = 1;
+ ASSERT_TRUE(ret.firstElement().valueStringData().size() >= 1);
+ ASSERT_EQUALS(ret.firstElement().valueStringData()[0], 'b');
+ ASSERT_EQUALS(ret.firstElement().valueStringData()[1], 0);
+ ((char*)ret.firstElement().valueStringData().rawData())[1] = 1;
return ret.copy();
}
};
diff --git a/src/mongo/dbtests/jsontests.cpp b/src/mongo/dbtests/jsontests.cpp
index 334bb3730d9..cb16219f51d 100644
--- a/src/mongo/dbtests/jsontests.cpp
+++ b/src/mongo/dbtests/jsontests.cpp
@@ -728,7 +728,7 @@ TEST(FromJsonTest, Utf8Test) {
using namespace std::literals::string_literals;
const std::string u = "\xea\x80\x80\xea\x80\x80"s;
BSONObj built = B().append("a", u).obj();
- ASSERT_EQUALS(built.firstElement().valuestr(), u);
+ ASSERT_EQUALS(built.firstElement().str(), u);
checkEquivalenceEach({
// EscapedUnicodeToUtf8
diff --git a/src/mongo/dbtests/jstests.cpp b/src/mongo/dbtests/jstests.cpp
index 7a6522c5c81..38a33c35472 100644
--- a/src/mongo/dbtests/jstests.cpp
+++ b/src/mongo/dbtests/jstests.cpp
@@ -234,7 +234,7 @@ public:
s->invoke("z = { x : 'eliot' };", nullptr, nullptr);
out = s->getObject("z");
- ASSERT_EQUALS((string) "eliot", out["x"].valuestr());
+ ASSERT_EQUALS("eliot", out["x"].str());
ASSERT_EQUALS(1, out.nFields());
BSONObj o = BSON("x" << 17);
@@ -598,7 +598,7 @@ public:
out = s->getObject("c");
stringstream ss;
ss << "NumberLong(\"" << val << "\")";
- ASSERT_EQUALS(ss.str(), out.firstElement().valuestr());
+ ASSERT_EQUALS(ss.str(), out.firstElement().str());
ASSERT(s->exec("d = {d:a.a.toNumber()}", "foo", false, true, false));
out = s->getObject("d");
@@ -688,7 +688,7 @@ public:
out = s->getObject("c");
stringstream ss;
ss << "NumberLong(\"" << val << "\")";
- ASSERT_EQUALS(ss.str(), out.firstElement().valuestr());
+ ASSERT_EQUALS(ss.str(), out.firstElement().str());
ASSERT(s->exec("d = {d:a.a.toNumber()}", "foo", false, true, false));
out = s->getObject("d");
@@ -732,7 +732,7 @@ public:
out = s->getObject("c");
stringstream ss;
ss << "NumberDecimal(\"" << val.toString() << "\")";
- ASSERT_EQUALS(ss.str(), out.firstElement().valuestr());
+ ASSERT_EQUALS(ss.str(), out.firstElement().str());
}
};
diff --git a/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp b/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp
index 3785a11754e..7d728bf451a 100644
--- a/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp
+++ b/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp
@@ -368,7 +368,7 @@ TEST_F(MongodbCAPITest, KillOp) {
// See if we find the sleep command among the running commands
for (const auto& elt : inprog) {
auto inprogObj = inprog.getObjectField(elt.fieldNameStringData());
- std::string ns = inprogObj.getStringField("ns");
+ std::string ns = inprogObj.getStringField("ns").toString();
if (ns == "admin.$cmd") {
opid = inprogObj.getIntField("opid");
break;
diff --git a/src/mongo/idl/basic_types.h b/src/mongo/idl/basic_types.h
index e674b8ae1d4..d77ae561376 100644
--- a/src/mongo/idl/basic_types.h
+++ b/src/mongo/idl/basic_types.h
@@ -190,7 +190,7 @@ public:
if (wEl.isNumber()) {
return WriteConcernW{wEl.safeNumberLong()};
} else if (wEl.type() == BSONType::String) {
- return WriteConcernW{wEl.valuestrsafe()};
+ return WriteConcernW{wEl.str()};
} else if (wEl.eoo() || wEl.type() == BSONType::jstNULL ||
wEl.type() == BSONType::Undefined) {
return WriteConcernW{};
diff --git a/src/mongo/rpc/op_msg_integration_test.cpp b/src/mongo/rpc/op_msg_integration_test.cpp
index 3f235f58388..ee6cc857d6a 100644
--- a/src/mongo/rpc/op_msg_integration_test.cpp
+++ b/src/mongo/rpc/op_msg_integration_test.cpp
@@ -82,7 +82,7 @@ std::string getThreadNameByAppName(DBClientBase* conn, StringData appName) {
const auto cursorResponse = CursorResponse::parseFromBSON(curOpReply->getCommandReply());
ASSERT_OK(cursorResponse.getStatus());
const auto batch = cursorResponse.getValue().getBatch();
- return batch.empty() ? "" : batch[0].getStringField("desc");
+ return batch.empty() ? "" : batch[0].getStringField("desc").toString();
}
TEST(OpMsg, UnknownRequiredFlagClosesConnection) {
diff --git a/src/mongo/s/request_types/add_shard_request_type.cpp b/src/mongo/s/request_types/add_shard_request_type.cpp
index 3860552a63a..fbb77b17f66 100644
--- a/src/mongo/s/request_types/add_shard_request_type.cpp
+++ b/src/mongo/s/request_types/add_shard_request_type.cpp
@@ -82,7 +82,7 @@ StatusWith<AddShardRequest> AddShardRequest::parseInternalFields(const BSONObj&
<< " must be a string"};
}
- auto swConnString = ConnectionString::parse(firstElement.valuestrsafe());
+ auto swConnString = ConnectionString::parse(firstElement.str());
if (!swConnString.isOK()) {
return swConnString.getStatus();
}
diff --git a/src/mongo/s/transaction_router_test.cpp b/src/mongo/s/transaction_router_test.cpp
index e92b32860e1..7c4c0c20cda 100644
--- a/src/mongo/s/transaction_router_test.cpp
+++ b/src/mongo/s/transaction_router_test.cpp
@@ -1523,7 +1523,7 @@ TEST_F(TransactionRouterTestWithDefaultSession,
ASSERT_EQ(expectedParticipants.size(), participantElements.size());
for (const auto& element : participantElements) {
- auto shardId = element["shardId"].valuestr();
+ auto shardId = element["shardId"].str();
ASSERT_EQ(1ull, expectedParticipants.count(shardId));
expectedParticipants.erase(shardId);
}
@@ -1575,7 +1575,7 @@ TEST_F(TransactionRouterTestWithDefaultSession,
ASSERT_EQ(expectedParticipants.size(), participantElements.size());
for (const auto& element : participantElements) {
- auto shardId = element["shardId"].valuestr();
+ auto shardId = element["shardId"].str();
ASSERT_EQ(1ull, expectedParticipants.count(shardId));
expectedParticipants.erase(shardId);
}
@@ -1741,7 +1741,7 @@ TEST_F(TransactionRouterTestWithDefaultSession,
ASSERT_EQ(expectedParticipants.size(), participantElements.size());
for (const auto& element : participantElements) {
- auto shardId = element["shardId"].valuestr();
+ auto shardId = element["shardId"].str();
ASSERT_EQ(1ull, expectedParticipants.count(shardId));
expectedParticipants.erase(shardId);
}
@@ -1803,7 +1803,7 @@ TEST_F(TransactionRouterTestWithDefaultSession,
ASSERT_EQ(expectedParticipants.size(), participantElements.size());
for (const auto& element : participantElements) {
- auto shardId = element["shardId"].valuestr();
+ auto shardId = element["shardId"].str();
ASSERT_EQ(1ull, expectedParticipants.count(shardId));
expectedParticipants.erase(shardId);
}
diff --git a/src/mongo/scripting/engine.cpp b/src/mongo/scripting/engine.cpp
index c7808f1a9f5..e78a71a48d4 100644
--- a/src/mongo/scripting/engine.cpp
+++ b/src/mongo/scripting/engine.cpp
@@ -256,9 +256,9 @@ void Scope::loadStored(OperationContext* opCtx, bool ignoreNotConnected) {
}
try {
- setElement(n.valuestr(), v, o);
- thisTime.insert(n.valuestr());
- _storedNames.insert(n.valuestr());
+ setElement(n.valueStringDataSafe().rawData(), v, o);
+ thisTime.insert(n.str());
+ _storedNames.insert(n.str());
} catch (const DBException& setElemEx) {
if (setElemEx.code() == ErrorCodes::Interrupted) {
throw;
@@ -266,7 +266,7 @@ void Scope::loadStored(OperationContext* opCtx, bool ignoreNotConnected) {
LOGV2_ERROR(22781,
"unable to load stored JavaScript function {n_valuestr}(): {setElemEx}",
- "n_valuestr"_attr = n.valuestr(),
+ "n_valuestr"_attr = n.valueStringDataSafe(),
"setElemEx"_attr = redact(setElemEx));
}
}
diff --git a/src/mongo/scripting/utils.cpp b/src/mongo/scripting/utils.cpp
index 51b084c44f0..08e08f3f6d7 100644
--- a/src/mongo/scripting/utils.cpp
+++ b/src/mongo/scripting/utils.cpp
@@ -40,12 +40,12 @@ static BSONObj native_hex_md5(const BSONObj& args, void* data) {
uassert(10261,
"hex_md5 takes a single string argument -- hex_md5(string)",
args.nFields() == 1 && args.firstElement().type() == String);
- const char* s = args.firstElement().valuestrsafe();
+ StringData sd = args.firstElement().valueStringDataSafe();
md5digest d;
md5_state_t st;
md5_init(&st);
- md5_append(&st, (const md5_byte_t*)s, strlen(s));
+ md5_append(&st, reinterpret_cast<const md5_byte_t*>(sd.rawData()), sd.size());
md5_finish(&st, d);
return BSON("" << digestToString(d));
diff --git a/src/mongo/shell/shell_utils.cpp b/src/mongo/shell/shell_utils.cpp
index 79f89b28c57..8789168f3c8 100644
--- a/src/mongo/shell/shell_utils.cpp
+++ b/src/mongo/shell/shell_utils.cpp
@@ -446,8 +446,8 @@ BSONObj replMonitorStats(const BSONObj& a, void* data) {
"replMonitorStats requires a single string argument (the ReplSet name)",
a.nFields() == 1 && a.firstElement().type() == String);
- auto name = a.firstElement().valuestrsafe();
- auto rsm = ReplicaSetMonitor::get(name);
+ auto name = a.firstElement().valueStringDataSafe();
+ auto rsm = ReplicaSetMonitor::get(name.toString());
if (!rsm) {
return BSON(""
<< "no ReplSetMonitor exists by that name");
@@ -482,7 +482,7 @@ BSONObj fileExistsJS(const BSONObj& a, void*) {
uassert(40678,
"fileExists expects one string argument",
a.nFields() == 1 && a.firstElement().type() == String);
- return BSON("" << fileExists(a.firstElement().valuestrsafe()));
+ return BSON("" << fileExists(a.firstElement().str()));
}
BSONObj isInteractive(const BSONObj& a, void*) {
diff --git a/src/mongo/shell/shell_utils_extended.cpp b/src/mongo/shell/shell_utils_extended.cpp
index fbdddc1318d..6cd6dc6ed0d 100644
--- a/src/mongo/shell/shell_utils_extended.cpp
+++ b/src/mongo/shell/shell_utils_extended.cpp
@@ -77,7 +77,7 @@ BSONObj listFiles(const BSONObj& _args, void* data) {
BSONArrayBuilder lst;
- string rootname = args.firstElement().valuestrsafe();
+ string rootname = args.firstElement().str();
boost::filesystem::path root(rootname);
stringstream ss;
ss << "listFiles: no such directory: " << rootname;
@@ -178,16 +178,16 @@ BSONObj cat(const BSONObj& args, void* data) {
mode |= std::ios::binary;
}
- ifstream f(filePath.valuestrsafe(), mode);
- uassert(CANT_OPEN_FILE, "couldn't open file {}"_format(filePath.valuestrsafe()), f.is_open());
+ ifstream f(filePath.valueStringDataSafe().rawData(), mode);
+ uassert(CANT_OPEN_FILE, "couldn't open file {}"_format(filePath.str()), f.is_open());
std::streamsize fileSize = 0;
// will throw on filesystem error
- fileSize = boost::filesystem::file_size(filePath.valuestrsafe());
+ fileSize = boost::filesystem::file_size(filePath.str());
static constexpr auto kFileSizeLimit = 1024 * 1024 * 16;
uassert(
13301,
"cat() : file {} too big to load as a variable (file is {} bytes, limit is {} bytes.)"_format(
- filePath.valuestrsafe(), fileSize, kFileSizeLimit),
+ filePath.str(), fileSize, kFileSizeLimit),
fileSize < kFileSizeLimit);
std::ostringstream ss;
@@ -252,8 +252,8 @@ BSONObj copyFileRange(const BSONObj& args, void* data) {
BSONObj md5sumFile(const BSONObj& args, void* data) {
BSONElement e = singleArg(args);
stringstream ss;
- FILE* f = fopen(e.valuestrsafe(), "rb");
- uassert(CANT_OPEN_FILE, str::stream() << "couldn't open file " << e.valuestrsafe(), f);
+ FILE* f = fopen(e.valueStringDataSafe().rawData(), "rb");
+ uassert(CANT_OPEN_FILE, str::stream() << "couldn't open file " << e.str(), f);
ON_BLOCK_EXIT([&] { fclose(f); });
md5digest d;
@@ -315,7 +315,7 @@ BSONObj removeFile(const BSONObj& args, void* data) {
BSONElement e = singleArg(args);
bool found = false;
- boost::filesystem::path root(e.valuestrsafe());
+ boost::filesystem::path root(e.str());
if (boost::filesystem::exists(root)) {
found = true;
boost::filesystem::remove_all(root);
diff --git a/src/mongo/shell/shell_utils_launcher.cpp b/src/mongo/shell/shell_utils_launcher.cpp
index 65532f18632..d45b2eda43d 100644
--- a/src/mongo/shell/shell_utils_launcher.cpp
+++ b/src/mongo/shell/shell_utils_launcher.cpp
@@ -401,7 +401,7 @@ ProgramRunner::ProgramRunner(const BSONObj& args, const BSONObj& env, bool isMon
"cannot pass an empty argument to ProgramRunner",
!args.isEmpty());
- string program(args.firstElement().valuestrsafe());
+ string program(args.firstElement().str());
uassert(ErrorCodes::FailedToParse,
"invalid program name passed to ProgramRunner",
!program.empty());
@@ -455,7 +455,7 @@ ProgramRunner::ProgramRunner(const BSONObj& args, const BSONObj& env, bool isMon
uassert(ErrorCodes::FailedToParse,
"Program arguments must be strings",
e.type() == mongo::String);
- str = e.valuestr();
+ str = e.str();
}
if (isMongo) {
if (str == "--port") {
@@ -476,7 +476,7 @@ ProgramRunner::ProgramRunner(const BSONObj& args, const BSONObj& env, bool isMon
"Environment variable values must be strings",
e.type() == mongo::String);
- _envp.emplace(std::string(e.fieldName()), std::string(e.valuestr()));
+ _envp.emplace(std::string(e.fieldName()), e.str());
}
// Import this process' environment into _envp, for all keys that have not already been set.
@@ -935,7 +935,7 @@ BSONObj RunNonMongoProgram(const BSONObj& a, void* data) {
BSONObj ResetDbpath(const BSONObj& a, void* data) {
uassert(ErrorCodes::FailedToParse, "Expected 1 field", a.nFields() == 1);
- string path = a.firstElement().valuestrsafe();
+ string path = a.firstElement().str();
if (path.empty()) {
LOGV2_WARNING(22824, "ResetDbpath(): nothing to do, path was empty");
return undefinedReturn;
@@ -980,7 +980,7 @@ BSONObj ResetDbpath(const BSONObj& a, void* data) {
BSONObj PathExists(const BSONObj& a, void* data) {
uassert(ErrorCodes::FailedToParse, "Expected 1 field", a.nFields() == 1);
- string path = a.firstElement().valuestrsafe();
+ string path = a.firstElement().str();
if (path.empty()) {
LOGV2_WARNING(22825, "PathExists(): path was empty");
return BSON(string("") << false);
diff --git a/src/mongo/util/fail_point.cpp b/src/mongo/util/fail_point.cpp
index cfc6f60d0d4..0d6875d4c9a 100644
--- a/src/mongo/util/fail_point.cpp
+++ b/src/mongo/util/fail_point.cpp
@@ -167,7 +167,7 @@ StatusWith<FailPoint::ModeOptions> FailPoint::parseBSON(const BSONObj& obj) {
if (modeElem.eoo()) {
return {ErrorCodes::IllegalOperation, "When setting a failpoint, you must supply a 'mode'"};
} else if (modeElem.type() == String) {
- const std::string modeStr(modeElem.valuestr());
+ const std::string modeStr(modeElem.str());
if (modeStr == "off") {
mode = FailPoint::off;
} else if (modeStr == "alwaysOn") {