Skip to content

Resolve build warnings BED-7491#273

Merged
lrfalslev merged 8 commits intov4from
lfalslev/bed-7491
Mar 5, 2026
Merged

Resolve build warnings BED-7491#273
lrfalslev merged 8 commits intov4from
lfalslev/bed-7491

Conversation

@lrfalslev
Copy link
Contributor

@lrfalslev lrfalslev commented Feb 23, 2026

Description

Resolve compile time warnings for clean build output.

Motivation and Context

BED-7491

How Has This Been Tested?

Ran dotnet build succeeded with no errors/warnings
image

Types of changes

  • Chore (a change that does not modify the application functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • Documentation updates are needed, and have been made accordingly.
  • I have added and/or updated tests to cover my changes.
  • All new and existing tests passed.
  • My changes include a database migration.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed null-check in test mock utilities to prevent null reference issues.
    • Removed unused test variables.
  • Tests

    • Added Windows platform restrictions to many Windows-specific tests for clearer gating.
    • Converted one previously Windows-only test to run on all platforms.
  • Refactoring

    • Enabled nullable reference annotations across multiple modules to improve code safety.
    • Adjusted test lambdas for clearer async/task semantics.
  • Chores

    • Updated package packaging metadata.

@lrfalslev lrfalslev self-assigned this Feb 23, 2026
@lrfalslev lrfalslev added the bug Something isn't working label Feb 23, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 410c40bb-539b-4686-ba0c-542c21016eca

📥 Commits

Reviewing files that changed from the base of the PR and between a705a68 and 1a7a18b.

📒 Files selected for processing (4)
  • test/unit/AsyncEnumerableTests.cs
  • test/unit/LdapPropertyTests.cs
  • test/unit/SPNProcessorsTest.cs
  • test/unit/UserRightsAssignmentProcessorTest.cs

Walkthrough

This PR adjusts nullable reference type contexts across several source files (adding and in one case removing #nullable directives), updates a processor constructor and event/method signatures for nullable parameters, adds Windows-only platform gating to many tests, refactors some test helpers, and changes an AntiXSS package reference to include PrivateAssets="All".

Changes

Cohort / File(s) Summary
Nullable context changes
src/CommonLib/Ntlm/LdapTransport.cs, src/CommonLib/SMB/NetBIOS/NetBIOSSessionType.cs, src/CommonLib/Logging/Logging.cs
Added #nullable enable / #nullable disable in several files; Logging.cs had its #nullable enable directive removed (nullability context altered, no runtime logic changes).
Nullable signature updates in processors
src/CommonLib/Processors/DCLdapProcessor.cs
Enabled nullable context and updated signatures to nullable variants: constructor ILogger? log, event ComputerStatusDelegate?, and parameters NtlmAuthenticationHandler? / LdapTransport?.
Package configuration
src/CommonLib/SharpHoundCommonLib.csproj
Added PrivateAssets="All" to the AntiXSS PackageReference.
Windows platform gating in tests
test/unit/ACLProcessorTest.cs, test/unit/CertAbuseProcessorTest.cs, test/unit/CommonLibHelperTests.cs, test/unit/DomainTrustProcessorTest.cs, test/unit/GPOLocalGroupProcessorTest.cs, test/unit/GroupProcessorTest.cs, test/unit/LDAPUtilsTest.cs, test/unit/LdapPropertyTests.cs, test/unit/LocalGroupProcessorTest.cs, test/unit/UserRightsAssignmentProcessorTest.cs
Added using System.Runtime.Versioning; and applied [SupportedOSPlatform("windows")] attributes to numerous Windows-specific tests (platform gating only).
Test utilities refactor & null-safety
test/unit/Facades/FacadeHelpers.cs, test/unit/Facades/MockExtensions.cs
Replaced FormatterServices.GetUninitializedObject with RuntimeHelpers.GetUninitializedObject, renamed MockExtentionsMockExtensions, added null-check guard in log verification predicate, and enabled nullable context in file.
Test project config
test/unit/CommonLibTest.csproj
Added NoWarn entry (NU1702) to suppress cross-targeting warnings.
Test cleanup and minor behavior changes
test/unit/DCLdapProcessorTest.cs, test/unit/WebClientServiceProcessorTest.cs, test/unit/AsyncEnumerableTests.cs, test/unit/SPNProcessorsTest.cs, test/unit/LdapPropertyTests.cs
Removed unused locals, changed one test attribute from [WindowsOnlyFact] to [Fact], added CS1998 suppression around an async test helper, and converted some async event handlers to synchronous lambdas returning Task.CompletedTask (test-only adjustments).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰
I hopped through nullable fields and tests,
Gated windows where behavior rests,
Renamed a helper, tightened a check,
A tiny tweak — a careful fleck,
The rabbit smiles and hops the rest.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title "Resolve build warnings BED-7491" directly summarizes the main change—resolving build warnings related to issue BED-7491—which aligns with the changeset's primary objective of achieving clean build output.
Description check ✅ Passed The PR description includes all major template sections: Description, Motivation and Context with linked issue, How Has This Been Tested with verification evidence, Types of changes (Chore selected), and relevant Checklist items marked (tests passed, no documentation/migration needed).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch lfalslev/bed-7491

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
test/unit/WebClientServiceProcessorTest.cs (1)

29-35: ⚠️ Potential issue | 🟠 Major

Reintroduce OS platform gating for Windows-only API dependency.

WebClientServiceProcessor.IsWebClientRunning() directly uses kernel32.dll's CreateFile API to access Windows named pipes (\\{computerName}\pipe\DAV RPC SERVICE), which is not available on Linux/macOS. With [WindowsOnlyFact] removed, this test will throw PlatformNotSupportedException on non-Windows platforms. Restore the [WindowsOnlyFact] attribute and/or add [SupportedOSPlatform("windows")] to prevent cross-platform test failures.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/WebClientServiceProcessorTest.cs` around lines 29 - 35, The test
WebClientServiceProcessorTest_TestPathExists calls
WebClientServiceProcessor.IsWebClientRunning which uses Windows-only
kernel32.dll CreateFile for named pipes; reintroduce platform gating by
restoring the [WindowsOnlyFact] attribute (or adding
[SupportedOSPlatform("windows")] on the test) so it only runs on Windows, or
alternatively annotate the IsWebClientRunning method with
[SupportedOSPlatform("windows")] to prevent PlatformNotSupportedException on
non-Windows platforms.
src/CommonLib/Processors/DCLdapProcessor.cs (3)

154-169: ⚠️ Potential issue | 🟡 Minor

Copy-paste error in CheckIsChannelBindingDisabled error message.

Line 168 returns "CheckIsNtlmSigningRequired failed: ..." when the failing method is CheckIsChannelBindingDisabled.

🐛 Proposed fix
-            return SharpHoundRPC.Result<bool>.Fail($"CheckIsNtlmSigningRequired failed: {ex}");
+            return SharpHoundRPC.Result<bool>.Fail($"CheckIsChannelBindingDisabled failed: {ex}");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/CommonLib/Processors/DCLdapProcessor.cs` around lines 154 - 169, The
error message in CheckIsChannelBindingDisabled incorrectly references
"CheckIsNtlmSigningRequired"; update the failure return in the catch block of
CheckIsChannelBindingDisabled to use the correct method name (e.g.,
"CheckIsChannelBindingDisabled failed: {ex}") so the returned
SharpHoundRPC.Result<bool>.Fail message accurately identifies the failing
function and includes the exception details.

81-88: ⚠️ Potential issue | 🟡 Minor

Copy-paste bug: isSigningRequired.Status logged in the isChannelBindingDisabled.IsFailed branch.

Line 88 logs isSigningRequired.Status instead of isChannelBindingDisabled.Status, making failure diagnostics for the channel-binding check misleading.

🐛 Proposed fix
-            _log.LogTrace("DCLdapScan failed on IsChannelBindingDisabled for {ComputerName}: {Status}", computerName, isSigningRequired.Status);
+            _log.LogTrace("DCLdapScan failed on IsChannelBindingDisabled for {ComputerName}: {Status}", computerName, isChannelBindingDisabled.Status);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/CommonLib/Processors/DCLdapProcessor.cs` around lines 81 - 88, The log in
the isChannelBindingDisabled failure branch mistakenly references
isSigningRequired.Status; update the DCLdapProcessor failure handling so the
trace log uses isChannelBindingDisabled.Status (the same result used for
SendComputerStatus) — locate the branch around the SendComputerStatus call for
DCLdapIsChannelBindingDisabled and replace the incorrect
isSigningRequired.Status reference in the _log.LogTrace call with
isChannelBindingDisabled.Status to ensure accurate diagnostics.

178-228: ⚠️ Potential issue | 🟠 Major

LdapTransport created locally in Authenticate is never disposed — native LDAP handle leak.

When ldapTransport is null (always the case for calls from CheckIsNtlmSigningRequired and CheckIsChannelBindingDisabled), a new LdapTransport is created at line 183 but never disposed. LdapTransport implements IDisposable and wraps a native LdapConnection; omitting disposal leaks the unmanaged handle on every scan call.

🔧 Proposed fix — dispose only the locally-owned transport
 protected internal virtual async Task<bool> Authenticate(Uri endpoint, LdapAuthOptions options, NtlmAuthenticationHandler? ntlmAuth = null, LdapTransport? ldapTransport = null, CancellationToken cancellationToken = default) {
     var host = endpoint.Host;
     var auth = ntlmAuth ?? new NtlmAuthenticationHandler($"LDAP/{host.ToUpper()}") {
         Options = options
     };
-    var transport = ldapTransport ?? new LdapTransport(_log, endpoint);
+    var ownedTransport = ldapTransport is null ? new LdapTransport(_log, endpoint) : null;
+    var transport = ownedTransport ?? ldapTransport!;
 
     try {
         transport.InitializeConnectionAsync(_ldapTimeout);
         await auth.PerformNtlmAuthenticationAsync(transport, cancellationToken);
         return true;
     } catch (LdapNativeException ex) {
         // ... existing catch blocks ...
-    }
+    } finally {
+        ownedTransport?.Dispose();
+    }
 
     return false;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/CommonLib/Processors/DCLdapProcessor.cs` around lines 178 - 228, The
Authenticate method creates a new LdapTransport when the ldapTransport parameter
is null but never disposes it, leaking the native LdapConnection; update
Authenticate so that when you instantiate a local transport (the local variable
transport when ldapTransport == null) you dispose it after use (e.g., wrap the
created LdapTransport in a using or try/finally that calls Dispose) while
ensuring you do not dispose the incoming ldapTransport parameter passed by
callers (only dispose the locally-owned instance). Ensure this change references
the Authenticate method, the ldapTransport parameter, the transport local
variable, and the LdapTransport type so only the locally-created instance is
cleaned up.
🧹 Nitpick comments (2)
test/unit/Facades/MockExtensions.cs (1)

32-33: VerifyLog is inconsistent with the null-guard added to VerifyLogContains.

VerifyLogContains now explicitly checks o != null before dereferencing, but VerifyLog calls o.ToString() without a null guard. In the #nullable enable context this will also emit a nullable warning for o.ToString(). Aligning the two predicates makes the guard explicit and silences the warning.

♻️ Proposed fix for consistency and nullable compliance
-                It.Is<It.IsAnyType>((o, t) =>
-                    string.Equals(expectedMessage, o.ToString(), StringComparison.InvariantCultureIgnoreCase)),
+                It.Is<It.IsAnyType>((o, t) =>
+                    o != null &&
+                    string.Equals(expectedMessage, o.ToString()!, StringComparison.InvariantCultureIgnoreCase)),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/Facades/MockExtensions.cs` around lines 32 - 33, VerifyLog
currently calls o.ToString() without a null guard, causing a nullable warning
and inconsistency with VerifyLogContains; update the predicate used in VerifyLog
(the It.Is<It.IsAnyType>((o, t) => ... ) lambda) to check o != null before
calling ToString(), e.g. change the predicate to ensure o != null &&
string.Equals(expectedMessage, o.ToString(),
StringComparison.InvariantCultureIgnoreCase) so it matches VerifyLogContains and
silences the nullable warning.
src/CommonLib/Ntlm/LdapTransport.cs (1)

37-37: InitializeConnectionAsync misleadingly named — it is synchronous (void).

The Async suffix implies a Task-returning awaitable. Callers (DCLdapProcessor.Authenticate, line 186) call it without await and the compiler CA1849 / naming analyzer can flag this. Consider renaming to InitializeConnection and adding a proper Task-returning async overload if needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/CommonLib/Ntlm/LdapTransport.cs` at line 37, The method
InitializeConnectionAsync is misleadingly named but is synchronous; rename the
method to InitializeConnection (update its declaration and all call sites, e.g.,
DCLdapProcessor.Authenticate) to satisfy naming conventions, and if asynchronous
behavior is required later add an async Task-returning overload
InitializeConnectionAsync(int timeout = -1) that performs the async work; ensure
call sites either call the new synchronous InitializeConnection or await the new
Task-based InitializeConnectionAsync as appropriate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/CommonLib/Processors/DCLdapProcessor.cs`:
- Around line 154-169: The error message in CheckIsChannelBindingDisabled
incorrectly references "CheckIsNtlmSigningRequired"; update the failure return
in the catch block of CheckIsChannelBindingDisabled to use the correct method
name (e.g., "CheckIsChannelBindingDisabled failed: {ex}") so the returned
SharpHoundRPC.Result<bool>.Fail message accurately identifies the failing
function and includes the exception details.
- Around line 81-88: The log in the isChannelBindingDisabled failure branch
mistakenly references isSigningRequired.Status; update the DCLdapProcessor
failure handling so the trace log uses isChannelBindingDisabled.Status (the same
result used for SendComputerStatus) — locate the branch around the
SendComputerStatus call for DCLdapIsChannelBindingDisabled and replace the
incorrect isSigningRequired.Status reference in the _log.LogTrace call with
isChannelBindingDisabled.Status to ensure accurate diagnostics.
- Around line 178-228: The Authenticate method creates a new LdapTransport when
the ldapTransport parameter is null but never disposes it, leaking the native
LdapConnection; update Authenticate so that when you instantiate a local
transport (the local variable transport when ldapTransport == null) you dispose
it after use (e.g., wrap the created LdapTransport in a using or try/finally
that calls Dispose) while ensuring you do not dispose the incoming ldapTransport
parameter passed by callers (only dispose the locally-owned instance). Ensure
this change references the Authenticate method, the ldapTransport parameter, the
transport local variable, and the LdapTransport type so only the locally-created
instance is cleaned up.

In `@test/unit/WebClientServiceProcessorTest.cs`:
- Around line 29-35: The test WebClientServiceProcessorTest_TestPathExists calls
WebClientServiceProcessor.IsWebClientRunning which uses Windows-only
kernel32.dll CreateFile for named pipes; reintroduce platform gating by
restoring the [WindowsOnlyFact] attribute (or adding
[SupportedOSPlatform("windows")] on the test) so it only runs on Windows, or
alternatively annotate the IsWebClientRunning method with
[SupportedOSPlatform("windows")] to prevent PlatformNotSupportedException on
non-Windows platforms.

---

Nitpick comments:
In `@src/CommonLib/Ntlm/LdapTransport.cs`:
- Line 37: The method InitializeConnectionAsync is misleadingly named but is
synchronous; rename the method to InitializeConnection (update its declaration
and all call sites, e.g., DCLdapProcessor.Authenticate) to satisfy naming
conventions, and if asynchronous behavior is required later add an async
Task-returning overload InitializeConnectionAsync(int timeout = -1) that
performs the async work; ensure call sites either call the new synchronous
InitializeConnection or await the new Task-based InitializeConnectionAsync as
appropriate.

In `@test/unit/Facades/MockExtensions.cs`:
- Around line 32-33: VerifyLog currently calls o.ToString() without a null
guard, causing a nullable warning and inconsistency with VerifyLogContains;
update the predicate used in VerifyLog (the It.Is<It.IsAnyType>((o, t) => ... )
lambda) to check o != null before calling ToString(), e.g. change the predicate
to ensure o != null && string.Equals(expectedMessage, o.ToString(),
StringComparison.InvariantCultureIgnoreCase) so it matches VerifyLogContains and
silences the nullable warning.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 52b978a and a705a68.

📒 Files selected for processing (20)
  • src/CommonLib/Logging/Logging.cs
  • src/CommonLib/Ntlm/LdapTransport.cs
  • src/CommonLib/Processors/DCLdapProcessor.cs
  • src/CommonLib/SMB/NetBIOS/NetBIOSSessionType.cs
  • src/CommonLib/SharpHoundCommonLib.csproj
  • test/unit/ACLProcessorTest.cs
  • test/unit/CertAbuseProcessorTest.cs
  • test/unit/CommonLibHelperTests.cs
  • test/unit/CommonLibTest.csproj
  • test/unit/DCLdapProcessorTest.cs
  • test/unit/DomainTrustProcessorTest.cs
  • test/unit/Facades/FacadeHelpers.cs
  • test/unit/Facades/MockExtensions.cs
  • test/unit/GPOLocalGroupProcessorTest.cs
  • test/unit/GroupProcessorTest.cs
  • test/unit/LDAPUtilsTest.cs
  • test/unit/LdapPropertyTests.cs
  • test/unit/LocalGroupProcessorTest.cs
  • test/unit/UserRightsAssignmentProcessorTest.cs
  • test/unit/WebClientServiceProcessorTest.cs
💤 Files with no reviewable changes (1)
  • test/unit/DCLdapProcessorTest.cs

@lrfalslev lrfalslev changed the title BED-7491 Resolve build warnings BED-7491 Feb 26, 2026
@lrfalslev lrfalslev merged commit 2156a25 into v4 Mar 5, 2026
4 checks passed
@lrfalslev lrfalslev deleted the lfalslev/bed-7491 branch March 5, 2026 17:37
@github-actions github-actions bot locked and limited conversation to collaborators Mar 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants