Skip to content

Fix several small bugs that an AI agent detected#2303

Open
mjcheetham wants to merge 16 commits intogit-ecosystem:mainfrom
mjcheetham:bug-fixes
Open

Fix several small bugs that an AI agent detected#2303
mjcheetham wants to merge 16 commits intogit-ecosystem:mainfrom
mjcheetham:bug-fixes

Conversation

@mjcheetham
Copy link
Copy Markdown
Contributor

A collection of small bug fixes found with the help of an AI agent scanning the codebase. None of these are known to be actively exploited or causing user-reported issues, but each is a latent defect that could cause crashes, hangs, or incorrect behaviour under the right conditions.

Fixes

Credential UIgithub/gitlab: use correct param order

  • Custom credential UI commands had swapped URL and username arguments.

Stream extensionsstreamextensions: fix a bug in multi-var reset handling

  • Multi-dictionary writer emitted the wrong value when a reset marker was followed by a single entry.

GitHub authgithub: handle empty domain or enterprise hints

  • Null-reference exception when WWW-Authenticate header is missing domain/enterprise hints.

GitHub account filteringgithub: do not filter accounts outside of dotcom

  • Account filtering was applied outside of GitHub.com despite detecting it shouldn't be.

Network diagnosticsdiagnose: fix network diag to await HTTP requests

  • HTTP requests in the network diagnostic were not properly awaited.

macOS notarize scriptmacos: add die function to notarize.sh script

  • Missing die function.

Git stderr handlinggit: drain stderr on IsInsideRepository

  • Potential hang when Git writes enough to stderr to fill the pipe buffer.

Windows layout scriptwindows: fix layout.ps1 if symboloutput is not set

  • Null-reference trimming SymbolOutput when the variable is unset.

OAuth device code UIoauth: pass cancellation token to in-proc device code UI

  • Cancellation token was not forwarded, so dismissing the dialog didn't work.

TRACE2 thread IDtrace2: fix main thread identification

  • Main thread ID starts at 1, not 0.

TRACE2 perf formattrace2: fix crash in perf format for large elapsed times

  • ArgumentOutOfRangeException crash when elapsed time exceeds 9999 seconds.

HTTP confighttp: use correct http.sslAutoClientCert setting name

  • Setting was read from the wrong Git config section.

TRACE2 writer cleanuptrace2: fix incomplete disposal of writers on cleanup

  • Forward iteration with removal skipped every other writer, leaking file handles.

Git stderr redirectgit: fix crash when reading stderr from non-redirected processes

  • InvalidOperationException when GetRemotes/CreateGitException read non-redirected stderr.

Executable lookupenvironment: check execute permission in TryLocateExecutable

  • PATH scan didn't verify execute bits on POSIX, unlike the which it replaced.

Installer Exec commandwindows: fix en-dash characters in installer Exec command

  • Unicode en-dash characters instead of ASCII hyphens broke PowerShell 5.1 parameter parsing.

When using a custom credential UI for either GitHub or GitLab the
commands are mixing up the optional URL and user name args. This is
because the positional args of the `ExecuteAsync` methods was not the
same as the `SetHandler`.

Swap the args to fix this.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
The multi-dictionary writer normalises value lists to honor reset
semantics (empty values clear prior entries). However, when only
one normalised value remains, it writes the first element from
the original list instead of the normalised list.

If the list contains an empty reset marker followed by a single
valid value, the output will incorrectly emit the pre-reset value
(or an empty string), violating the protocol and potentially
leaking stale data that should have been cleared.

Fix the issue and extend the unit tests to cover this shape.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
If the WWW-Authenticate header from GitHub is missing a domain or
enterprise hint we'd be hitting a null-reference exception when
calculating a hash code for the `GitHubAuthChallenge`. Fix this.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
Outside of GitHub.com we should not filter accounts. The
`FilterAccounts` method was detecting and logging this, but didn't
actually stop filtering!

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
The network diagnostic failed to correctly await the test HTTP requests,
and also did not return and await a `Task` (to capture exceptions).

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
Add the missing die function.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
When suppressStreams is true, Git's stderr is redirected to a pipe but
then we only read stdout before waiting for exit. If Ggit writes lots
to stderr (for example when tracing is enabled), the stderr pipe can
fill, causing the Git process to block and GCM to hang while checking
repository state.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
If SymbolOutput is not set then there's a bug whereby we try and trim
the end '/' and '\' characters on a null value. Guard against this.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
In the OAuth device-code flow, the in-proc UI path the calling logic
creates a `CancellationTokenSource` and later calls `Cancel()` on that
CTS to close the dialog once the token is obtained (or the user
cancels).

However, `ShowDeviceCodeViaUiAsync` disregards the provided cancellation
token and passes `CancellationToken.None` into `AvaloniaUi.ShowViewAsync`.

Pass the cancellation token correctly.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
The `Thread::ManagedTheadId` always starts with the entry thread as `1`
and not `0`.

https://github.com/dotnet/runtime/blob/790e8a525a0f76b8ad755c12e95b7f8770195d67/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ManagedThreadId.cs#L181

Fix this in Trace2.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
BuildTimeSpan assumes an 11-character span and adjusts padding when the
formatted elapsed time overflows. For values with 5+ digits before the
decimal (>= 10000 seconds), the size difference exceeds the available
padding budget, driving BeginPadding below zero. This causes
`new string(' ', BeginPadding)` to throw an ArgumentOutOfRangeException.

Since Trace2FileWriter does not catch exceptions, this crashes the
credential helper when TRACE2 performance output is enabled.

Fix the overflow check from `==` to `>=` so that values exceeding the
full span (data + padding) zero out all padding rather than producing a
negative value.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
We had been incorrectly looking for the `sslAutoClientCert` Git config
option under the `credential` section, rather than `http`.

Note: this is a Git for Windows only option.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
ReleaseManagedResources iterates forward by index while removing
elements from the same list. Each removal shifts remaining elements
left, but the loop increments i, causing the next element to be
skipped. As a result, only about half of the writers are disposed and
removed, leaving file handles or buffers open.

Fix by iterating in reverse so that removals do not shift any unvisited
indices, and use RemoveAt(i) to avoid a redundant linear search.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
ProcessManager.CreateProcess sets RedirectStandardError=false for all
processes to avoid TRACE2 deadlocks. However, GetRemotes and
CreateGitException unconditionally read StandardError, which throws
InvalidOperationException when stderr is not redirected.

Fix GetRemotes by explicitly redirecting stderr before starting the
process, since it needs to check for 'not a git repository' errors.
Guard CreateGitException defensively, as it is called from various
contexts where stderr may or may not be redirected.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
@mjcheetham mjcheetham requested a review from a team March 31, 2026 13:09
@mjcheetham mjcheetham requested review from a team as code owners March 31, 2026 13:09
In f1a1ae5 (environment: manually scan $PATH on POSIX systems,
2022-05-31) the `which`-based lookup was replaced with a manual PATH
scan that only checks FileExists, without verifying execute permissions.
Unlike `which`, this means a non-executable file earlier in PATH can
shadow a valid executable, causing process creation to fail when GCM
later tries to run the located path.

Add an IsExecutable check that verifies at least one execute bit is set
on POSIX systems, matching the behaviour of `which`. On Windows, any
existing file is considered executable. Guard the POSIX-specific
File.GetUnixFileMode call with #if !NETFRAMEWORK for net472
compatibility.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
The powershell.exe invocation in the Installer.Windows.csproj Exec
task uses Unicode en dash characters (U+2013) instead of ASCII hyphens
for the -NonInteractive and -ExecutionPolicy parameters. Windows
PowerShell 5.1 does not recognise en dashes as parameter prefixes, so
these flags are not applied correctly, which can cause the layout step
to fail or run with an unexpected execution policy.

Replace the en dash characters with ASCII hyphens.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
@mufasacubana8-pixel

This comment was marked as spam.

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