Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 21 additions & 17 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,36 @@ jobs:
- name: Checkout
uses: actions/checkout@v7

- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: |
8.0.x
10.0.x

- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: csharp
# build-mode: none analyses the C# source directly, without a build.
# It is load-bearing, not a convenience, for two reasons:
#
# 1. paths-ignore (below) only takes effect in this mode. When CodeQL
# builds a compiled language, GitHub applies no path filter — every
# file the compiler sees is analysed, obj/ included — so under the
# explicit build this workflow used to run, paths-ignore was
# silently inert and the xUnit auto-generated entry point in obj/
# was analysed and flagged in every repo. Buildless extraction
# honours the filter, so the exclusion the standard mandates
# actually happens.
#
# 2. It reads the source across every target framework at once. These
# repos multi-target, and autobuild has picked a single TFM in the
# past, silently analysing half the code; the explicit build existed
# to guard against that. Buildless extraction reads the source
# itself, not one TFM's build output, so it covers all of it with no
# build step to get wrong.
build-mode: none
# security-and-quality is broader than the default security-extended;
# these are small libraries, so the extra findings are affordable.
queries: security-and-quality
# Analyse source only. obj/ and bin/ hold generated and compiled
# output — e.g. the xUnit auto-generated entry point — so findings
# there are noise against code no human maintains.
# there are noise against code no human maintains. Effective only
# under build-mode: none (above).
#
# query-filters excludes the two audit queries that fire on every
# P/Invoke declaration and call site (cs/unmanaged-code,
Expand All @@ -68,15 +81,6 @@ jobs:
- exclude:
id: cs/call-to-unmanaged-code

# Explicit build rather than autobuild: these repos multi-target, and
# autobuild has picked a single TFM in the past, silently analysing half
# the code. Restore is separate so a restore failure is legible.
- name: Restore
run: dotnet restore

- name: Build
run: dotnet build --configuration Release --no-restore

- name: Perform CodeQL analysis
uses: github/codeql-action/analyze@v4
with:
Expand Down
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- **Two CodeQL `security-and-quality` findings resolved with genuine changes.**
`SplashColors.ValidateHex` no longer hand-rolls the hex-digit range test
(`cs/complex-condition`): the three chained comparisons are replaced by the canonical
`char.IsAsciiHexDigit`, which is available on both shipped target frameworks and reads
as the intent. The two `TestConsole` instances in `SplashScreenTests` are now disposed
via `using` (`cs/local-not-disposed`); `TestConsole` is `IDisposable` and both were
leaking. No behaviour, public API or rendered output changed.

### Changed

- **CodeQL now analyses with `build-mode: none`, per the updated `codeql.yml` template
(§4.4).** The workflow previously ran an explicit `dotnet build` before analysis, under
which GitHub applies no path filter to a compiled language — so the `paths-ignore:
**/obj/**` this repo already carried was silently inert, and CodeQL flagged the xUnit
auto-generated entry point in `obj/` (two `cs/missed-ternary-operator` alerts against
code no human maintains). Buildless extraction honours `paths-ignore`, so that
exclusion now actually takes effect, and it reads the source across every target
framework at once rather than one TFM's build output. The file is the Standards
template verbatim; the Setup .NET / Restore / Build steps are gone.

---

## [1.0.0] — 2026-08-21
Expand Down
3 changes: 1 addition & 2 deletions src/NextIteration.SpectreConsole.Splash/SplashColors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ private static void ValidateHex(string hex)
for (var i = 1; i < 7; i++)
{
var c = hex[i];
var isHex = (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
if (!isHex)
if (!char.IsAsciiHexDigit(c))
{
throw new ArgumentException(
$"Hex colour '{hex}' contains non-hex character '{c}' at position {i}.", nameof(hex));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
// Redirecting AnsiConsole.Console to a test console lets us
// confirm the single-Markup call actually produces output.
var prev = AnsiConsole.Console;
var test = new TestConsole();
using var test = new TestConsole();
AnsiConsole.Console = test;
try
{
Expand All @@ -49,7 +49,7 @@
public void Show_with_custom_tagline_emits_it()
{
var prev = AnsiConsole.Console;
var test = new TestConsole().Width(120);
using var test = new TestConsole().Width(120);
AnsiConsole.Console = test;
try
{
Expand Down