[release/9.0-staging] Fix LINQ handling of iterator.Take(...).Last(...) #112714
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 #112680 to release/9.0-staging
Customer Impact
Code that does
commonLINQOperators.Take(...).Last()
, wherecertainLINQOperators
are things likeRange
,Select
,Where
, etc., if the value passed to take is larger than the number of elements in the source,Last
will throw an exception, andLastOrDefault
will end up returning the default value rather than the actual last value. Essentially, the consumer can start operating on incorrect data or hit unexpected failures.Regression
This was introduced accidentally in .NET 9 as part of a change that consolidated several internal abstractions in LINQ.
Testing
Revamped the LINQ tests to execute various combinations that lead to this, but also a bunch of other combinations to try to root out any other similar issues.
Risk
Low. The change is isolated to a single block and is now much better tested. Developers would have either been getting back erroneous results, or erroneous exceptions; it'd be difficult for someone to have taken a meaningful dependency on the bug.