Repository navigation
Validate custom union type classifier results before deserialization - #136226
Merged
eiriktsarpalis merged 1 commit intoNov 6, 2026
Merged
eiriktsarpalis merged 1 commit into
eiriktsarpalis merged 1 commit into
Conversation
Reject classifier results that are not declared union cases before resolving metadata or invoking their converters. Cache the allowed types after contract customization and cover invalid results and modified contracts with shared regression tests. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 60a19e82-e4d1-4d77-a6ed-cd039cd02cab
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @dotnet/area-system-text-json |
jeffhandley
approved these changes
Nov 6, 2026
Member
Author
|
/backport to release/11.0 |
Contributor
|
Started backporting to |
2 of 4 tasks
This was referenced Nov 6, 2026
ViveliDuCh
pushed a commit
that referenced
this pull request
Nov 10, 2026
…eserialization (#137079) Backport of #136226 to release/11.0 /cc @eiriktsarpalis ## Customer Impact - [x] Customer reported - [ ] Found internally The newly introduced type classifier infrastructure intended to support union type deserialization did not include any validation for user-defined classifier delegates returning invalid types. ## Regression - [ ] Yes - [x] No ## Testing Added testing covering the missed scenario. ## Risk Low. Adds a straightforward validation step after invoking the user-defined delegate. Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com> Copilot-Session: 60a19e82-e4d1-4d77-a6ed-cd039cd02cab
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
JsonUnionConverter<TUnion>currently resolves metadata and invokes the converter for any non-null type returned by a custom classifier. Unlike polymorphic deserialization, it does not check the result against the configured case types before dispatch.Cache the final
UnionCasesin aHashSet<Type>for classifier-backed unions and throwJsonExceptionfor undeclared results before resolving their metadata. Membership is exact: an undeclared subtype is rejected even when assignable to a declared case. Default classification and JSON null handling are unchanged.The shared regression tests cover invalid and undeclared results, undeclared subtypes, cases added or removed through contract customization, and declared nullable cases. The rejection regressions were reproduced before the fix. All 154 new cases pass across reflection and source-generated serializers targeting
net11.0andnet481. The affected union, structural-classifier, and polymorphism test groups also pass: 7,676 reflection cases and 3,284 source-generation cases per target, with 8 existing skips per source-generation run. Release builds pass for all four library target frameworks.HashSet<Type>avoids adding aSystem.Collections.Immutableproduct dependency. Local lookup benchmarks foundFrozenSet<Type>faster for 2-4 entries, but not consistently faster for 8-16 entries. End-to-end BenchmarkDotNet measurements on a Windows x64 Hyper-V VM were:The scalar case adds approximately 3% overhead; the object case is approximately unchanged in this local run.
Note
This pull request was generated with GitHub Copilot.