Skip to content

fix: address code review findings (QA, security, thread-safety) - #249

Merged
laurentiu021 merged 1 commit into
mainfrom
fix/code-review-batch
May 12, 2026
Merged

laurentiu021 merged 1 commit into
mainfrom
fix/code-review-batch

Conversation

@laurentiu021

@laurentiu021 laurentiu021 commented May 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

Fixes 8 issues identified in the review.

Changes

Bug Fixes

  • TEST-004: UpdateServiceTests expects SystemManager (repo rename)
  • QA-002: Null-safe filter in ProcessManagerViewModel.ApplyFilter
  • QA-003: ConcurrentDictionary for NetworkSharedState.Buffers/TraceBuffers
  • QA-001: Await AnalyzeAsync in DiskAnalyzerViewModel DrillDown/GoUp
  • CQ-005: Dispatcher.BeginInvoke in ConsoleViewModel (non-blocking)

Security

  • SEC-003: Regex validation on chkdsk drive letter (^[A-Z]:$)
  • SEC-004: Regex validation on AppBlockerService exeName
  • SEC-002: Parameterized PowerShell in CreateRestorePointAsync

Testing

  • Build: 0 errors
  • All changes are minimal (1-5 lines each), low risk

- TEST-004: UpdateServiceTests expects 'SystemManager' (repo rename)
- QA-002: null-safe filter in ProcessManagerViewModel.ApplyFilter
- QA-003: ConcurrentDictionary for NetworkSharedState.Buffers/TraceBuffers
- SEC-003: regex validation on chkdsk drive letter (^[A-Z]:$)
- SEC-004: regex validation on AppBlockerService exeName
- QA-001: await AnalyzeAsync in DiskAnalyzerViewModel DrillDown/GoUp
- CQ-005: Dispatcher.BeginInvoke in ConsoleViewModel (non-blocking)
- SEC-002: parameterized PowerShell in CreateRestorePointAsync
@coderabbitai

coderabbitai Bot commented May 12, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR applies security hardening, concurrency fixes, and robustness improvements across multiple system services. Input validation prevents injection attacks in executable names and drive letters; PowerShell execution is parameterized to avoid script injection; threading is corrected by eliminating fire-and-forget races and enabling thread-safe concurrent access; null-safety is improved with defensive filtering.

Changes

Security, Concurrency, and Robustness Hardening

