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

C#: Adding synthetic implicit ToString calls in binary- and string interpolation expressions. #18446

Merged
merged 22 commits into from
Jan 16, 2025

Conversation

michaelnebel
Copy link
Contributor

@michaelnebel michaelnebel commented Jan 8, 2025

In this PR we get the ball rolling on synthesizing compiler generated ToString calls.
We introduce ToString calls in binary expressions for concatenating strings and string interpolation expressions:
That is,

"abc" + x -> "abc" + x.ToString()`
$"abx{x}" -> $"abx{x.ToString()}"

This is expected to increase accuracy of the data flow analysis, but there are some pitfalls:

  • We might loose results in case, the ToString that is implicitly called is not in source code and if we don't have a model for it.
  • We might get more results: If Object.ToString is the one being implicitly called and there exists a ToString implementation that contains a source for a query. In this case we might get false positives due to dynamic dispatch. DCA reports a couple of results like that (cs/web/xss, cs/log-forging and cs/information-exposure-through-exception on ASP.NET and cs/cleartext-storage-of-sensitive-information and cs/exposure-of-sensitive-information on mono). In any case, this is an anti pattern that should generally be avoided (there is also a quality query for this). We could consider not to extract the implicit to string call when the target is ToString is on System.Object?

The extra result on ASP.NET for cs/web/unvalidated-url-redirection is due to the summary model added for PathString.ToString.

According to DCA til change does not affect performance.

@github-actions github-actions bot added the C# label Jan 8, 2025
@michaelnebel michaelnebel force-pushed the csharp/implicittostring2 branch 2 times, most recently from 7ba7af1 to 9959976 Compare January 9, 2025 10:43
@michaelnebel michaelnebel force-pushed the csharp/implicittostring2 branch 7 times, most recently from bf46c42 to 825c64f Compare January 10, 2025 13:17
@michaelnebel michaelnebel changed the title C#: Adding synthetic implicit ToString calls in binary expressions. C#: Adding synthetic implicit ToString calls in binary- and string interpolation expressions. Jan 10, 2025
@michaelnebel michaelnebel force-pushed the csharp/implicittostring2 branch from 825c64f to 9ebee34 Compare January 10, 2025 13:51
Copy link
Contributor

⚠️ The head of this PR and the base branch were compared for differences in the framework coverage reports. The generated reports are available in the artifacts of this workflow run. The differences will be picked up by the nightly job after the PR gets merged.

Click to show differences in coverage

csharp

Generated file changes for csharp

  • Changes to framework-coverage-csharp.rst:
-    Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.AspNetCore.Components``, ``Microsoft.AspNetCore.Mvc``, ``Microsoft.AspNetCore.WebUtilities``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.Sdk.WebAssembly``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",61,2074,152,4
+    Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.AspNetCore.Components``, ``Microsoft.AspNetCore.Http``, ``Microsoft.AspNetCore.Mvc``, ``Microsoft.AspNetCore.WebUtilities``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.Sdk.WebAssembly``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",61,2075,152,4
-    Totals,,108,12900,400,9
+    Totals,,108,12901,400,9
  • Changes to framework-coverage-csharp.csv:
+ Microsoft.AspNetCore.Http,,,1,,,,,,,,,,,,,,,,,,,1,

@michaelnebel michaelnebel marked this pull request as ready for review January 14, 2025 10:07
@Copilot Copilot bot review requested due to automatic review settings January 14, 2025 10:07
@michaelnebel michaelnebel requested a review from a team as a code owner January 14, 2025 10:07

Choose a reason for hiding this comment

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

Copilot reviewed 35 out of 50 changed files in this pull request and generated no comments.

Files not reviewed (15)
  • csharp/ql/examples/snippets/ternary_conditional.ql: Language not supported
  • csharp/ql/lib/semmle/code/csharp/PrintAst.qll: Language not supported
  • csharp/ql/lib/semmle/code/csharp/commons/Constants.qll: Language not supported
  • csharp/ql/lib/semmle/code/csharp/commons/Strings.qll: Language not supported
  • csharp/ql/lib/semmle/code/csharp/dataflow/Nullness.qll: Language not supported
  • csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll: Language not supported
  • csharp/ql/lib/semmle/code/csharp/exprs/Call.qll: Language not supported
  • csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll: Language not supported
  • csharp/ql/src/Bad Practices/VirtualCallInConstructorOrDestructor.ql: Language not supported
  • csharp/ql/src/Likely Bugs/Dynamic/BadDynamicCall.ql: Language not supported
  • csharp/ql/src/Likely Bugs/ObjectComparison.ql: Language not supported
  • csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected: Language not supported
  • csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs: Evaluated as low risk
  • csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/InterpolatedString.cs: Evaluated as low risk
  • csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs: Evaluated as low risk

Tip: Copilot code review supports C#, Go, Java, JavaScript, Markdown, Python, Ruby and TypeScript, with more languages coming soon. Learn more

@michaelnebel michaelnebel force-pushed the csharp/implicittostring2 branch from dbc7a80 to 0c5c2a3 Compare January 14, 2025 16:17
@michaelnebel michaelnebel marked this pull request as draft January 16, 2025 08:08
@michaelnebel michaelnebel marked this pull request as ready for review January 16, 2025 08:08
Copy link
Contributor

@tamasvajk tamasvajk left a comment

Choose a reason for hiding this comment

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

LGTM

@michaelnebel michaelnebel merged commit ba2b7ab into github:main Jan 16, 2025
22 checks passed
Copy link
Contributor

@hvitved hvitved left a comment

Choose a reason for hiding this comment

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

Great work; one question.

private static IMethodSymbol? GetToStringMethod(ITypeSymbol? type)
{
return type?
.GetMembers()
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this include inherited members?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it doesn't.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe we should consider to support this as well - should be fairly easy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also good observation @hvitved !! 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should consider to support this as well - should be fairly easy.

Yes, I think we should support that as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Follow up #18508

@michaelnebel michaelnebel deleted the csharp/implicittostring2 branch January 16, 2025 10:37
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.

3 participants