Skip to content

Commit 1c81886

Browse files
CodeQL cleanup in the Control Panel Views layer
Every change is behaviour-preserving; the analysis of each finding said so before the edit did. Misleading indentation (5): all five were the stacked multi-foreach idiom (inner loop unindented under its outer), not latent bugs - the full cross product is intended at every site. FindSetting_ became SelectMany/ FirstOrDefault, the two AssignAccessibleNames became braced nested loops, the BuildUi wiring loop was indented, and Save_Click's triple loop became a SelectMany flattening (its body never used tab or card). Dead store: ApiKeysView dropped the unused 'label' capture of Field_'s return - the helper adds the control to the panel itself, and the two sibling call sites already discard it. LINQ shape (10): find-first loops became FirstOrDefault (TLS certificate lookups, SSL grid reselect), digit scans became All(char.IsAsciiDigit) (backup archive-name parsing), the activity scan became nested Any, and filter/projection prologues moved into Where/Select where the predicate is pure and order is unchanged. CertificateNameFor keeps its exact found-but-null-Name behaviour. Also combined one nested if (IniNumber.CreateEditor - TryParse assigns the out var on every path, so the merge is exact), removed a genuine cast-to-self on the statically-typed ServerSession.Host, and added the two missing XML doc summaries.
1 parent 060b542 commit 1c81886

10 files changed

Lines changed: 59 additions & 95 deletions

hmailserver/source/Tools/ControlPanel/Views/AccessibleChartCard.cs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
44
using System.Globalization;
5+
using System.Linq;
56
using System.Windows;
67
using System.Windows.Automation;
78
using System.Windows.Controls;
@@ -840,16 +841,7 @@ private IReadOnlyList<ChartSeriesSamples> SeriesSamples_()
840841

841842
private bool HasActivity_()
842843
{
843-
foreach (List<double?> series in samples_)
844-
{
845-
foreach (double? value in series)
846-
{
847-
if (value.GetValueOrDefault() > 0)
848-
return true;
849-
}
850-
}
851-
852-
return false;
844+
return samples_.Any(series => series.Any(value => value.GetValueOrDefault() > 0));
853845
}
854846

855847
private static SKColor Skia_(uint argb)

hmailserver/source/Tools/ControlPanel/Views/ApiKeysView.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ public static ApiKeyRequest Ask(Window owner)
610610
"The key is shown once, when it is created, and never again. It is live immediately - the server "
611611
+ "re-reads its key store on every request."));
612612

613-
var label = Field_(panel, "Label", "What this key is for, e.g. \"Grafana probe\"", out TextBox labelBox);
613+
Field_(panel, "Label", "What this key is for, e.g. \"Grafana probe\"", out TextBox labelBox);
614614
System.Windows.Automation.AutomationProperties.SetAutomationId(labelBox, "apikeys-dialog-label");
615615

616616
// Read-only first and selected by default, matching the server: a create

hmailserver/source/Tools/ControlPanel/Views/BackupView.xaml.cs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Globalization;
3+
using System.Linq;
34
using System.Windows;
45
using System.Windows.Controls;
56
using System.Windows.Documents;
@@ -346,9 +347,9 @@ private void RefreshScheduleStatus()
346347