Layer / File(s) Summary
Security input validation and parameterized execution
SysManager/SysManager/Services/AppBlockerService.cs, SysManager/SysManager/Services/PerformanceService.cs, SysManager/SysManager/ViewModels/SystemHealthViewModel.cs
AppBlockerService validates executable names against a whitelist regex to prevent registry path injection; PerformanceService switches from string-concatenated PowerShell scripts to parameterized command execution with $desc parameter; SystemHealthViewModel validates drive-letter format (^[A-Z]:$) before passing to chkdsk.
Concurrency and threading fixes
SysManager/SysManager/ViewModels/ConsoleViewModel.cs, SysManager/SysManager/ViewModels/DiskAnalyzerViewModel.cs, SysManager/SysManager/ViewModels/NetworkSharedState.cs
ConsoleViewModel switches Dispatcher.Invoke to BeginInvoke for non-blocking cross-thread marshaling; DiskAnalyzerViewModel converts DrillDown and GoUp from fire-and-forget to async Task with awaited AnalyzeAsync() calls; NetworkSharedState upgrades Buffers and TraceBuffers to ConcurrentDictionary and uses TryRemove for safe cleanup.
Null-safety filtering
SysManager/SysManager/ViewModels/ProcessManagerViewModel.cs
ApplyFilter() uses null-safe ?.Contains() checks with fallback on process metadata fields (Description, PlainDescription, Category) to prevent null reference exceptions.
Test expectation and changelog updates
SysManager/SysManager.IntegrationTests/UpdateServiceTests.cs, CHANGELOG.md
UpdateServiceTests updates expected repository constant from "SysManager" to "SystemManager"; CHANGELOG.md documents all fixes and security entries.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Security and threads align,
Validation guards the input line,
Concurrency grows safe and sound,
No more fire-and-forget around,
Polish shines, and bugs decline!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the pull request's primary focus: addressing multiple code review findings across QA, security, and thread-safety domains.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/code-review-batch

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 35.00000% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...sManager/SysManager/Services/PerformanceService.cs 0.00% 4 Missing ⚠️
...ysManager/SysManager/Services/AppBlockerService.cs 0.00% 3 Missing ⚠️
...ger/SysManager/ViewModels/SystemHealthViewModel.cs 0.00% 3 Missing ⚠️
...ger/SysManager/ViewModels/DiskAnalyzerViewModel.cs 0.00% 2 Missing ⚠️
...sManager/SysManager/ViewModels/ConsoleViewModel.cs 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@SysManager/SysManager/Services/AppBlockerService.cs`:
- Around line 35-40: Introduce a centralized validation helper (e.g.,
ValidateExeName or IsValidExeName) that encapsulates the SEC-004 regex
(@"^[A-Za-z0-9_\-. ]+\.exe$" with RegexOptions.IgnoreCase) and use it at the
start of BlockApp, UnblockApp, and IsBlocked to return false (or short-circuit)
and Log.Warning when validation fails; ensure all registry reads/writes in those
methods occur only after this helper approves the exeName to eliminate the
current bypass risk.

In `@SysManager/SysManager/Services/PerformanceService.cs`:
- Around line 514-517: The success check using results != null is ineffective
because _ps.RunAsync(...) always returns a Collection; update the
Checkpoint-Computer invocation in PerformanceService.Checkpoint (the code
calling _ps.RunAsync with script, parameters, ct) to detect failures by adding
"-ErrorAction Stop" to the PowerShell script and wrap the await
_ps.RunAsync(...) call in a try/catch to treat exceptions as failures (or
alternatively inspect the PowerShell error stream returned by your RunAsync
implementation) and return true only on success, false on exception/error.

In `@SysManager/SysManager/ViewModels/NetworkSharedState.cs`:
- Around line 47-48: The ContainsKey + indexer pattern on the
ConcurrentDictionary fields Buffers (and similarly TraceBuffers) can race with
concurrent removals; replace those checks with atomic retrieval using
ConcurrentDictionary.TryGetValue (or GetOrAdd where appropriate) so you obtain
the collection instance in one operation before operating on it (e.g., in your
flush method use Buffers.TryGetValue(key, out var buffer) and only proceed if
buffer is non-null), and if you need to remove the entry during the operation
use TryRemove to avoid TOCTOU failures.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0a81c2e2-a49f-4977-95ba-54f915d52fd6

📥 Commits

Reviewing files that changed from the base of the PR and between c00751f and 1612df7.

📒 Files selected for processing (9)
  • CHANGELOG.md
  • SysManager/SysManager.IntegrationTests/UpdateServiceTests.cs
  • SysManager/SysManager/Services/AppBlockerService.cs
  • SysManager/SysManager/Services/PerformanceService.cs
  • SysManager/SysManager/ViewModels/ConsoleViewModel.cs
  • SysManager/SysManager/ViewModels/DiskAnalyzerViewModel.cs
  • SysManager/SysManager/ViewModels/NetworkSharedState.cs
  • SysManager/SysManager/ViewModels/ProcessManagerViewModel.cs
  • SysManager/SysManager/ViewModels/SystemHealthViewModel.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build & unit tests
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (7)
SysManager/SysManager.IntegrationTests/UpdateServiceTests.cs (1)

82-82: Repo constant assertion update looks correct.

This matches the renamed repository and keeps the integration test aligned with runtime constants.

SysManager/SysManager/ViewModels/ProcessManagerViewModel.cs (1)

144-146: Null-safe filter update is solid.

Good fix for nullable metadata fields in the process filter predicate.

SysManager/SysManager/ViewModels/SystemHealthViewModel.cs (1)

200-205: Drive-letter validation hardening is well implemented.

Early rejection of invalid formats is the right guardrail before building the chkdsk command args.

SysManager/SysManager/ViewModels/ConsoleViewModel.cs (1)

31-31: Switch to non-blocking UI dispatch is a good concurrency improvement.

BeginInvoke is a safer fit here than synchronous marshal for high-frequency console updates.

SysManager/SysManager/ViewModels/DiskAnalyzerViewModel.cs (1)

168-175: Awaiting AnalyzeAsync() in navigation commands is the right fix.

This removes fire-and-forget behavior and makes DrillDown/GoUp command flow deterministic.

Also applies to: 178-186

CHANGELOG.md (2)

10-23: Changelog “Fixed” entries are clear and well-scoped.

The added notes are specific, map cleanly to issue IDs, and are consistent with the PR objectives.


24-30: Security changelog entries look solid and actionable.

Good level of detail on validation patterns and parameterization approach, with clear traceability to SEC tickets.

Comment on lines +35 to +40
// SEC-004: reject path separators and invalid chars to prevent registry path injection
if (!System.Text.RegularExpressions.Regex.IsMatch(exeName, @"^[A-Za-z0-9_\-. ]+\.exe$", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
{
Log.Warning("Rejected invalid exeName: {ExeName}", exeName);
return false;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify all AppBlockerService entry points and their validation paths.
rg -n -C3 '\b(public static bool (BlockApp|UnblockApp|IsBlocked)\s*\()' SysManager/SysManager/Services/AppBlockerService.cs
rg -n -C3 'Regex\.IsMatch\(|EndsWith\("\.exe"' SysManager/SysManager/Services/AppBlockerService.cs
rg -n -C3 '\b(AppBlockerService\.)?(BlockApp|UnblockApp|IsBlocked)\s*\(' --type=cs

Repository: laurentiu021/SystemManager

Length of output: 6034


🏁 Script executed:

cat -n SysManager/SysManager/Services/AppBlockerService.cs | head -150

Repository: laurentiu021/SystemManager

Length of output: 6465


Centralize exeName validation across BlockApp, UnblockApp, and IsBlocked.

Only BlockApp enforces the regex validation (SEC-004) before registry operations. UnblockApp and IsBlocked access/modify registry keys without this check, creating a security gap where malicious input (e.g., path traversal with \ or ..) could bypass validation.

Create a shared validation helper and use it in all three methods before any registry operations:

Suggested refactor
+    private static bool TryNormalizeExeName(string input, out string exeName)
+    {
+        exeName = input?.Trim() ?? "";
+        if (string.IsNullOrWhiteSpace(exeName)) return false;
+        if (!exeName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
+            exeName += ".exe";
+        return System.Text.RegularExpressions.Regex.IsMatch(
+            exeName,
+            @"^[A-Za-z0-9_\-. ]+\.exe$",
+            System.Text.RegularExpressions.RegexOptions.IgnoreCase);
+    }

Use this in BlockApp (line 28), UnblockApp (line 73), and IsBlocked (line 123) before registry access.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SysManager/SysManager/Services/AppBlockerService.cs` around lines 35 - 40,
Introduce a centralized validation helper (e.g., ValidateExeName or
IsValidExeName) that encapsulates the SEC-004 regex (@"^[A-Za-z0-9_\-. ]+\.exe$"
with RegexOptions.IgnoreCase) and use it at the start of BlockApp, UnblockApp,
and IsBlocked to return false (or short-circuit) and Log.Warning when validation
fails; ensure all registry reads/writes in those methods occur only after this
helper approves the exeName to eliminate the current bypass risk.

