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); } }
void UnsetNode::validateUpdate(mutablebson::ConstElement updatedElement, mutablebson::ConstElement leftSibling, mutablebson::ConstElement rightSibling, std::uint32_t recursionLevel, ModifyResult modifyResult) const { invariant(modifyResult == ModifyResult::kNormalUpdate); // We only need to check the left and right sibling to see if the removed element was part of a // now invalid DBRef. const bool doRecursiveCheck = false; const uint32_t recursionLevelForCheck = 0; if (leftSibling.ok()) { storage_validation::storageValid(leftSibling, doRecursiveCheck, recursionLevelForCheck); } if (rightSibling.ok()) { storage_validation::storageValid(rightSibling, doRecursiveCheck, recursionLevelForCheck); } }