Skip to content

[Repo Assist] fix(canvas): skip GetFinalPathFromHandle containment check on non-Windows#264

Merged
shanselman merged 1 commit intomasterfrom
repo-assist/fix-canvas-jsonl-linux-2026-05-03-899c253f0d54645f
May 5, 2026
Merged

[Repo Assist] fix(canvas): skip GetFinalPathFromHandle containment check on non-Windows#264
shanselman merged 1 commit intomasterfrom
repo-assist/fix-canvas-jsonl-linux-2026-05-03-899c253f0d54645f

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented May 3, 2026

🤖 This is an automated pull request from Repo Assist.

Summary

Fixes two pre-existing test failures that occurred on every non-Windows CI run:

  • CanvasCapabilityTests.A2UIPush_WithJsonlPath_ReadsFile
  • A2UICapabilitySecurityTests.A2UIPush_FileJsonl_OverCap_ReturnsError

Root cause

GetFinalPathFromHandle calls the Win32 GetFinalPathNameByHandle API and already guards non-Windows correctly by returning string.Empty (line 440–441):

if (!OperatingSystem.IsWindows())
    return string.Empty;

However the call site unconditionally passed that empty string into IsPathWithinRoot, which resolves it via Path.GetFullPath("") — producing the current working directory — then checked whether CWD falls inside tempRoot. On Linux CI (CWD = /home/runner/work/...), this always evaluated to false, throwing "jsonlPath must resolve within the system temp directory" before any content was read.

Fix

One-line guard: only perform the handle-resolved-path containment check when GetFinalPathFromHandle returns a non-empty string.

// Before
if (!IsPathWithinRoot(finalPath, tempRoot))

// After
if (!string.IsNullOrEmpty(finalPath) && !IsPathWithinRoot(finalPath, tempRoot))

On non-Windows the earlier symlink-resolution check (lines 379–404, using cross-platform FileInfo.ResolveLinkTarget) already provides the equivalent security guarantee.

Security impact

None. The Windows handle-path guard defends against a race where a symlink is swapped between the FileInfo check and the FileStream open. On Linux:

  • The FileInfo.ResolveLinkTarget check (lines 379–404) detects symlinks pointing outside temp before the file is opened.
  • The OS does not have the same NTFS reparse-point attack surface.

Test Status

Suite Before After
OpenClaw.Shared.Tests ❌ 1150 passed / 2 failed / 20 skipped 1152 passed / 0 failed / 20 skipped
OpenClaw.Tray.Tests 406 passed / 1 pre-existing DPAPI failure (Linux-only, unrelated) 406 passed / 1 pre-existing DPAPI failure (unrelated, unchanged)

./build.ps1 was not run (Linux environment); the fix is a one-line guard in a net10.0 cross-platform library with no platform-specific build requirements.

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@97143ac59cb3a13ef2a77581f929f06719c7402a

…dows

GetFinalPathFromHandle calls the Win32 GetFinalPathNameByHandle API, which
is not available on non-Windows platforms. The method already guards this
correctly by returning string.Empty when not on Windows (line 440-441).

However the call site unconditionally passed that empty string into
IsPathWithinRoot, which resolves it via Path.GetFullPath("") — producing
the current working directory — then checked whether CWD falls inside the
temp root. On Linux CI runners (CWD = /home/runner/work/...) this always
fails, throwing "jsonlPath must resolve within the system temp directory"
before any content is read, causing two tests to fail on every non-Windows
run:

  - CanvasCapabilityTests.A2UIPush_WithJsonlPath_ReadsFile
  - A2UICapabilitySecurityTests.A2UIPush_FileJsonl_OverCap_ReturnsError

Fix: only perform the handle-resolved-path containment check when
GetFinalPathFromHandle returns a non-empty string. On non-Windows the
earlier symlink-resolution check (lines 379-404) already provides the
equivalent security guarantee using cross-platform .NET APIs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added automation bug Something isn't working repo-assist labels May 3, 2026
@shanselman shanselman marked this pull request as ready for review May 5, 2026 17:18
@shanselman shanselman merged commit a1ef5e6 into master May 5, 2026
3 checks passed
@shanselman shanselman deleted the repo-assist/fix-canvas-jsonl-linux-2026-05-03-899c253f0d54645f branch May 5, 2026 17:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automation bug Something isn't working repo-assist

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant