[release/6.0-staging] Fix Item4 is missing in some ValueTuples' IStructuralEquatable.Equals
#91472
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.
Backport of #91461 to release/6.0-staging
/cc @jeffhandley @hamarb123 @skyoxZ
Customer Impact
When
ValueTuplehas 5 or more items, thebool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer)implementation skips overItem4. This leads to instances returning as equal when they are not.This was reported by a customer in #91457 and fixed in .NET 8 with #91461. This latent behavioral bug could be silently affecting customer applications with potential data loss and data corruption issues. The bug only surfaces when explicitly using
IStructuralEquatable.Equalswith a comparer provided. That usage pattern would be most prevalent within framework and library usage where it could be hard for customers to diagnose or work around the issue if encountered.A GitHub code search revealed signal of such usage patterns being used. Here are a couple examples: 1, 2
Testing
The
ValueTupleimplementation was scanned for other errors like this and they were all fixed together. Unit tests were added to ensure each item of the tuple affects equality.Risk
Medium. This is a behavioral correction to a latent bug. It's plausible that data has been persisted based on the incorrect behavior; in such a case, the behavioral correction might surface for customers.