Repository navigation
fix: address 10 high-priority code review findings #294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -75,7 +75,7 @@ private async Task ScanAsync() | |
| } | ||
| } | ||
|
|
||
| [RelayCommand] | ||
| [RelayCommand(CanExecute = nameof(CanToggle))] | ||
| private async Task ToggleFeatureAsync(WindowsFeature? feature) | ||
|
Comment on lines
+78
to
79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an in-method re-entrancy guard in
Proposed fix private async Task ToggleFeatureAsync(WindowsFeature? feature)
{
- if (feature == null) return;
+ if (IsBusy || feature == null) return;Also applies to: 81-82, 155-155 🤖 Prompt for AI Agents |
||
| { | ||
| if (feature == null) return; | ||
|
|
@@ -152,6 +152,8 @@ private async Task ToggleFeatureAsync(WindowsFeature? feature) | |
| [RelayCommand] | ||
| private void Cancel() => _cts?.Cancel(); | ||
|
|
||
| private bool CanToggle(WindowsFeature? _) => !IsBusy; | ||
|
|
||
| protected override void Dispose(bool disposing) | ||
| { | ||
| if (disposing) _cts?.Dispose(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -20,12 +20,14 @@ public ConsoleView() | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| System.Windows.FrameworkElement.RequestBringIntoViewEvent, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new System.Windows.RequestBringIntoViewEventHandler((s, e) => e.Handled = true)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DataContextChanged += (_, __) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DataContextChanged += (_, args) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (DataContext is ConsoleViewModel vm) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // MEM-003: unsubscribe from previous DataContext to prevent leak | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (args.OldValue is ConsoleViewModel oldVm) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| oldVm.Lines.CollectionChanged -= OnLinesChanged; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (args.NewValue is ConsoleViewModel vm) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vm.Lines.CollectionChanged += OnLinesChanged; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+23
to
31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also detach from current This fixes DataContext swaps, but not the case where the control is unloaded without a DataContext change. Add unload-time unsubscription to fully close the leak path. Proposed fix public ConsoleView()
{
InitializeComponent();
+ Unloaded += OnUnloaded;
@@
};
}
+
+ private void OnUnloaded(object sender, System.Windows.RoutedEventArgs e)
+ {
+ if (DataContext is ConsoleViewModel vm)
+ vm.Lines.CollectionChanged -= OnLinesChanged;
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,8 @@ namespace SysManager.Views; | |
|
|
||
| public partial class PerformanceView : UserControl | ||
| { | ||
| private System.ComponentModel.PropertyChangedEventHandler? _propertyHandler; | ||
|
|
||
| public PerformanceView() | ||
| { | ||
| InitializeComponent(); | ||
|
|
@@ -18,13 +20,18 @@ public PerformanceView() | |
|
|
||
| private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) | ||
| { | ||
| // MEM-004: unsubscribe from previous VM to prevent leak | ||
| if (e.OldValue is PerformanceViewModel oldVm && _propertyHandler != null) | ||
| oldVm.PropertyChanged -= _propertyHandler; | ||
|
|
||
| if (e.NewValue is PerformanceViewModel vm) | ||
| { | ||
| vm.PropertyChanged += (_, args) => | ||
| _propertyHandler = (_, args) => | ||
| { | ||
| if (args.PropertyName == nameof(PerformanceViewModel.SelectedPlan)) | ||
| SyncRadioButtons(vm.SelectedPlan); | ||
| }; | ||
| vm.PropertyChanged += _propertyHandler; | ||
| SyncRadioButtons(vm.SelectedPlan); | ||
| } | ||
| } | ||
|
Comment on lines
21
to
37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsubscribe Current logic handles DataContext swaps, but if the view unloads with the same VM, the VM can still retain the view via the handler. Proposed fix public PerformanceView()
{
InitializeComponent();
DataContextChanged += OnDataContextChanged;
+ Unloaded += OnUnloaded;
}
@@
}
+
+ private void OnUnloaded(object sender, RoutedEventArgs e)
+ {
+ if (DataContext is PerformanceViewModel vm && _propertyHandler != null)
+ vm.PropertyChanged -= _propertyHandler;
+ }🤖 Prompt for AI Agents |
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fail closed on Ookla hash mismatch.
Hash mismatch currently only logs and continues, which nullifies the pinning control and permits untrusted binaries to proceed.
Proposed fix
var expectedHash = arch == "win64" ? PinnedHashWin64 : PinnedHashWin32; if (!string.Equals(hash, expectedHash, StringComparison.OrdinalIgnoreCase)) { - Log.Warning("Ookla CLI hash mismatch! Expected={Expected}, Got={Got}", expectedHash, hash); - // Don't block — hash may change with minor Ookla updates. - // Log warning but allow if zip is structurally valid. + Log.Warning("Ookla CLI hash mismatch! Expected={Expected}, Got={Got}", expectedHash, hash); + File.Delete(zipPath); + throw new InvalidOperationException("Downloaded Ookla CLI hash mismatch"); }📝 Committable suggestion
🤖 Prompt for AI Agents