From 3ad290808245d94650a8f68402a85ff60ef1d616 Mon Sep 17 00:00:00 2001 From: Erik Darling <2136037+erikdarlingdata@users.noreply.github.com> Date: Fri, 3 Apr 2026 22:35:44 -0400 Subject: [PATCH] Fix CLI installer argument parsing treating flags as positional args Flags like --encrypt optional (space-separated) were not fully stripped from positional arguments, causing the installer to misinterpret them as a username and fall into the SQL Auth path unexpectedly. Replace individual flag filters with a single loop that strips all -- prefixed flags and consumes trailing values for --entra and --encrypt. Also support --encrypt (space) in addition to --encrypt=. Fixes #786 Co-Authored-By: Claude Opus 4.6 (1M context) --- Installer/Program.cs | 52 +++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/Installer/Program.cs b/Installer/Program.cs index 9c7cb652..bbb487a5 100644 --- a/Installer/Program.cs +++ b/Installer/Program.cs @@ -100,12 +100,13 @@ static async Task Main(string[] args) } } - /*Parse encryption option (default: Mandatory)*/ - var encryptArg = args.FirstOrDefault(a => a.StartsWith("--encrypt=", StringComparison.OrdinalIgnoreCase)); + /*Parse encryption option (default: Mandatory) + Supports both --encrypt=optional and --encrypt optional */ string encryptionLevel = "Mandatory"; - if (encryptArg != null) + var encryptEqualsArg = args.FirstOrDefault(a => a.StartsWith("--encrypt=", StringComparison.OrdinalIgnoreCase)); + if (encryptEqualsArg != null) { - string encryptValue = encryptArg.Substring("--encrypt=".Length).ToLowerInvariant(); + string encryptValue = encryptEqualsArg.Substring("--encrypt=".Length).ToLowerInvariant(); encryptionLevel = encryptValue switch { "optional" => "Optional", @@ -113,21 +114,38 @@ static async Task Main(string[] args) _ => "Mandatory" }; } + else + { + int encryptIndex = Array.FindIndex(args, a => a.Equals("--encrypt", StringComparison.OrdinalIgnoreCase)); + if (encryptIndex >= 0 && encryptIndex + 1 < args.Length && !args[encryptIndex + 1].StartsWith("--", StringComparison.Ordinal)) + { + encryptionLevel = args[encryptIndex + 1].ToLowerInvariant() switch + { + "optional" => "Optional", + "strict" => "Strict", + _ => "Mandatory" + }; + } + } - /*Filter out option flags and --entra to get positional arguments*/ - var filteredArgsList = args - .Where(a => !a.Equals("--reinstall", StringComparison.OrdinalIgnoreCase)) - .Where(a => !a.Equals("--uninstall", StringComparison.OrdinalIgnoreCase)) - .Where(a => !a.Equals("--reset-schedule", StringComparison.OrdinalIgnoreCase)) - .Where(a => !a.Equals("--trust-cert", StringComparison.OrdinalIgnoreCase)) - .Where(a => !a.StartsWith("--encrypt=", StringComparison.OrdinalIgnoreCase)) - .Where(a => !a.Equals("--entra", StringComparison.OrdinalIgnoreCase)) - .ToList(); - - /*Remove the entra email from positional args if present*/ - if (entraEmail != null) + /*Filter out all --flags and their trailing values to get positional arguments + (server, username, password). Flags like --entra and --encrypt + have a following value that must also be removed.*/ + var filteredArgsList = new List(); + for (int i = 0; i < args.Length; i++) { - filteredArgsList.Remove(entraEmail); + if (args[i].StartsWith("--", StringComparison.Ordinal)) + { + /*Skip flags that take a trailing value (--entra , --encrypt )*/ + if ((args[i].Equals("--entra", StringComparison.OrdinalIgnoreCase) + || args[i].Equals("--encrypt", StringComparison.OrdinalIgnoreCase)) + && i + 1 < args.Length && !args[i + 1].StartsWith("--", StringComparison.Ordinal)) + { + i++; /*skip the value too*/ + } + continue; + } + filteredArgsList.Add(args[i]); } var filteredArgs = filteredArgsList.ToArray();