Comment on lines +514 to +517
var script = "Checkpoint-Computer -Description $desc -RestorePointType 'MODIFY_SETTINGS'";
var parameters = new Dictionary<string, object?> { ["desc"] = description };
var results = await _ps.RunAsync(script, parameters, ct).ConfigureAwait(false);
return results != null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify PowerShellRunner.RunAsync behavior and current callers' success checks.
for f in $(fd -i PowerShellRunner.cs); do
  echo "=== $f ==="
  rg -n -C6 'RunAsync\s*\(|RunProcessAsync\s*\(|RunScriptViaPwshAsync\s*\(' "$f"
done

echo "=== CreateRestorePointAsync call site ==="
rg -n -C8 'CreateRestorePointAsync|RunAsync\s*\(' SysManager/SysManager/Services/PerformanceService.cs

Repository: laurentiu021/SystemManager

Length of output: 3576


🏁 Script executed:

#!/bin/bash
# Get full RunAsync implementation to see error handling
rg -n -A 80 'public async Task<Collection<PSObject>> RunAsync' SysManager/SysManager/Services/PowerShellRunner.cs | head -100

Repository: laurentiu021/SystemManager

Length of output: 3970


🏁 Script executed:

#!/bin/bash
# Check if RunAsync can return null and how errors are handled
rg -n 'return null|throw|catch|error' SysManager/SysManager/Services/PowerShellRunner.cs | head -30

Repository: laurentiu021/SystemManager

Length of output: 405


🌐 Web query:

PowerShell Checkpoint-Computer cmdlet output success behavior

💡 Result:

In Windows PowerShell, Checkpoint-Computer produces no output on success; you detect success only via the absence of terminating/non-terminating errors (or by checking after the fact with Get-ComputerRestorePoint). [1] If the restore point cannot be created (for example, Windows’ “max one restore point per 24 hours” restriction), PowerShell generates an error message instead of returning a success value/output. [1] Practical implications: - There is no “success object”/return value to capture from Checkpoint-Computer. - Use try/catch (and/or -ErrorAction Stop) to treat failure as an error condition. - If you need positive verification, query the system restore points after the call with Get-ComputerRestorePoint. [2] Example pattern (Windows PowerShell): try { Checkpoint-Computer -Description "Install MyApp" -ErrorAction Stop # success: no error thrown; optionally verify # Get-ComputerRestorePoint |... } catch { # failure throw } Notes: - Checkpoint-Computer is deprecated/removed in PowerShell 6+ (still relevant for Windows PowerShell 5.1). [3]

Citations:


RunAsync always returns a non-null Collection, making the success check ineffective.

Checkpoint-Computer produces no output on success and writes errors to the PowerShell error stream, not the output collection. Since RunAsync always returns a Collection<PSObject> (never null) and only captures output objects—not error status—the check results != null will always return true, even when the command fails. The method needs to either inspect the error stream or use -ErrorAction Stop to properly detect command failure.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SysManager/SysManager/Services/PerformanceService.cs` around lines 514 - 517,
The success check using results != null is ineffective because _ps.RunAsync(...)
always returns a Collection; update the Checkpoint-Computer invocation in
PerformanceService.Checkpoint (the code calling _ps.RunAsync with script,
parameters, ct) to detect failures by adding "-ErrorAction Stop" to the
PowerShell script and wrap the await _ps.RunAsync(...) call in a try/catch to
treat exceptions as failures (or alternatively inspect the PowerShell error
stream returned by your RunAsync implementation) and return true only on
success, false on exception/error.

Comment on lines +47 to +48
internal readonly ConcurrentDictionary<string, ObservableCollection<DateTimePoint>> Buffers = new();
internal readonly ConcurrentDictionary<string, ObservableCollection<ObservablePoint>> TraceBuffers = new();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify TOCTOU dictionary access patterns in NetworkSharedState.
rg -n -C3 'Buffers\.ContainsKey|Buffers\[[^]]+\]' SysManager/SysManager/ViewModels/NetworkSharedState.cs
rg -n -C3 'TraceBuffers\.ContainsKey|TraceBuffers\[[^]]+\]' SysManager/SysManager/ViewModels/NetworkSharedState.cs

Repository: laurentiu021/SystemManager

Length of output: 1176


🏁 Script executed:

#!/bin/bash
# Get context around lines 232-233
sed -n '228,237p' SysManager/SysManager/ViewModels/NetworkSharedState.cs

# Search for all ContainsKey + indexer patterns more broadly
rg -n 'Buffers\.ContainsKey|TraceBuffers\.ContainsKey' SysManager/SysManager/ViewModels/NetworkSharedState.cs

# Check entire file structure to understand the context
wc -l SysManager/SysManager/ViewModels/NetworkSharedState.cs

Repository: laurentiu021/SystemManager

Length of output: 759


🏁 Script executed:

#!/bin/bash
# Get exact lines around 232-233 with more context
sed -n '220,240p' SysManager/SysManager/ViewModels/NetworkSharedState.cs | cat -n

# Search for all patterns where Buffers or TraceBuffers are accessed with indexer
rg -n '\bBuffers\[.*\]|\bTraceBuffers\[.*\]' SysManager/SysManager/ViewModels/NetworkSharedState.cs

# Search for all ContainsKey calls to find every potential TOCTOU
rg -n '\bContainsKey\(' SysManager/SysManager/ViewModels/NetworkSharedState.cs

Repository: laurentiu021/SystemManager

Length of output: 1383


🏁 Script executed:

#!/bin/bash
# Get full context around line 324-326
sed -n '320,340p' SysManager/SysManager/ViewModels/NetworkSharedState.cs | cat -n

# Search specifically for TraceBuffers with ContainsKey pattern
rg -n -A2 'TraceBuffers\.ContainsKey' SysManager/SysManager/ViewModels/NetworkSharedState.cs

Repository: laurentiu021/SystemManager

Length of output: 1051


Fix TOCTOU race condition with ContainsKey + indexer access on Buffers.

At lines 324-326, the ContainsKey check does not guarantee the key still exists when accessed via indexer, since removals can happen concurrently in other threads. This can cause KeyNotFoundException intermittently during flush operations.

Suggested fix
-        foreach (var host in touched.Where(h => Buffers.ContainsKey(h)))
-        {
-            var buffer = Buffers[host];
+        foreach (var host in touched)
+        {
+            if (!Buffers.TryGetValue(host, out var buffer)) continue;
             TrimBuffer(buffer);
             var target = Targets.FirstOrDefault(t => t.Host == host);
             if (target == null) continue;
             RecomputeStats(target, buffer);
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SysManager/SysManager/ViewModels/NetworkSharedState.cs` around lines 47 - 48,
The ContainsKey + indexer pattern on the ConcurrentDictionary fields Buffers
(and similarly TraceBuffers) can race with concurrent removals; replace those
checks with atomic retrieval using ConcurrentDictionary.TryGetValue (or GetOrAdd
where appropriate) so you obtain the collection instance in one operation before
operating on it (e.g., in your flush method use Buffers.TryGetValue(key, out var
buffer) and only proceed if buffer is non-null), and if you need to remove the
entry during the operation use TryRemove to avoid TOCTOU failures.

@laurentiu021
laurentiu021 merged commit 6768b91 into main May 12, 2026
5 checks passed
@laurentiu021
laurentiu021 deleted the fix/code-review-batch branch May 12, 2026 06:20
This was referenced May 12, 2026
laurentiu021 added a commit that referenced this pull request May 22, 2026
)

## Summary

Offloads synchronous operations that were running on the WPF dispatcher
thread to the thread pool, eliminating UI freezes of 1-10 seconds across
three tabs.

## Changes

### PowerShellRunner.cs
- **RunProcessAsync**: Wrap \Process.Start()\ + \BeginOutputReadLine()\
+ \BeginErrorReadLine()\ in \Task.Run\ — process creation (especially
\powershell.exe\ with its slow startup) no longer blocks the UI thread
- **RunAsync**: Offload \ unspace.Open()\ to thread pool — in-process
PowerShell runspace initialization no longer blocks the dispatcher

### SpeedTestService.cs
- **EnsureOoklaAsync**: Move all synchronous file-system I/O
(\Directory.CreateDirectory\, \File.Exists\, \FileInfo.Length\,
\ZipFile.ExtractToDirectory\) to \Task.Run\
- **RunOoklaAsync**: Offload \Process.Start\ for \speedtest.exe\ to
thread pool

### DeepCleanupViewModel.cs
- **ScanAsync**: Separate \PropertyChanged\ event wiring from
\Categories.Add()\ loop to reduce per-item UI re-renders during
collection population

## Testing
- Build: 0 errors (main project + tests)
- Existing tests unaffected — changes are purely async scheduling, no
behavior change
- All \ConfigureAwait(false)\ applied where continuation doesn't need UI
context

Closes #261, Closes #258, Closes #249

Co-authored-by: laurentiu021 <laurentiu021@users.noreply.github.com>
laurentiu021 added a commit that referenced this pull request May 22, 2026
- TEST-004: UpdateServiceTests expects 'SystemManager' (repo rename)
- QA-002: null-safe filter in ProcessManagerViewModel.ApplyFilter
- QA-003: ConcurrentDictionary for NetworkSharedState.Buffers/TraceBuffers
- SEC-003: regex validation on chkdsk drive letter (^[A-Z]:$)
- SEC-004: regex validation on AppBlockerService exeName
- QA-001: await AnalyzeAsync in DiskAnalyzerViewModel DrillDown/GoUp
- CQ-005: Dispatcher.BeginInvoke in ConsoleViewModel (non-blocking)
- SEC-002: parameterized PowerShell in CreateRestorePointAsync

Co-authored-by: laurentiu021 <laurentiu021@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants