void storageValid(mutablebson::ConstElement elem, const bool deep, std::uint32_t recursionLevel) { uassert(ErrorCodes::BadValue, "Invalid elements cannot be stored.", elem.ok()); uassert(ErrorCodes::Overflow, str::stream() << "Document exceeds maximum nesting depth of " << BSONDepth::getMaxDepthForUserStorage(), recursionLevel <= BSONDepth::getMaxDepthForUserStorage()); // Field names of elements inside arrays are not meaningful in mutable bson, // so we do not want to validate them. const mutablebson::ConstElement& parent = elem.parent(); const bool childOfArray = parent.ok() ? (parent.getType() == BSONType::Array) : false; if (!childOfArray) { auto fieldName = elem.getFieldName(); // Cannot start with "$", unless dbref. if (fieldName[0] == '$') { validateDollarPrefixElement(elem); } } if (deep) { // Check children if there are any. storageValidChildren(elem, deep, recursionLevel); } }
Status storageValid(const mb::ConstElement& elem, const bool deep) { if (!elem.ok()) return Status(ErrorCodes::BadValue, "Invalid elements cannot be stored."); // Field names of elements inside arrays are not meaningful in mutable bson, // so we do not want to validate them. // // TODO: Revisit how mutable handles array field names. We going to need to make // this better if we ever want to support ordered updates that can alter the same // element repeatedly; see SERVER-12848. const mb::ConstElement& parent = elem.parent(); const bool childOfArray = parent.ok() ? (parent.getType() == mongo::Array) : false; if (!childOfArray) { StringData fieldName = elem.getFieldName(); // Cannot start with "$", unless dbref if (fieldName[0] == '$') { Status status = validateDollarPrefixElement(elem, deep); if (!status.isOK()) return status; } else if (fieldName.find(".") != string::npos) { // Field name cannot have a "." in it. return Status(ErrorCodes::DottedFieldName, str::stream() << "The dotted field '" << elem.getFieldName() << "' in '" << mb::getFullName(elem) << "' is not valid for storage."); } } if (deep) { // Check children if there are any. Status s = storageValidChildren(elem, deep); if (!s.isOK()) return s; } return Status::OK(); }