Skip to content

Commit e4e3ab3

Browse files
committed
Harden AddValidation check in validations generator
1 parent d24486f commit e4e3ab3

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

src/Http/Http.Extensions/gen/Microsoft.AspNetCore.Http.ValidationsGenerator/Parsers/ValidationsGenerator.AddValidation.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ internal bool FindAddValidation(SyntaxNode syntaxNode, CancellationToken cancell
2626
{
2727
var node = (InvocationExpressionSyntax)context.Node;
2828
var semanticModel = context.SemanticModel;
29+
var symbol = semanticModel.GetSymbolInfo(node, cancellationToken).Symbol;
30+
if (symbol is not IMethodSymbol methodSymbol
31+
|| methodSymbol.ContainingType.Name != "ValidationServiceCollectionExtensions"
32+
|| methodSymbol.ContainingAssembly.Name != "Microsoft.AspNetCore.Http.Abstractions")
33+
{
34+
return null;
35+
}
2936
return semanticModel.GetInterceptableLocation(node, cancellationToken);
3037
}
3138
}

src/Http/Http.Extensions/test/ValidationsGenerator/ValidationsGenerator.NoOp.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,62 @@ await VerifyEndpoint(compilation, "/complex-type", async (endpoint, serviceProvi
5151
});
5252
}
5353

54+
[Fact]
55+
public async Task DoesNotEmitIfNotCorrectAddValidationCallExists()
56+
{
57+
// Arrange
58+
var source = """
59+
using System;
60+
using System.ComponentModel.DataAnnotations;
61+
using System.Collections.Generic;
62+
using System.Threading.Tasks;
63+
using Microsoft.AspNetCore.Builder;
64+
using Microsoft.AspNetCore.Http;
65+
using Microsoft.AspNetCore.Routing;
66+
using Microsoft.Extensions.DependencyInjection;
67+
68+
var builder = WebApplication.CreateBuilder();
69+
70+
builder.Services.AddValidation("example");
71+
72+
var app = builder.Build();
73+
74+
app.MapPost("/complex-type", (ComplexType complexType) => Results.Ok("Passed"));
75+
76+
app.Run();
77+
78+
public class ComplexType
79+
{
80+
[Range(10, 100)]
81+
public int IntegerWithRange { get; set; } = 10;
82+
}
83+
84+
public static class SomeExtensions
85+
{
86+
public static IServiceCollection AddValidation(this IServiceCollection services, string someString)
87+
{
88+
// This is not the correct AddValidation method
89+
return services;
90+
}
91+
}
92+
""";
93+
await Verify(source, out var compilation);
94+
// Verify that we don't validate types if no AddValidation call exists
95+
await VerifyEndpoint(compilation, "/complex-type", async (endpoint, serviceProvider) =>
96+
{
97+
var payload = """
98+
{
99+
"IntegerWithRange": 5
100+
}
101+
""";
102+
var context = CreateHttpContextWithPayload(payload, serviceProvider);
103+
104+
await endpoint.RequestDelegate(context);
105+
106+
Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
107+
});
108+
}
109+
54110
[Fact]
55111
public async Task DoesNotEmitForExemptTypes()
56112
{

0 commit comments

Comments
 (0)