docs(tests): fix CommentChecker findings across tests/ — 13,392 → 0 (repo-wide scan clean)

Comment/XML-doc changes only:
- add summaries to ~10k test methods, fixtures, fakes and helpers
  (+ <param> on theories, <returns> on async Task methods,
  <inheritdoc/> on interface implementations the checker can resolve)
- strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N,
  #NN, Component-0NN) from comments, keeping the explanatory text;
  reword false positives in comments only
- real docs on fakes implementing BCL/library interfaces
  (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime)
- reword the last 5 src/ false positives (CWE-1236, failures-1,
  year-0001, M365)

Only non-comment edits: four one-line nested classes split across lines
so members can carry docs. Build 0 errors / 0 warnings.
This commit is contained in:
Joseph Doherty
2026-10-07 15:05:49 -04:00
parent 0ffd4bdbea
commit 513fa1aa16
998 changed files with 17896 additions and 2395 deletions
@@ -3,7 +3,7 @@ using ZB.MOM.WW.ScadaBridge.ScriptAnalysis;
namespace ZB.MOM.WW.ScadaBridge.ScriptAnalysis.Tests;
/// <summary>
/// M3.1: adversarial + legitimate cases for the fused trust validator. Reject
/// Adversarial + legitimate cases for the fused trust validator. Reject
/// cases exercise the semantic pass (alias / using static / global::), the
/// reflection-gateway hardening pass, and the namespace deny-list union; clean
/// cases pin the allowed exceptions (Tasks, CancellationToken, Diagnostics
@@ -11,6 +11,8 @@ namespace ZB.MOM.WW.ScadaBridge.ScriptAnalysis.Tests;
/// </summary>
public class ScriptTrustValidatorTests
{
/// <summary>Verifies that runtime escape APIs are rejected.</summary>
/// <param name="code">The script source containing a runtime escape API call.</param>
[Theory]
[InlineData("object o = new object(); System.Runtime.CompilerServices.Unsafe.As<object, string>(ref o);")]
[InlineData("System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject(typeof(object));")]
@@ -22,6 +24,8 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that compiler-support constructs are allowed.</summary>
/// <param name="code">The script source using compiler-support APIs.</param>
[Theory]
[InlineData("await System.Threading.Tasks.Task.Delay(1);")]
[InlineData("string Name([System.Runtime.CompilerServices.CallerMemberName] string name = \"\") => name;")]
@@ -32,6 +36,7 @@ public class ScriptTrustValidatorTests
// ---- Reject (non-empty violations) --------------------------------------
/// <summary>Verifies that a <c>using</c> of the System.IO namespace is rejected.</summary>
[Fact]
public void Rejects_SystemIo_Using()
{
@@ -39,6 +44,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that a global-qualified System.IO reference is rejected.</summary>
[Fact]
public void Rejects_SystemIo_GlobalQualified()
{
@@ -46,6 +52,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that an aliased System.IO reference is rejected.</summary>
[Fact]
public void Rejects_SystemIo_Aliased()
{
@@ -53,6 +60,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that a <c>using static</c> of a System.IO type is rejected.</summary>
[Fact]
public void Rejects_SystemIo_UsingStatic()
{
@@ -60,6 +68,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that reflection-gateway members are rejected on a permitted type.</summary>
[Fact]
public void Rejects_ReflectionGateway_OffPermittedType()
{
@@ -67,6 +76,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that the <c>dynamic</c> keyword is rejected.</summary>
[Fact]
public void Rejects_Dynamic_Keyword()
{
@@ -74,6 +84,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that <c>Activator.CreateInstance</c> is rejected.</summary>
[Fact]
public void Rejects_Activator_CreateInstance()
{
@@ -81,6 +92,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that System.Runtime.InteropServices usage is rejected.</summary>
[Fact]
public void Rejects_RuntimeInteropServices()
{
@@ -88,6 +100,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that Microsoft.Win32 usage is rejected.</summary>
[Fact]
public void Rejects_MicrosoftWin32()
{
@@ -95,6 +108,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that <c>Thread.Sleep</c> is rejected.</summary>
[Fact]
public void Rejects_Threading_Thread_Sleep()
{
@@ -102,6 +116,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that all System.Net usage is rejected.</summary>
[Fact]
public void Rejects_All_SystemNet()
{
@@ -109,6 +124,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that reflection-gateway members are rejected on an allowed Task type.</summary>
[Fact]
public void Rejects_ReflectionGateway_OffAllowedTaskType()
{
@@ -119,6 +135,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that forbidden IO nested inside an allowed <c>Task.Run</c> lambda is rejected.</summary>
[Fact]
public void Rejects_ForbiddenIo_NestedInAllowedTaskRunLambda()
{
@@ -129,6 +146,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that a forbidden mutex used as a generic argument under an allowed Tasks prefix is rejected.</summary>
[Fact]
public void Rejects_ForbiddenMutex_AsGenericArg_UnderAllowedTasksPrefix()
{
@@ -139,6 +157,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that a direct threading mutex is rejected independently of <c>Thread.Sleep</c>.</summary>
[Fact]
public void Rejects_DirectThreadingMutex_NotThreadSleep()
{
@@ -148,6 +167,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that <c>FileInfo</c> used as a generic argument is rejected.</summary>
[Fact]
public void Rejects_ForbiddenFileInfo_AsGenericArg()
{
@@ -157,6 +177,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that <c>nameof</c> applied to a forbidden type is rejected.</summary>
[Fact]
public void Rejects_NameOf_ForbiddenType()
{
@@ -166,6 +187,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that a qualified <c>Process</c> type reference is rejected.</summary>
[Fact]
public void Rejects_Process_QualifiedType()
{
@@ -173,6 +195,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that a bare <c>Process</c> identifier introduced via a <c>using</c> is rejected.</summary>
[Fact]
public void Rejects_Process_BareIdentifier_ViaUsing()
{
@@ -185,6 +208,7 @@ public class ScriptTrustValidatorTests
// ---- Clean (empty violations) -------------------------------------------
/// <summary>Verifies that <c>Task.Delay</c> is allowed.</summary>
[Fact]
public void Allows_TasksDelay()
{
@@ -192,6 +216,7 @@ public class ScriptTrustValidatorTests
Assert.Empty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that <c>Stopwatch</c> from System.Diagnostics is allowed while <c>Process</c> is not.</summary>
[Fact]
public void Allows_DiagnosticsStopwatch_NotProcess()
{
@@ -199,6 +224,7 @@ public class ScriptTrustValidatorTests
Assert.Empty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that <c>CancellationTokenSource</c> is allowed.</summary>
[Fact]
public void Allows_CancellationTokenSource()
{
@@ -206,6 +232,7 @@ public class ScriptTrustValidatorTests
Assert.Empty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that LINQ and <c>Math</c> usage is allowed.</summary>
[Fact]
public void Allows_LinqAndMath()
{
@@ -213,6 +240,7 @@ public class ScriptTrustValidatorTests
Assert.Empty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that <c>Alarms.CurrentAsync</c> and the <c>ScriptAlarm</c> type are allowed.</summary>
[Fact]
public void Allows_AlarmsCurrentAsync_AndTheScriptAlarmType()
{
@@ -231,6 +259,7 @@ public class ScriptTrustValidatorTests
Assert.Empty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that the <c>Log</c> global is allowed.</summary>
[Fact]
public void Allows_TheLogGlobal()
{
@@ -249,6 +278,7 @@ public class ScriptTrustValidatorTests
Assert.Empty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that the forbidden scopes do not cover the Commons script surface.</summary>
[Fact]
public void ForbiddenScopes_DoNotCover_TheCommonsScriptSurface()
{
@@ -261,9 +291,9 @@ public class ScriptTrustValidatorTests
.Namespace!.StartsWith(scope, StringComparison.Ordinal));
}
// ---- ScriptAnalysis-003: adversarial bypass-vector coverage --------------
// ---- Adversarial bypass-vector coverage --------------
// (a) TPA-FALLBACK DEGRADATION (the SA-001 hole). Forces Pass 1 onto the
// (a) TPA-FALLBACK DEGRADATION (the original bypass hole). Forces Pass 1 onto the
// minimal fallback reference set (DefaultAssemblies + ForbiddenAnchorAssemblies)
// — the set used on a single-file/AOT/trimmed host with no TPA list — and
// proves a BARE forbidden type inside an ALLOWED namespace is STILL caught.
@@ -272,18 +302,20 @@ public class ScriptTrustValidatorTests
// bare identifier — so `Process.Start` slipped the validator entirely. The
// anchor assemblies folded into the fallback close that hole.
/// <summary>Verifies that the minimal fallback reference set still rejects a bare <c>Process</c> introduced via a <c>using</c>.</summary>
[Fact]
public void TpaFallback_StillRejects_BareProcess_ViaUsing()
{
// The documented forbidden-type-in-allowed-namespace case: System.Diagnostics
// is allowed (Stopwatch/Debug), the `using` is not flagged, and `Process`
// is a BARE identifier. Against the minimal fallback set this must still
// be rejected — otherwise the SA-001 fallback hole is open.
// be rejected — otherwise the fallback hole is open.
var minimal = ScriptTrustPolicy.BuildMinimalFallbackReferences();
var code = "using System.Diagnostics; var p = Process.Start(\"x\");";
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code, minimal));
}
/// <summary>Verifies that the minimal fallback reference set still rejects a bare <c>Socket</c> introduced via a <c>using</c>.</summary>
[Fact]
public void TpaFallback_StillRejects_BareSocket_ViaUsing()
{
@@ -295,6 +327,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code, minimal));
}
/// <summary>Verifies that the minimal fallback reference set still allows <c>Stopwatch</c>.</summary>
[Fact]
public void TpaFallback_StillAllows_DiagnosticsStopwatch()
{
@@ -305,6 +338,7 @@ public class ScriptTrustValidatorTests
Assert.Empty(ScriptTrustValidator.FindViolations(code, minimal));
}
/// <summary>Verifies that the minimal fallback references resolve <c>Process</c> as a forbidden type.</summary>
[Fact]
public void MinimalFallbackReferences_Resolve_Process_AsForbidden()
{
@@ -323,6 +357,7 @@ public class ScriptTrustValidatorTests
// (a forbidden namespace) even though it is invoked in receiver position — the
// semantic pass resolves the reduced extension method's containing type, so the
// forbidden namespace is caught through the invocation itself.
/// <summary>Verifies that an extension method from a forbidden namespace is rejected.</summary>
[Fact]
public void Rejects_ExtensionMethod_InForbiddenNamespace()
{
@@ -337,6 +372,7 @@ public class ScriptTrustValidatorTests
// VisitIdentifierName compares Identifier.ValueText, which decodes both the
// verbatim '@' prefix and \uXXXX escapes — so neither spelling evades the
// ForbiddenIdentifiers deny-list.
/// <summary>Verifies that a verbatim-identifier <c>Activator</c> reference is rejected.</summary>
[Fact]
public void Rejects_VerbatimIdentifier_Activator()
{
@@ -344,6 +380,7 @@ public class ScriptTrustValidatorTests
Assert.NotEmpty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that a Unicode-escaped <c>Activator</c> identifier is rejected.</summary>
[Fact]
public void Rejects_UnicodeEscapedIdentifier_Activator()
{
@@ -356,6 +393,7 @@ public class ScriptTrustValidatorTests
// language-feature gate: a benign `unsafe` block reaches no forbidden API, so
// it must NOT be a false positive — while a forbidden API used INSIDE an unsafe
// block is still caught (the walker descends into the block).
/// <summary>Verifies that an unsafe block without forbidden APIs is allowed.</summary>
[Fact]
public void Allows_BenignUnsafeBlock_NoForbiddenApi()
{
@@ -363,6 +401,7 @@ public class ScriptTrustValidatorTests
Assert.Empty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that a forbidden API inside an unsafe block is rejected.</summary>
[Fact]
public void Rejects_ForbiddenApi_InsideUnsafeBlock()
{
@@ -375,6 +414,7 @@ public class ScriptTrustValidatorTests
// must stay clean (the walker inspects name/member nodes, never trivia or
// literal text). Reconstructing a forbidden API from runtime strings is outside
// the static validator's remit (documented sandbox caveat).
/// <summary>Verifies that a forbidden namespace mentioned only in a comment is allowed.</summary>
[Fact]
public void Allows_ForbiddenNamespace_InCommentOnly()
{
@@ -382,6 +422,7 @@ public class ScriptTrustValidatorTests
Assert.Empty(ScriptTrustValidator.FindViolations(code));
}
/// <summary>Verifies that a forbidden namespace mentioned only in a string literal is allowed.</summary>
[Fact]
public void Allows_ForbiddenNamespace_InStringLiteralOnly()
{
@@ -389,10 +430,12 @@ public class ScriptTrustValidatorTests
Assert.Empty(ScriptTrustValidator.FindViolations(code));
}
// ---- PLAN-05 Task 21: hardened deny-list additions -----------------------
// ---- Hardened deny-list additions -----------------------
// Environment (whole type), GC, and the concrete ADO.NET provider namespaces
// (Microsoft.Data / System.Data.SqlClient / .Odbc / .OleDb) are now forbidden.
/// <summary>Verifies that scripts using hardened deny-list APIs are flagged as violations.</summary>
/// <param name="code">The script source expected to be flagged.</param>
[Theory]
[InlineData("Environment.Exit(0);")]
[InlineData("Environment.FailFast(\"x\");")]
@@ -402,6 +445,8 @@ public class ScriptTrustValidatorTests
// Syntactic gateway closure (matters in TPA-degraded fallback mode): these
// reflection-gateway members are rejected regardless of receiver.
/// <summary>Verifies that the syntactic pass flags reflection-gateway members regardless of receiver.</summary>
/// <param name="code">The script source expected to be flagged.</param>
[Theory]
[InlineData("typeof(string).Assembly.GetTypes()")]
[InlineData("asm.EntryPoint")]
@@ -409,6 +454,8 @@ public class ScriptTrustValidatorTests
// Must NOT regress legitimate scripts: Task.Delay stays allowed and
// delegate.Invoke() is deliberately NOT on the reflection-gateway list.
/// <summary>Verifies that legitimate scripts are not flagged as violations.</summary>
/// <param name="code">The script source expected to be allowed.</param>
[Theory]
[InlineData("await Task.Delay(1);")]
[InlineData("Func<int,int> f = x => x; f.Invoke(3);")]