Skip to content

Commit 459928e

Browse files
committed
cli and pwsh cmdlet issues fixed
1 parent 432c1a6 commit 459928e

7 files changed

Lines changed: 321 additions & 46 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
## [Unreleased]
22

3+
## [0.2.4] - 2026-02-26
4+
5+
### Changed
6+
- CLI surface table now shows separate **METHOD** and **ROUTE** columns instead of combined `DisplayRoute`; renamed the C# method name column from METHOD to **ACTION**
7+
- New column order: `TYPE | METHOD | ROUTE | CLASS | ACTION | AUTH`
8+
9+
### Fixed
10+
- PowerShell formatter TypeNames used wrong namespace (`Spy.Core.Contracts` instead of `DllSpy.Core.Contracts`), causing `Format-Table` to fall back to raw property dump
11+
- Remaining `Spy` references in help XML and cmdlet base class comment updated to `DllSpy`
12+
13+
### Added
14+
- PowerShell formatter views for `RazorPageHandler` (table + list) and `BlazorRoute` (table + list)
15+
316
## [0.2.3] - 2026-02-26
417

518
### Added

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22

33
<PropertyGroup>
4-
<Version>0.2.3</Version>
4+
<Version>0.2.4</Version>
55
</PropertyGroup>
66

77
</Project>

src/DllSpy.Cli/OutputWriter.cs

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,32 +80,33 @@ public static void PrintIssues(List<SecurityIssue> issues, OutputFormat? format)
8080

8181
private static void PrintSurfacesTable(List<InputSurface> surfaces)
8282
{
83-
const string typeH = "TYPE", routeH = "ROUTE", classH = "CLASS", methodH = "METHOD", authH = "AUTH";
84-
const int gaps = 10; // 4 x 2-char gaps + AUTH column ~4
83+
const string typeH = "TYPE", methodH = "METHOD", routeH = "ROUTE", classH = "CLASS", actionH = "ACTION", authH = "AUTH";
84+
const int gaps = 12; // 5 x 2-char gaps + AUTH column ~4
8585
const int authCol = 4;
8686

8787
int tw = Math.Max(typeH.Length, surfaces.Max(s => GetTypeLabel(s).Length));
88-
int rw = Math.Max(routeH.Length, surfaces.Max(s => s.DisplayRoute.Length));
88+
int mthW = Math.Max(methodH.Length, surfaces.Max(s => GetMethod(s).Length));
89+
int rw = Math.Max(routeH.Length, surfaces.Max(s => GetRoute(s).Length));
8990
int cw = Math.Max(classH.Length, surfaces.Max(s => s.ClassName.Length));
90-
int mw = Math.Max(methodH.Length, surfaces.Max(s => s.MethodName.Length));
91+
int aw = Math.Max(actionH.Length, surfaces.Max(s => s.MethodName.Length));
9192

9293
int termWidth = GetTerminalWidth();
93-
int total = tw + rw + cw + mw + gaps + authCol;
94+
int total = tw + mthW + rw + cw + aw + gaps + authCol;
9495
if (total > termWidth)
9596
{
96-
int budget = termWidth - tw - gaps - authCol; // TYPE and AUTH are short, keep them
97-
// Give ROUTE 50% of remaining budget, CLASS 25%, METHOD 25%
97+
int budget = termWidth - tw - mthW - gaps - authCol; // TYPE, METHOD and AUTH are short, keep them
98+
// Give ROUTE 50% of remaining budget, CLASS 25%, ACTION 25%
9899
rw = Math.Max(routeH.Length, budget / 2);
99100
cw = Math.Max(classH.Length, budget / 4);
100-
mw = Math.Max(methodH.Length, budget - rw - cw);
101+
aw = Math.Max(actionH.Length, budget - rw - cw);
101102
}
102103

103-
var fmt = $"{{0,-{tw}}} {{1,-{rw}}} {{2,-{cw}}} {{3,-{mw}}} {{4}}";
104+
var fmt = $"{{0,-{tw}}} {{1,-{mthW}}} {{2,-{rw}}} {{3,-{cw}}} {{4,-{aw}}} {{5}}";
104105

105106
Console.WriteLine(
106-
Colorize(string.Format(fmt, typeH, routeH, classH, methodH, authH), Bold));
107+
Colorize(string.Format(fmt, typeH, methodH, routeH, classH, actionH, authH), Bold));
107108
Console.WriteLine(
108-
Colorize(new string('─', tw + rw + cw + mw + gaps + authCol), Dim));
109+
Colorize(new string('─', tw + mthW + rw + cw + aw + gaps + authCol), Dim));
109110

