summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLingzhi Deng <lingzhi.deng@mongodb.com>2020-11-09 20:32:26 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-11-10 04:00:23 +0000
commita36a312b744a419a3e065df99abb8c232bc93267 (patch)
tree9fa36ab142ee4d7a15573a65f95595024acb27c4
parent21b2bc7ecb9b16d1043b2a6fe845127637ea3467 (diff)
downloadmongo-a36a312b744a419a3e065df99abb8c232bc93267.tar.gz
SERVER-52679: Disallow null/undefined command parameter for IDL commands with {namespace: type}
-rw-r--r--buildscripts/idl/idl/generator.py12
-rw-r--r--src/mongo/idl/idl_test.cpp8
2 files changed, 17 insertions, 3 deletions
diff --git a/buildscripts/idl/idl/generator.py b/buildscripts/idl/idl/generator.py
index caf340a9c3c..70eb1e00499 100644
--- a/buildscripts/idl/idl/generator.py
+++ b/buildscripts/idl/idl/generator.py
@@ -1163,9 +1163,11 @@ class _CppSourceFileWriter(_CppFileWriterBase):
if _is_required_serializer_field(field):
self._writer.write_line('%s = true;' % (_get_has_field_member_name(field)))
- def gen_field_deserializer(self, field, bson_object, bson_element, field_usage_check):
- # type: (ast.Field, str, str, _FieldUsageCheckerBase) -> None
+ def gen_field_deserializer(self, field, bson_object, bson_element, field_usage_check,
+ is_command_field=False):
+ # type: (ast.Field, str, str, _FieldUsageCheckerBase, bool) -> None
"""Generate the C++ deserializer piece for a field."""
+ # pylint: disable=too-many-arguments
if field.array:
self._gen_usage_check(field, bson_element, field_usage_check)
@@ -1223,6 +1225,10 @@ class _CppSourceFileWriter(_CppFileWriterBase):
_get_field_member_setter_name(field), object_value))
else:
validate_and_assign_or_uassert(field, object_value)
+ if is_command_field and predicate:
+ with self._block('else {', '}'):
+ self._writer.write_line(
+ 'ctxt.throwMissingField(%s);' % (_get_field_constant_name(field)))
def gen_doc_sequence_deserializer(self, field):
# type: (ast.Field) -> None
@@ -1345,7 +1351,7 @@ class _CppSourceFileWriter(_CppFileWriterBase):
if isinstance(struct, ast.Command) and struct.command_field:
with self._block('{', '}'):
self.gen_field_deserializer(struct.command_field, bson_object, "commandElement",
- None)
+ None, is_command_field=True)
else:
struct_type_info = struct_types.get_struct_info(struct)
diff --git a/src/mongo/idl/idl_test.cpp b/src/mongo/idl/idl_test.cpp
index 6bfb54782f9..206aa0b5aaf 100644
--- a/src/mongo/idl/idl_test.cpp
+++ b/src/mongo/idl/idl_test.cpp
@@ -2837,6 +2837,14 @@ TEST(IDLTypeCommand, TestStruct) {
assert_same_types<decltype(testStruct.getCommandParameter()),
mongo::idl::import::One_string&>();
+ // Negative: Command with struct parameter should disallow 'undefined' input.
+ {
+ auto invalidDoc = BSON(CommandTypeStructCommand::kCommandName << BSONUndefined << "$db"
+ << "db");
+ ASSERT_THROWS(CommandTypeStructCommand::parse(ctxt, makeOMR(invalidDoc)),
+ AssertionException);
+ }
+
// Positive: Test we can roundtrip from the just parsed document
{
BSONObjBuilder builder;