diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 196e7a8..af16057 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,6 +11,13 @@ on: branches: [main] workflow_dispatch: +# Minimum permissions for a build-only workflow: read the repo, nothing +# else. Closes the CodeQL "Workflow does not contain permissions" alert +# and matches the principle-of-least-privilege the security guide +# recommends for workflows that don't push or create releases. +permissions: + contents: read + jobs: build: name: Build (Release) diff --git a/ChatTwo/Util/ImGuiUtil.cs b/ChatTwo/Util/ImGuiUtil.cs index 7379001..97deb15 100755 --- a/ChatTwo/Util/ImGuiUtil.cs +++ b/ChatTwo/Util/ImGuiUtil.cs @@ -94,18 +94,24 @@ internal static class ImGuiUtil foreach (var part in csText.Split(["\r\n", "\r", "\n"], StringSplitOptions.None)) { var bytes = Encoding.UTF8.GetBytes(part); + + // Empty splits (consecutive newlines) leave bytes.Length at 0 + // and the textEnd pointer below would coincide with text. The + // ImGuiNative word-wrap calls treat that as undefined input, + // and the CodeQL "unvalidated local pointer arithmetic" alert + // also flags it. Render an empty line and skip the unsafe + // block entirely for this iteration. + if (bytes.Length == 0) + { + ImGui.TextUnformatted(""); + continue; + } + fixed (byte* rawText = bytes) { var text = rawText; var textEnd = text + bytes.Length; - // empty string - if (text == null) - { - ImGui.TextUnformatted(""); - continue; - } - var widthLeft = ImGui.GetContentRegionAvail().X; var endPrevLine = ImGuiNative.CalcWordWrapPositionA(ImGui.GetFont().Handle, ImGuiHelpers.GlobalScale, text, textEnd, widthLeft); if (endPrevLine == null)