Skip to content

Commit

Permalink
Explicitly check for null values in C# jsonization
Browse files Browse the repository at this point in the history
We explicitly check that both optional and required properties can not
be set to ``null``. The optional properties should be explicitly absent
from the object by specification, and thus ``null`` is not an acceptable
value for optional properties.
  • Loading branch information
mristin committed Sep 3, 2024
1 parent b14237b commit 47cc19d
Show file tree
Hide file tree
Showing 2 changed files with 1,931 additions and 301 deletions.
48 changes: 37 additions & 11 deletions aas_core_codegen/csharp/jsonization/_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def _generate_from_method_for_interface(
if (obj == null)
{{
{I}error = new Reporting.Error(
{II}"Expected Nodes.JsonObject, but got {{node.GetType()}}");
{II}$"Expected Nodes.JsonObject, but got {{node.GetType()}}");
{I}return null;
}}"""
),
Expand Down Expand Up @@ -336,6 +336,42 @@ def _generate_deserialize_constructor_argument(
else:
assert_never(arg.type_annotation)

# NOTE (mristin):
# We need to add a prologue to the parsing body to explicitly check for null
# values as the null values are not allowed for optional properties by
# specification.
if isinstance(arg.type_annotation, intermediate.OptionalTypeAnnotation):
parse_block = Stripped(
f"""\
if (keyValue.Value == null)
{{
{I}error = new Reporting.Error(
{II}"Expected optional property to be absent, " +
{II}"but got null instead");
{I}error.PrependSegment(
{II}new Reporting.NameSegment(
{III}{json_literal}));
{I}return null;
}}
{parse_block}"""
)
else:
parse_block = Stripped(
f"""\
if (keyValue.Value == null)
{{
{I}error = new Reporting.Error(
{II}"Unexpected null for a required property");
{I}error.PrependSegment(
{II}new Reporting.NameSegment(
{III}{json_literal}));
{I}return null;
}}
{parse_block}"""
)

return parse_block, None


Expand Down Expand Up @@ -398,21 +434,11 @@ def _generate_from_method_for_class(
assert case_body is not None
json_name = naming.json_property(arg.name)

# NOTE (mristin, 2022-07-23):
# We put ``if (keyValue.Value != null)`` here instead of the outer loop
# since we want to detect the unexpected additional properties even
# though their value can be set to null.

cases.append(
Stripped(
f"""\
case {csharp_common.string_literal(json_name)}:
{{
{I}if (keyValue.Value == null)
{I}{{
{II}continue;
{I}}}
{I}{indent_but_first_line(case_body, I)}
{I}break;
}}"""
Expand Down
Loading

0 comments on commit 47cc19d

Please sign in to comment.