Skip to content

[release/9.0-staging] [STJ] Fix formatting of flag enums when values are overlapping. #117806

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

github-actions[bot]
Copy link
Contributor

@github-actions github-actions bot commented Jul 18, 2025

Backport of #117730 to release/9.0-staging

/cc @eiriktsarpalis

Customer Impact

  • Customer reported
  • Found internally

Fixes a regression introduced in .NET 9 impacting formatting of enum flag types as strings, when the enums define values whose bits are a subset of other values. This results in the enum either being formatted as a non-canonical combination of values or being formatted using its underlying numeric value.

Regression

  • Yes
  • No

The regression was introduced by #105032, which added support for customizable enum labels. This necessitated a departure from the built-in string formatting for enums in favor of a custom solution, which has created a bug tail.

Testing

New test cases were added for [Flags] scenarios with overlapping values.

Risk

Low. The fix involves topologically sorting of the built-in enum values which changes the string-based formatting of enum values but doesn't impact the underlying value being marshalled (as likewise the regression didn't impact the underlying value either).

@eiriktsarpalis eiriktsarpalis added this to the 9.0.x milestone Jul 18, 2025
@eiriktsarpalis eiriktsarpalis added area-System.Text.Json Servicing-consider Issue for next servicing release review labels Jul 18, 2025
@eiriktsarpalis eiriktsarpalis self-assigned this Jul 18, 2025
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis
See info in area-owners.md if you want to be subscribed.

@tarekgh
Copy link
Member

tarekgh commented Jul 22, 2025

The time zone failures are already tracked with the issue #117731 and #117903. It looks BA is not recognizing it because the console logs not including the actual failure output.

@eiriktsarpalis
Copy link
Member

eiriktsarpalis commented Jul 23, 2025

Before merging, let's also cherry pick the improvement from #117839 once merged. cc @PranavSenthilnathan

EDIT: now done.

@eiriktsarpalis eiriktsarpalis enabled auto-merge (squash) July 23, 2025 11:38
@eiriktsarpalis eiriktsarpalis disabled auto-merge July 23, 2025 11:39
eiriktsarpalis and others added 2 commits July 23, 2025 14:39
* [STJ] Only compute PopCount once when topologically sorting Enums

Packs the calculated (once per entry) PopCount into the high 32 bits of the long and the original index into the low 32 bits. Then that can just be sorted using the heavily optimized Array.Sort() method.
After sorting just extract the low 32 bits as the original array index. As before, we negate the actual _PopCount_ to ensure that `Key`s with more on-bits (e.g. more flags represented) will sort **first**.

This trades 2 x O(N log N) [average case] to 2 x O(N^2) [worst case] calls to the `popcount` instruction (or the emulation if NET is not defined) for N **shift-left-32** and **or** + N x **truncate to 32 bits**. It _also_ eliminates the overhead of the `CompareTo` method as it's now a direct `long` low-level compare.

* PR Feedback

Switched to Tuple

* PR Feedback
Switched to native tuple syntax
Co-authored-by: Pranav Senthilnathan <[email protected]>

* Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs

---------

Co-authored-by: Eirik Tsarpalis <[email protected]>
@jeffhandley jeffhandley added Servicing-rejected and removed Servicing-consider Issue for next servicing release review labels Jul 25, 2025
@jeffhandley
Copy link
Member

We are going to hold off on backporting this to .NET 9. If more customer impact is reported before migrating to .NET 10 is an option, we will reconsider the backport.

@jkotas jkotas deleted the backport/pr-117730-to-release/9.0-staging branch July 26, 2025 00:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants