-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
[Analyzer Proposal]: Analyzer/fixer for converting Stream.Read calls to ReadAtLeast and ReadExactly #69159
Comments
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsWith the addition of the new Stream stream.Read(buffer, 0, buffer.Length); where the return value isn't checked, and recommend it be changed to a call to Or cases where the return value is checked but required to be the same as what was requested: if (stream.Read(buffer, 0, buffer.Length) != buffer.Length) throw ...; and similarly suggest it use If the caller is using a length that is different than the length of the buffer being passed in, and not checking the return value, we can suggest to use stream.Read(buffer, 0, count); would become: stream.ReadAtLeast(buffer, count); However, note in the One problem with this analyzer might be when we implement #34098. If the caller saw the "Do not discard results of methods marked as cc @stephentoub
|
This comment was marked as outdated.
This comment was marked as outdated.
@jeffhandley @stephentoub with 3.1 EOL in 3 months, and based on some of the issues posted here recently, we can expect a number of folks migrating before support expires. Some of them will hit this and get a hang in their app. It might take a while to connect to the breaking change notice because there isn't an obvious "smell" (the doc doesn't contain the word "hang" for example). Once they've made that connection, they may have many places in their codebase that need auditing for the bug and fixing. An analyzer/fixer could help with both those hurdles. I wonder whether we should start now to front load getting one into the SDK .. |
The intent had been that this be addressed in .NET 7. It unfortunately got pushed out due to lack of time. We should tackle it soon. |
Note that another analyzer that would help in this case is #34098. Code that doesn't capture the result of However, the downfall of #34098 is that the necessary attribute didn't get added to net7.0, so we can't mark the APIs as "do not discard" yet. |
Estimates:
|
Looks good as proposed. The diagnostic (possibly with a different diagnostic ID) should still fire on older TFMs to report that the call made to Read is unreliable as written. Category: Reliability |
I would like to be assigned to this one, please. |
Terrific. Done. Thanks! |
What is the reason for suggesting to call |
I'm actually not sure now... @eerhardt, do you remember what you had in mind there? |
@stephentoub I think the initial post is based on a comment from you when discussing the implementation of One of the reasons why I am following up on the second code fix is because I am not sure how we can enforce the following:
The code is still unreliable (in a different way) if we just change the call to |
in fact, if I read this right, if you change from Read to ReadAtLeast you may introduce additional bugs because now you can overwrite data past the original count being passed in? it might be best to always suggest ReadExactly when the return value isn't checked in the first place? maybe the description of the diagnostic can mention the other options |
Thinking about this now, I think ReadExactly is the only correct suggestion here. It's the only method you can call without checking the return value, as it is the only method that ensures you got exactly |
Yeah, for the life of me I can't think of why I wrote ReadAtLeast in my original comment. It should be ReadExact. |
Thank you all for helping to clarify 😃. |
With the addition of the new Stream
ReadAtLeast
andReadExactly
methods, there is a pattern of mistakes we can catch with an analyzer and suggest the caller use the new APIs. For example:where the return value isn't checked, and recommend it be changed to a call to
ReadExactly
.Or cases where the return value is checked but required to be the same as what was requested:
and similarly suggest it use
ReadExactly
.If the caller is using a length that is different than the length of the buffer being passed in, and not checking the return value, we can suggest to use
ReadAtLeast
:would become:
However, note in the
ReadAtLeast
case, the caller should still be checking the return value because theReadAtLeast
call could be returning more thancount
bytes, and this data would be missed if the caller only consumedcount
bytes frombuffer
.One problem with this analyzer might be when we implement #34098. If the caller saw the "Do not discard results of methods marked as
DoNotIgnoreReturnValue
" warning first and addressed it, they would lose out on this fixer.cc @stephentoub
The text was updated successfully, but these errors were encountered: