-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Remove unsafe code from SmtpReplyReaderFactory.ProcessRead #121297
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
Remove unsafe code from SmtpReplyReaderFactory.ProcessRead #121297
Conversation
SmtpReplyReaderFactory.cs in ProcessRead function, please file a PR to replace with just normal ReadOnlySpan memory access to make it memory safe.…plyReaderFactory Co-authored-by: EgorBo <[email protected]>
Co-authored-by: EgorBo <[email protected]>
xtqqczze
left a comment
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.
Codegen with !char.IsAsciiDigit((char)b) should be equivalent: sharplab.io
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpReplyReaderFactory.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpReplyReaderFactory.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpReplyReaderFactory.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: xtqqczze <[email protected]>
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.
Pull Request Overview
This PR refactors the ProcessRead method in SmtpReplyReaderFactory to eliminate unsafe pointer-based code in favor of safe, index-based buffer access. The logic remains functionally equivalent while improving code safety and maintainability.
Key Changes:
- Replaced unsafe pointer arithmetic (
ptr++,*ptr, etc.) with safe array indexing using anicounter - Removed the
unsafeblock andfixedstatement that were previously required for pointer manipulation - Maintained the same state machine logic for parsing SMTP reply messages
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpReplyReaderFactory.cs
Show resolved
Hide resolved
|
@stephentoub @MihaZupan is it fine to remove the unsafe from System.Net.Mail Smtp without perf benchmark, it's unclear to me how nanoseconds saved on bounds check can have an impact on it + SmptClient is effectively deprecated
|
|
I recommend reviewing it with "Hide whitespaces" option |
MihaZupan
left a comment
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.
is it fine to remove the unsafe from System.Net.Mail Smtp without perf benchmark
Fine by me.
cc: @rzikm re: the changed validation for ASCII digits that were previously wrong and unreachable.
|
Tagging subscribers to this area: @dotnet/ncl |
|
I think the perf is fine. But it still looks complicated to me. Basically it should be 3 digits + ASCII text. I would think there is better way than iterating though and keeping stated. (assuming we can handle the folding) |
rzikm
left a comment
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, I agree that the logic could be simplified (not only here, but across the entire implementation), but I already touched many parts during the refactor that I didn't want to add another possible breaking point.
|
/ba-g deadletter |

The
ProcessReadmethod used unnecessary unsafe pointer arithmetic despite accepting aReadOnlySpan<byte>parameter that already provides safe, efficient indexing.Changes
Replaced unsafe pointer arithmetic with ReadOnlySpan indexing
unsafeblock andfixedstatementbyte*pointers with integer index tracking*ptr++tobuffer[i++],(int)(ptr - start)toiFixed pre-existing validation bug (discovered during refactoring)
if (b < '0' && b > '9')toif (b < '0' || b > '9')in digit validationBefore/After
All existing tests pass. No API or behavior changes.
Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
1d7b368770e34adf874f9425defe0a54/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)2f1ac5ebdede409c885709296cd79caf/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)3e267405dc55499fbf89ba600b269486/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)4741d8119c5b46deb7b6a3247cf3e987/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)4777e169b2a54bef872d3013b91d119d/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)674cfdb34af049bc80dcbc8c430c56e8/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)83b38af9921845538f0d2b8e91bd4c93/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)8445b7f8594e4fa79d67a5f60e1917e1/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)9c17f6fe624d4688a482d039f62e9376/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)9caf23efb9b44deeaad1f5a4390857ed/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)ad5b1d9a0284470497198faf9964749f/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)dad9f17011b54a2883ca8f7489dde4e8/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)dc00558270b44330978820a282438ebc/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)f13d3b87148d4771ab29f5a3afc20964/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)f4e51707a3454d68a871b21a5edce6f6/home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net10.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Net.Mail.Functional.Tests.runtimeconfig.json --depsfile System.Net.Mail.Functional.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.25528.108/build/../tools/net/xunit.console.dll System.Net.Mail.Functional.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.