Uh oh!
There was an error while loading. Please reload this page.
[release/7.0] Ensure source generated metadata properties are read-only. (#76540) - #76899
Conversation
ghost
commented
Oct 11, 2022
Note regarding the 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
commented
Oct 11, 2022
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsBackport of #76540 to release/7.0 Customer ImpactThe inclusion of the contract customization feature exposes a number of APIs that makes it possible for users to modify aspects of the pre-existing JsonTypeInfo<MyPoco>metadata=MyContext.Default.MyPoco;// Can modify metadata on the static `Default` context instance.metadata.CreateObject=null;metadata.Properties.Clear();[JsonSerializable(typeof(MyPoco))]publicpartialclassMyContext:JsonSerializerContext{}publicclassMyPoco{publicintId{get;set;}}At first glance this problem might be considered benign, however it has the potential to create a couple of issues:
TestingAdded testing validating that cached source generated metadata is read-only. RiskModerate. Even though the fix is fairly straightforward, it necessitates the introduction of a single public method that can be used by the source generator for locking the metadata it is producing. Adding new APIs at such a late stage carries inherent risks, however this particular method is part of the
|
carlossanlop
commented
Oct 11, 2022
Approved by Tactics via email. |
jeffhandley
commented
Oct 11, 2022
We're still deliberating this. We don't have consensus on adding this API in this form to address the issue. We'll hold off on merging this... |
jeffhandley
commented
Oct 12, 2022
The description and code have been updated to reflect the outcomes from the API review discussions. The APIs have been moved to @carlossanlop -- please let us know how this will affect IntelliSense. Will 7.0 be missing IntelliSense for these APIs in GA? Does that ever get serviced, or would IntelliSense be missing forever in 7.0? Even if that's the case, we can tolerate the gap, but it'll be helpful to know if that's the case. |
jeffhandley
left a comment
There was a problem hiding this comment.
Once CI is green, this can be merged.
carlossanlop
commented
Oct 12, 2022
We won't have intellisense for these new APIs in GA. Here is what we will have to do to fix that:
|
jeffhandley
commented
Oct 12, 2022
Excellent; thanks, @carlossanlop! |
carlossanlop
commented
Oct 12, 2022
CI is green. |
Backport of #76540 to release/7.0
Customer Impact
The inclusion of the contract customization feature exposes a number of APIs that makes it possible for users to modify aspects of the pre-existing
JsonTypeInfocontract metadata model. However, it seems that we neglected to freeze modifications for instances instantiated and cached by the source generator:At first glance this problem might be considered benign, however it has the potential to create a couple of issues:
The source generator is aggressively caching metadata instances for performance, so this is effectively introducing global mutable state. Changes in one component can cause unforeseen changes in an unrelated context:
or might be the cause of races when multiple threads are independently attempting to modify contracts:
Direct mutation of source gen metadata breaks the fast-path invalidation logic:
Testing
Added testing validating that cached source generated metadata is read-only.
Risk
Moderate. Even though the fix is fairly straightforward, it necessitates the introduction of a new public method that can be used by the source generator for locking the metadata it is producing. Adding new APIs at such a late stage carries inherent risks, but we've explored the options thoroughly and landed on an API that should also help customers discover that the metadata can be locked and understand when that occurs.
While we don't expect user code will directly invoke either of these APIs, their presence is beneficial. When the metadata is locked, mutation members throw exceptions, and customers can anticipate that possibility by seeing
IsReadOnlyand inspecting its value and when it changes. There is a possibility user code will begin referencingMakeReadOnlyin scenarios we don't anticipate, and/or that we'll want to introduce scoped or validated read-only states in the future. If those scenarios arise, it's possible the shape introduced here won't be ideal. But we have mitigation approaches if needed.