347348
try
348349
{
349-
foreach (string file in System.IO.Directory.EnumerateFiles(destination))
350+
foreach (string name in System.IO.Directory.EnumerateFiles(destination)
351+
.Select(System.IO.Path.GetFileName))
350352
{
351-
string name = System.IO.Path.GetFileName(file);
352353
if (TryParseArchiveName(name, out DateTime created) &&
353354
(newestName == null || created > newestTime))
354355
{
@@ -469,12 +470,10 @@ private static bool TryParseTimeOfDay(string value, out int hour, out int minute
469470
if (hourPart.Length > 2 || minutePart.Length != 2)
470471
return false;
471472

472-
foreach (char c in hourPart)
473-
if (!char.IsAsciiDigit(c))
474-
return false;
475-
foreach (char c in minutePart)
476-
if (!char.IsAsciiDigit(c))
477-
return false;
473+
if (!hourPart.All(char.IsAsciiDigit))
474+
return false;
475+
if (!minutePart.All(char.IsAsciiDigit))
476+
return false;
478477

479478
int parsedHour = int.Parse(hourPart, CultureInfo.InvariantCulture);
480479
int parsedMinute = int.Parse(minutePart, CultureInfo.InvariantCulture);
@@ -512,9 +511,8 @@ private static bool TryParseArchiveName(string fileName, out DateTime created)
512511
return false;
513512

514513
int[] dateDigitOffsets = { 9, 10, 11, 12, 14, 15, 17, 18 };
515-
foreach (int offset in dateDigitOffsets)
516-
if (!char.IsAsciiDigit(fileName[offset]))
517-
return false;
514+
if (!dateDigitOffsets.All(offset => char.IsAsciiDigit(fileName[offset])))
515+
return false;
518516

519517
for (int offset = 20; offset <= 25; offset++)
520518
if (!char.IsAsciiDigit(fileName[offset]))

hmailserver/source/Tools/ControlPanel/Views/CollectionEditorView.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public CollectionEditorView(CollectionSpec spec) : this(spec, false)
7474
{
7575
}
7676

77+
/// <summary>Creates the editor for one collection, optionally without page chrome.</summary>
7778
/// <param name="embedded">
7879
/// When true the page chrome (large title/subtitle and outer page margins)
7980
/// is dropped so the editor can be hosted inside a dialog tab. Only a
@@ -421,11 +422,8 @@ public object Convert(object value, Type t, object p, CultureInfo c)
421422
try
422423
{
423424
int number = System.Convert.ToInt32(value, CultureInfo.InvariantCulture);
424-
foreach ((int Value, string Label) option in options_)
425-
{
426-
if (option.Value == number)
427-
return option.Label;
428-
}
425+
foreach ((int Value, string Label) option in options_.Where(o => o.Value == number))
426+
return option.Label;
429427
}
430428
catch (FormatException)
431429
{

hmailserver/source/Tools/ControlPanel/Views/DirectorySyncView.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using System.Runtime.InteropServices;
45
using System.Text;
56
using System.Threading.Tasks;
@@ -890,17 +891,11 @@ private void RenderRows_(DirectorySyncReport report)
890891
{
891892
// The rows that cost something first. Four hundred lines of equal weight is a
892893
// log; the six that matter have to be at the top or they are not read at all.
893-
foreach (DirectorySyncRow row in report.Rows)
894-
{
895-
if (row.NeedsAttention)
896-
rows_.Children.Add(Row_(row, true));
897-
}
894+
foreach (DirectorySyncRow row in report.Rows.Where(r => r.NeedsAttention))
895+
rows_.Children.Add(Row_(row, true));
898896

899-
foreach (DirectorySyncRow row in report.Rows)
900-
{
901-
if (!row.NeedsAttention)
902-
rows_.Children.Add(Row_(row, false));
903-
}
897+
foreach (DirectorySyncRow row in report.Rows.Where(r => !r.NeedsAttention))
898+
rows_.Children.Add(Row_(row, false));
904899

905900
if (report.SkipBreakdown.Count == 0)
906901
return;

hmailserver/source/Tools/ControlPanel/Views/DnsRecordsView.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,9 +1620,8 @@ private static string DescribeFound(List<string> records)
16201620
/// the comparison in DnsTxtLookup.</summary>
16211621
private static string ParseTag(string record, string tag)
16221622
{
1623-
foreach (string part in (record ?? "").Split(';'))
1623+
foreach (string trimmed in (record ?? "").Split(';').Select(part => part.Trim()))
16241624
{
1625-
string trimmed = part.Trim();
16261625
int equals = trimmed.IndexOf('=');
16271626
if (equals > 0 && trimmed.Substring(0, equals).Trim().Equals(tag, StringComparison.OrdinalIgnoreCase))
16281627
return trimmed.Substring(equals + 1).Trim();

hmailserver/source/Tools/ControlPanel/Views/FeatureSettingsView.xaml.cs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,7 @@ private class ElsewhereSetting : Setting
692692
{
693693
private readonly string page_;
694694

695+
/// <summary>Creates a signpost row pointing at the page that owns a setting.</summary>
695696
/// <param name="page">Nav key of the page that owns the setting.</param>
696697
/// <param name="caption">What is over there, in the administrator's words.</param>
697698
public ElsewhereSetting(string page, string caption)
@@ -804,14 +805,9 @@ private Setting FindSetting_(string key)
804805
if (cards_ == null)
805806
return null;
806807

807-
foreach (CardDef card in cards_)
808-
foreach (Setting setting in card.Settings)
809-
{
810-
if (string.Equals(setting.Key, key, StringComparison.OrdinalIgnoreCase))
811-
return setting;
812-
}
813-
814-
return null;
808+
return cards_
809+
.SelectMany(card => card.Settings)
810+
.FirstOrDefault(setting => string.Equals(setting.Key, key, StringComparison.OrdinalIgnoreCase));
815811
}
816812

817813
private string LiveText_(string key, string fallbackDefault)
@@ -2703,10 +2699,12 @@ private void AssignAccessibleNames()
27032699
var editors = new List<LabelledEditor>();
27042700

27052701
foreach (CardDef card in cards_)
2706-
foreach (Setting setting in card.Settings)
27072702
{
2708-
settings.Add(setting);
2709-
editors.Add(new LabelledEditor(setting.Label, card.Title, setting.Key));
2703+
foreach (Setting setting in card.Settings)
2704+
{
2705+
settings.Add(setting);
2706+
editors.Add(new LabelledEditor(setting.Label, card.Title, setting.Key));
2707+
}
27102708
}
27112709

27122710
IReadOnlyList<string> names = AccessibleNames.Resolve(editors);
@@ -2772,8 +2770,8 @@ private void BuildUi()
27722770
// Wire every editor to the warnings AFTER all the editors exist, because
27732771
// a warning may read a setting on a later card than its own.
27742772
foreach (CardDef card in cards_)
2775-
foreach (Setting setting in card.Settings)
2776-
setting.OnEditorChanged(RefreshWarnings_);
2773+
foreach (Setting setting in card.Settings)
2774+
setting.OnEditorChanged(RefreshWarnings_);
27772775

27782776
RefreshWarnings_();
27792777

hmailserver/source/Tools/ControlPanel/Views/ServerSettingsView.xaml.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -458,10 +458,10 @@ private class SectionIniNumber : ComSetting, IIniSetting
458458
public override FrameworkElement CreateEditor(object value)
459459
{
460460
int current = Default;
461-
if (IniStore != null && IniStore.IsAvailable)
461+
if (IniStore != null && IniStore.IsAvailable &&
462+
!int.TryParse(IniStore.ReadFrom(Section, Path, Default.ToString()), out current))
462463
{
463-
if (!int.TryParse(IniStore.ReadFrom(Section, Path, Default.ToString()), out current))
464-
current = Default;
464+
current = Default;
465465
}
466466

467467
var panel = new StackPanel();
@@ -2581,11 +2581,15 @@ private void AssignAccessibleNames()
25812581
var editors = new List<LabelledEditor>();
25822582

25832583
foreach (TabDef tab in tabs_)
2584-
foreach (CardDef card in tab.Cards)
2585-
foreach (ComSetting setting in card.Settings)
25862584
{
2587-
settings.Add(setting);
2588-
editors.Add(new LabelledEditor(setting.Label, card.Title, setting.Path));
2585+
foreach (CardDef card in tab.Cards)
2586+
{
2587+
foreach (ComSetting setting in card.Settings)
2588+
{
2589+
settings.Add(setting);
2590+
editors.Add(new LabelledEditor(setting.Label, card.Title, setting.Path));
2591+
}
2592+
}
25892593
}
25902594

25912595
IReadOnlyList<string> names = AccessibleNames.Resolve(editors);
@@ -3183,9 +3187,7 @@ private void Save_Click(object sender, RoutedEventArgs e)
31833187

31843188
bool iniWritten = false;
31853189

3186-
foreach (TabDef tab in tabs_)
3187-
foreach (CardDef card in tab.Cards)
3188-
foreach (ComSetting setting in card.Settings)
3190+
foreach (ComSetting setting in tabs_.SelectMany(tab => tab.Cards).SelectMany(card => card.Settings))
31893191
{
31903192
try
31913193
{

hmailserver/source/Tools/ControlPanel/Views/SslCertificatesView.xaml.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4+
using System.Linq;
45
using System.Threading.Tasks;
56
using System.Windows;
67
using System.Windows.Controls;
@@ -138,14 +139,9 @@ await Task.Run(() =>
138139

139140
if (reselectId != 0)
140141
{
141-
foreach (CertRow row in rows)
142-
{
143-
if (row.Id == reselectId)
144-
{
145-
CertGrid.SelectedItem = row;
146-
break;
147-
}
148-
}
142+
CertRow reselect = rows.FirstOrDefault(row => row.Id == reselectId);
143+
if (reselect != null)
144+
CertGrid.SelectedItem = reselect;
149145
}
150146

151147
UpdateDetailsPane();
@@ -271,10 +267,8 @@ private static CertificateFinding PassphraseFinding(StoredPassphrase state, bool
271267
private static CertificateFinding WorstOf(params CertificateFinding[] findings)
272268
{
273269
CertificateFinding worst = null;
274-
foreach (CertificateFinding finding in findings)
270+
foreach (CertificateFinding finding in findings.Where(f => f != null))
275271
{
276-
if (finding == null)
277-
continue;
278272
if (worst == null || finding.Level > worst.Level)
279273
worst = finding;
280274
}

hmailserver/source/Tools/ControlPanel/Views/TlsOverviewView.cs

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using System.Windows;
45
using System.Windows.Controls;
56
using System.Windows.Documents;
@@ -135,7 +136,7 @@ private TlsPostureConfig ReadConfig()
135136
// The certificate files live beside the server. Read remotely, the file
136137
// checks are meaningless - and quietly reporting "missing" for a file
137138
// that is simply on another machine would be the worst possible answer.
138-
string host = Read(() => (string) ServerSession.Current.Host) ?? "";
139+
string host = Read(() => ServerSession.Current.Host) ?? "";
139140
config.CertificateFilesReadable = string.IsNullOrEmpty(host) || CertificateInspector.SessionIsLocal(host);
140141

141142
// Certificates first: the listener pass resolves each port's certificate
@@ -222,13 +223,10 @@ private void ReadCertificates(TlsPostureConfig config, dynamic settings)
222223

223224
private static string FirstProblem(CertificateHealth health)
224225
{
225-
foreach (CertificateFinding finding in new[] { health.CertificateFile, health.PrivateKeyFile, health.Pair })
226-
{
227-
if (finding != null && finding.Level == StatusLevel.Critical)
228-
return finding.Detail;
229-
}
226+
CertificateFinding critical = new[] { health.CertificateFile, health.PrivateKeyFile, health.Pair }
227+
.FirstOrDefault(finding => finding != null && finding.Level == StatusLevel.Critical);
230228

231-
return null;
229+
return critical?.Detail;
232230
}
233231

234232
private void ReadListeners(TlsPostureConfig config, dynamic settings)
@@ -313,25 +311,15 @@ private static string CertificateNameFor(TlsPostureConfig config, int certificat
313311
if (certificateId <= 0)
314312
return "";
315313

316-
foreach (TlsCertificate certificate in config.Certificates)
317-
{
318-
if (certificate.Id == certificateId)
319-
return certificate.Name;
320-
}
321-
322-
return "";
314+
TlsCertificate match = config.Certificates.FirstOrDefault(c => c.Id == certificateId);
315+
return match == null ? "" : match.Name;
323316
}
324317

325318
private static void MarkInUse(TlsPostureConfig config, int certificateId)
326319
{
327-
foreach (TlsCertificate certificate in config.Certificates)
328-
{
329-
if (certificate.Id == certificateId)
330-
{
331-
certificate.InUse = true;
332-
return;
333-
}
334-
}
320+
TlsCertificate match = config.Certificates.FirstOrDefault(c => c.Id == certificateId);
321+
if (match != null)
322+
match.InUse = true;
335323
}
336324

337325
private void ReadSecurityRanges(TlsPostureConfig config, dynamic settings)

0 commit comments

Comments
 (0)