Skip to content
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

Add CA2022: Avoid inexact read with 'Stream.Read' #7208

Merged
merged 4 commits into from
Mar 26, 2024

Conversation

mpidash
Copy link
Contributor

@mpidash mpidash commented Feb 24, 2024

Fixes dotnet/runtime#69159.

Category: Reliability
Severity: Warning

This analyzer detects calls to Stream.Read or Stream.ReadAsync that do not check the return value. These methods may return fewer bytes than requested, resulting in unreliable code.
The fixer will recommend replacing the call with Stream.ReadExactly or Stream.ReadExactlyAsync, if available.


All findings look legit, mostly calls in test code, although there are a few hits in non-test code in dotnet/runtime:

  1. https://github.com/dotnet/runtime/blob/79dd9bae9bb881eb716b608577c4cedc6c9cba72/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStreamWrapper.cs#L93
  2. https://github.com/dotnet/runtime/blob/79dd9bae9bb881eb716b608577c4cedc6c9cba72/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/XmlBuffer.cs#L89
  3. https://github.com/dotnet/runtime/blob/79dd9bae9bb881eb716b608577c4cedc6c9cba72/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.cs#L966
  4. https://github.com/dotnet/runtime/blob/79dd9bae9bb881eb716b608577c4cedc6c9cba72/src/libraries/System.Speech/src/Internal/Synthesis/AudioBase.cs#L124
  5. https://github.com/dotnet/runtime/blob/79dd9bae9bb881eb716b608577c4cedc6c9cba72/src/libraries/System.Speech/src/Internal/Synthesis/EngineSite.cs#L177

I've also added all findings from dotnet/roslyn, dotnet/runtime and dotnet/aspnetcore (no warnings found in dotnet/roslyn-analyzer:
roslyn.txt
runtime.txt
aspnetcore.txt

This analyzer detects calls to 'Stream.Read' or 'Stream.ReadAsync' that
do not check the return value. These methods may return fewer bytes than
requested, resulting in unreliable code.

The fixer will recommend replacing the call with 'Stream.ReadExactly' or
'Stream.ReadExactlyAsync', if available.
@mpidash mpidash requested a review from a team as a code owner February 24, 2024 21:33
Copy link

codecov bot commented Feb 24, 2024

Codecov Report

Attention: Patch coverage is 97.15302% with 24 lines in your changes are missing coverage. Please review.

Project coverage is 96.48%. Comparing base (29bdbf5) to head (254f3a8).
Report is 3 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #7208    +/-   ##
========================================
  Coverage   96.48%   96.48%            
========================================
  Files        1439     1442     +3     
  Lines      344369   345212   +843     
  Branches    11324    11345    +21     
========================================
+ Hits       332259   333081   +822     
- Misses       9244     9256    +12     
- Partials     2866     2875     +9     

Copy link
Contributor

@buyaa-n buyaa-n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @mpidash, left a few comment, mostly for messages. Overall looks good 👍

@mpidash mpidash changed the title Add CA2022: Avoid unreliable call to 'Stream.Read' Add CA2022: Avoid inexact read with 'Stream.Read' Mar 25, 2024
Copy link
Contributor

@buyaa-n buyaa-n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thank you @mpidash!

One of the CI legs somehow failed, might be one of the docs are not in sync that needs build with /pack PTAL

@buyaa-n
Copy link
Contributor

buyaa-n commented Mar 26, 2024

All findings look legit, mostly calls in test code, although there are a few hits in non-test code in dotnet/runtime:

Runtime findings in src looks legit, please let us know if you would like to put up a fix for them, and also set dotnet_diagnostic.CA2022.severity = warning for source projects and set dotnet_diagnostic.CA2022.severity = none for test projects, we will not fix any findings in test.

This better to be done before the merged code flows to runtime, as the analyzer warns by default it would fail the roslyn-analyzers => runtime code-flow PRs.

@mpidash
Copy link
Contributor Author

mpidash commented Mar 26, 2024

Thanks for the review!

One of the CI legs somehow failed, might be one of the docs are not in sync that needs build with /pack PTAL

I ran the pack task again locally and got no changes, but it seems like the CI ran successfully now.

This better to be done before the merged code flows to runtime, as the analyzer warns by default it would fail the roslyn-analyzers => runtime code-flow PRs.

I can prepare a MR tomorrow to fix the findings and enable the rule (and disable it for tests).

@buyaa-n
Copy link
Contributor

buyaa-n commented Mar 26, 2024

I ran the pack task again locally and got no changes, but it seems like the CI ran successfully now.

Yeah, I hit the rerun button and now it is passed, gonna merge now

I can prepare a MR tomorrow to fix the findings and enable the rule (and disable it for tests).

Great, thank you!

@buyaa-n buyaa-n merged commit 9022e53 into dotnet:main Mar 26, 2024
11 checks passed
{
var invocation = (IInvocationOperation)context.Operation;

if (symbols.IsAnyStreamReadMethod(invocation.TargetMethod))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we special-case MemoryStream and UnmanagedMemoryStream where if we can prove the target Stream is one of those we don't issue diagnostics? Those, in particular the former, are commonly used and we know they are actually safe for this usage; I'd like to avoid causing a lot of noise around them. While we don't necessarily document it's safe, we also don't need to cause folks to do a lot of work in response.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those, in particular the former, are commonly used and we know they are actually safe for this usage; I'd like to avoid causing a lot of noise around them. While we don't necessarily document it's safe, we also don't need to cause folks to do a lot of work in response.

Thanks, created an issue, FYI @mpidash as the analyzer warns by default we need to fix such breaking false positives ASAP, please let me know ASAP if you have no time for this. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can take a look at this.

@mpidash mpidash deleted the issue-69159 branch March 26, 2024 20:57
mus65 added a commit to mus65/SSH.NET that referenced this pull request Jun 15, 2024
see dotnet/roslyn-analyzers#7208

Most of these could be safely ignored because of the following assert.
As far as I can see, The SftpFileStream.Read() implementation guarentees
that the specified number of bytes is read anyway.
Rob-Hague added a commit to sshnet/SSH.NET that referenced this pull request Jun 16, 2024
* .NET 9: fix CA1872

see https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1872

* .NET 9: fix CA2022

see dotnet/roslyn-analyzers#7208

Most of these could be safely ignored because of the following assert.
As far as I can see, The SftpFileStream.Read() implementation guarentees
that the specified number of bytes is read anyway.

---------

Co-authored-by: Rob Hague <[email protected]>
sendevman pushed a commit to sendevman/SSH.NET that referenced this pull request Sep 1, 2024
* .NET 9: fix CA1872

see https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1872

* .NET 9: fix CA2022

see dotnet/roslyn-analyzers#7208

Most of these could be safely ignored because of the following assert.
As far as I can see, The SftpFileStream.Read() implementation guarentees
that the specified number of bytes is read anyway.

---------

Co-authored-by: Rob Hague <[email protected]>
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.

[Analyzer Proposal]: Analyzer/fixer for converting Stream.Read calls to ReadAtLeast and ReadExactly
4 participants