110111
foreach (var s in surfaces)
111112
{
@@ -114,9 +115,10 @@ private static void PrintSurfacesTable(List<InputSurface> surfaces)
114115
: "No";
115116
Console.WriteLine(fmt,
116117
Truncate(GetTypeLabel(s), tw),
117-
Truncate(s.DisplayRoute, rw),
118+
Truncate(GetMethod(s), mthW),
119+
Truncate(GetRoute(s), rw),
118120
Truncate(s.ClassName, cw),
119-
Truncate(s.MethodName, mw),
121+
Truncate(s.MethodName, aw),
120122
auth);
121123
}
122124
}
@@ -125,11 +127,11 @@ private static void PrintSurfacesTable(List<InputSurface> surfaces)
125127

126128
private static void PrintSurfacesTsv(List<InputSurface> surfaces)
127129
{
128-
Console.WriteLine("TYPE\tROUTE\tCLASS\tMETHOD\tAUTH");
130+
Console.WriteLine("TYPE\tMETHOD\tROUTE\tCLASS\tACTION\tAUTH");
129131
foreach (var s in surfaces)
130132
{
131133
var auth = s.RequiresAuthorization ? "Yes" : s.AllowAnonymous ? "Anon" : "No";
132-
Console.WriteLine($"{GetTypeLabel(s)}\t{s.DisplayRoute}\t{s.ClassName}\t{s.MethodName}\t{auth}");
134+
Console.WriteLine($"{GetTypeLabel(s)}\t{GetMethod(s)}\t{GetRoute(s)}\t{s.ClassName}\t{s.MethodName}\t{auth}");
133135
}
134136
}
135137

@@ -190,6 +192,26 @@ private static void PrintIssuesTsv(List<SecurityIssue> issues)
190192
_ => severity.ToString()
191193
};
192194

195+
private static string GetMethod(InputSurface surface) => surface switch
196+
{
197+
HttpEndpoint http => http.HttpMethod,
198+
RazorPageHandler razor => razor.HttpMethod,
199+
_ => string.Empty
200+
};
201+
202+
private static string GetRoute(InputSurface surface) => surface switch
203+
{
204+
HttpEndpoint http => http.Route,
205+
RazorPageHandler razor => string.IsNullOrEmpty(razor.HandlerName)
206+
? razor.PageRoute
207+
: $"{razor.PageRoute}?handler={razor.HandlerName}",
208+
SignalRMethod signalr => signalr.HubRoute,
209+
WcfOperation wcf => wcf.ContractName,
210+
GrpcOperation grpc => grpc.ServiceName,
211+
BlazorRoute blazor => blazor.RouteTemplate,
212+
_ => string.Empty
213+
};
214+
193215
private static string GetTypeLabel(InputSurface surface) => surface.SurfaceType switch
194216
{
195217
SurfaceType.HttpEndpoint => "HTTP",

src/DllSpy.PowerShell/Commands/SpyCmdletBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace DllSpy.PowerShell.Commands
66
{
77
/// <summary>
8-
/// Base class for Spy cmdlets that scan assemblies.
8+
/// Base class for DllSpy cmdlets that scan assemblies.
99
/// </summary>
1010
public abstract class SpyCmdletBase : PSCmdlet
1111
{

src/DllSpy.PowerShell/DllSpy.PowerShell.dll-Help.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
</maml:description>
7373
<command:parameterValue required="true">SurfaceType</command:parameterValue>
7474
<dev:type>
75-
<maml:name>Spy.Core.Contracts.SurfaceType</maml:name>
75+
<maml:name>DllSpy.Core.Contracts.SurfaceType</maml:name>
7676
<maml:uri />
7777
</dev:type>
7878
</command:parameter>
@@ -140,7 +140,7 @@
140140
<command:returnValues>
141141
<command:returnValue>
142142
<dev:type>
143-
<maml:name>Spy.Core.Contracts.InputSurface</maml:name>
143+
<maml:name>DllSpy.Core.Contracts.InputSurface</maml:name>
144144
</dev:type>
145145
<maml:description>
146146
<maml:para>Objects representing discovered input surfaces. HttpEndpoint objects include Route, HttpMethod, ClassName, MethodName, and authorization details. SignalRMethod objects include HubName, HubRoute, MethodName, streaming flags, and authorization details.</maml:para>
@@ -150,7 +150,7 @@
150150

151151
<maml:alertSet>
152152
<maml:alert>
153-
<maml:para>The assembly is loaded via System.Reflection. Dependent assemblies (e.g. ASP.NET Core framework) do not need to be present — Spy reads attributes by name rather than by type identity.</maml:para>
153+
<maml:para>The assembly is loaded via System.Reflection. Dependent assemblies (e.g. ASP.NET Core framework) do not need to be present — DllSpy reads attributes by name rather than by type identity.</maml:para>
154154
<maml:para>SignalR hub routes are conventional (strip "Hub" suffix) since actual MapHub routes are not discoverable via reflection.</maml:para>
155155
</maml:alert>
156156
</maml:alertSet>
@@ -200,7 +200,7 @@
200200
<maml:title>Example 6: Scan multiple assemblies via pipeline</maml:title>
201201
<dev:code>Get-ChildItem .\bin\Release\net8.0\*.dll | Search-DllSpy</dev:code>
202202
<dev:remarks>
203-
<maml:para>Pipes all DLLs in the output directory to Spy. Assemblies without controllers or hubs produce no output.</maml:para>
203+
<maml:para>Pipes all DLLs in the output directory to DllSpy. Assemblies without controllers or hubs produce no output.</maml:para>
204204
</dev:remarks>
205205
</command:example>
206206
</command:examples>
@@ -269,7 +269,7 @@
269269
</maml:description>
270270
<command:parameterValue required="true">SecuritySeverity</command:parameterValue>
271271
<dev:type>
272-
<maml:name>Spy.Core.Contracts.SecuritySeverity</maml:name>
272+
<maml:name>DllSpy.Core.Contracts.SecuritySeverity</maml:name>
273273
<maml:uri />
274274
</dev:type>
275275
<dev:defaultValue>Info</dev:defaultValue>
@@ -282,7 +282,7 @@
282282
</maml:description>
283283
<command:parameterValue required="true">SurfaceType</command:parameterValue>
284284
<dev:type>
285-
<maml:name>Spy.Core.Contracts.SurfaceType</maml:name>
285+
<maml:name>DllSpy.Core.Contracts.SurfaceType</maml:name>
286286
<maml:uri />
287287
</dev:type>
288288
</command:parameter>
@@ -302,7 +302,7 @@
302302
<command:returnValues>
303303
<command:returnValue>
304304
<dev:type>
305-
<maml:name>Spy.Core.Contracts.SecurityIssue</maml:name>
305+
<maml:name>DllSpy.Core.Contracts.SecurityIssue</maml:name>
306306
</dev:type>
307307
<maml:description>
308308
<maml:para>Objects representing security issues found, including Severity, SurfaceType, Title, Description, SurfaceRoute, ClassName, MethodName, and Recommendation.</maml:para>

src/DllSpy.PowerShell/DllSpy.psd1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
RootModule = 'DllSpy.PowerShell.dll'
55

66
# Version number of this module.
7-
ModuleVersion = '0.2.3'
7+
ModuleVersion = '0.2.4'
88

99
# ID used to uniquely identify this module
1010
GUID = 'f7e8a9b0-1c2d-3e4f-5a6b-7c8d9e0f1a2b'
@@ -64,7 +64,7 @@
6464
ProjectUri = 'https://github.com/n7on/dllspy'
6565

6666
# Release notes for this module
67-
ReleaseNotes = 'Added Razor Page handler and Blazor routable component discovery. Discover HTTP endpoints, SignalR hubs, WCF services, gRPC services, Razor Pages, and Blazor components. Security analysis with severity-based vulnerability detection.'
67+
ReleaseNotes = 'CLI now shows separate METHOD and ROUTE columns (renamed old METHOD to ACTION). Fixed PowerShell formatter TypeName mismatch so Format-Table uses custom views. Added Razor Page and Blazor formatter views.'
6868
}
6969
}
7070

0 commit comments

Comments
 (0)