Skip to content

Conversation

@steveharter
Copy link
Contributor

@steveharter steveharter commented Sep 7, 2021

Addresses #58221 for main. This PR is expected to be ported to 6.0.

Note that there is a single public API method addition for interop between generated code and STJ. This API is not expected to be controversial since it is not used by consumers and is consistent with other interop methods in the same location. It will be covered by @layomia in the next API review.

Also addresses:

  • Besides IAsyncEnumerable, we also throw on other known invalid types (that the serializer also throws on) including DateOnly, TimeOnly IntPtr, UIntPtr, Type, and SerializationInfo.
  • Fixes a JsonPath issue with the source generator where the "root" path of "$" was always returned during serialization when configured with a metadata-based context. This code is in the STJ assembly, not the STJ.SourceGeneration assembly.

The existing "disallowed" tests that only ran on the serializer were converted to also run on source gen. The tests were expanded to:

  • Add IAsyncEnumerable for source-gen tests.
  • Ensure any user-provided custom converters for these unsupported types will be called and not throw the default NotSupportedException.
  • Verify Nullable<T> semantics are correct for the unsupported types that are value types.

The exception thrown is the same as what the serializer throws. E.g.:

System.NotSupportedException: 'Serialization and deserialization of 'System.Collections.Generic.IAsyncEnumerable`1[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' instances are not supported. The unsupported member type is located on type 'System.Collections.Generic.IAsyncEnumerable`1[System.Int32]'. Path: $.Values.'```

@ghost
Copy link

ghost commented Sep 7, 2021

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@ghost
Copy link

ghost commented Sep 7, 2021

Tagging subscribers to this area: @eiriktsarpalis, @layomia
See info in area-owners.md if you want to be subscribed.

Issue Details

Addresses #58221 for main. This PR is expected to be ported to 6.0.

Note that there is a single public API method addition for interop between generated code and STJ. This API is not expected to be controversial since it is not used by consumers and is consistent with other interop methods in the same location. It will be covered by @layomia in the next API review.

Also addresses:

  • Other known invalid types (that the serializer knows about) including DateOnly, TimeOnly IntPtr, UIntPtr, Type, and SerializationInfo.
  • Fixes a JsonPath issue with the source generator where the "root" path of "$" was always returned during serialization when configured with a metadata-based context. This code is in the STJ assembly, not the STJ.SourceGeneration assembly.

The existing "disallowed" tests that only ran on the serializer were converted to also run on source gen. The tests were expanded to:

  • Add IAsyncEnumerable for source-gen tests.
  • Ensure any user-provided custom converters for these unsupported types will be called and not throw the default NotSupportedException.
  • Verify Nullable<T> semantics are correct for the unsupported types that are value types.

The exception thrown is the same as what the serializer throws. E.g.:

System.NotSupportedException: 'Serialization and deserialization of 'System.Collections.Generic.IAsyncEnumerable`1[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' instances are not supported and should be avoided since they can lead to security issues. The unsupported member type is located on type 'System.Collections.Generic.IAsyncEnumerable`1[System.Int32]'. Path: $.Values.'```

<table>
  <tr>
    <th align="left">Author:</th>
    <td>steveharter</td>
  </tr>
  <tr>
    <th align="left">Assignees:</th>
    <td>-</td>
  </tr>
  <tr>
    <th align="left">Labels:</th>
    <td>

`area-System.Text.Json`, `new-api-needs-documentation`

</td>
  </tr>
  <tr>
    <th align="left">Milestone:</th>
    <td>-</td>
  </tr>
</table>
</details>

Copy link
Contributor

@layomia layomia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with minor questions

{
// If a value type is added, also add a test that
// shows NSE is thrown when Nullable<T> is (de)serialized.
// If a type is added, also add to the souce-gen project.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should update the exception message since not all these types have security issues & could be supported in the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, that message is maybe weasel words? eg "since they can lead to security issues" --> "because it is insecure"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with Layomi we should remove references to security from the exception message, since this class has evolved into a general-purpose converter for unsupported types. We might consider special casing the error message for System.Type and SerializationInfo (e.g. by injecting a reason string to the constructed converter) but this is likely overkill.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the last section works for me:

from

"Serialization and deserialization of '{0}' instances are not supported and should be avoided since they can lead to security issues."

to

"Serialization and deserialization of '{0}' instances are not supported."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might consider special casing the error message for System.Type and SerializationInfo (e.g. by injecting a reason string to the constructed converter) but this is likely overkill.

FWIW there was a discussion on how to scale these exception messages (#42605 (comment), #42605 (comment)). Another approach to consider in the future is to add a JsonTypeDisallowReason enum which is passed to a new converter ctor overload, which would determine what exception message is shown.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a JsonTypeDisallowReason enum

Unless there is a requirement for the "security issue" in the message, I think this is overkill. It would also require 2 converter instances and add code\tests to separate the unsupported types into "security" and "non security".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

[Fact]
public async Task CompileTimeConverterIsSupported()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to also cover the IAsyncEnumerable case in this test? Ditto for runtime converter case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a test to ensure the converter gets called and doesn't throw NSE, but I think it's outside the scope here to verify actual IAsyncEnumerable semantics of serializer\deserialize; not sure if you wanted that as well.

@steveharter
Copy link
Contributor Author

@layomia please merge when API approved and green.

@eiriktsarpalis
Copy link
Member

@layomia should be ready to merge, can you take another look?

Copy link
Contributor

@layomia layomia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, merging to avoid conflicts with other PRs. Offline API review still pending.

@layomia layomia merged commit c8c044f into dotnet:main Sep 10, 2021
@eiriktsarpalis
Copy link
Member

/backport to release/6.0

@github-actions
Copy link
Contributor

@steveharter steveharter deleted the ThrowOnIAsyncEnumerable branch September 13, 2021 14:28
@ghost ghost locked as resolved and limited conversation to collaborators Nov 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants