-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Fix Position and Seek for MemoryStream with custom origin #88572
Conversation
Tagging subscribers to this area: @dotnet/area-system-io |
(10, 5), | ||
(10, 10), | ||
(Array.MaxLength, 0), | ||
(Array.MaxLength, Array.MaxLength) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these last two cases are causing OOM on 32 bit
Note that this will change the behavior of the MemoryStream.Property and will be in conflict with the current MemoryStream.Position documentation (https://learn.microsoft.com/en-us/dotnet/api/system.io.memorystream.position?view=net-8.0#exceptions). If this pull request is accepted, please don't forget to update the MemoryStream.Position documentation accordingly. |
using (MemoryStream ms = new MemoryStream(buffer, origin, buffer.Length - origin, true)) | ||
{ | ||
Seek(mode, ms, int.MaxValue - origin); | ||
Assert.Throws<ArgumentOutOfRangeException>(() => Seek(mode, ms, (long)int.MaxValue - origin + 1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please test with an offset of long.MinValue + 1
(uncasted). The check we discussed in https://github.com/dotnet/runtime/pull/88572/files/6880c4d6d148f46a878f929303fd2472e8fbc363#r1297747637 may be there to prevent an overflow after the (int)
conversion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, removing the unchecked(loc + offset) < _origin
check was a mistake. Because (int)offset
used for calculating tempPosition
will just cut the upper 32 bit from the long value, turning certain negative offset values into positive tempPosition
values that are equal to or larger than _origin
, thus not correctly failing on offset values representing invalid negative positions. For example, with this change, calling Seek(long.MinValue, SeekOrigin.Begin)
would lead to tempPosition
being equal to the value of _origin
and effectively set the stream position to zero instead of throwing, if i am not mistaken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added two Seek calls with long.MinValue + 1
and long.MaxValue - 1
as offset and checked that an exception is correctly raised in all cases.
Indeed I have manually checked that these calls are not always sending an exception when the unchecked(loc + offset) < _origin
check is not present.
6f31b63
to
23e33c7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Fixes #88541