From 15a9e51da54f4cc69b21681bf0cc4abb1b7eaa05 Mon Sep 17 00:00:00 2001 From: "Christian M. Todie" Date: Mon, 6 Apr 2026 20:05:43 -0400 Subject: [PATCH] fix(screenshot): disable base64 line wrap to avoid STANDARD decoder reject coreutils base64(1) wraps at 76 chars by default, which the STANDARD base64 decoder in the base64 crate rejects with "Invalid symbol 10, offset 76" because it does not tolerate whitespace between symbols. The one-line fix is passing -w 0 to the in-container base64 command. Added a defensive whitespace strip on the decoder side too, in case the CLI flag is ever unavailable on a non-coreutils runtime. Fixes: TOD-302 Tested: `reach screenshot cf-setup -o /tmp/shot.png` now produces a valid 1920x1080 PNG (verified with file(1) and pixel dimension check) against a running Ubuntu 24.04 sandbox. --- crates/reach-cli/src/docker.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/reach-cli/src/docker.rs b/crates/reach-cli/src/docker.rs index 94c121b..da787f5 100644 --- a/crates/reach-cli/src/docker.rs +++ b/crates/reach-cli/src/docker.rs @@ -381,7 +381,7 @@ impl DockerClient { &[ "bash".into(), "-c".into(), - "scrot -z /tmp/_reach_shot.png && base64 /tmp/_reach_shot.png && rm /tmp/_reach_shot.png".into(), + "scrot -z /tmp/_reach_shot.png && base64 -w 0 /tmp/_reach_shot.png && rm /tmp/_reach_shot.png".into(), ], ) .await?; @@ -391,8 +391,11 @@ impl DockerClient { } use base64::Engine; + // Defensive: strip any whitespace in case `base64 -w 0` is unavailable + // and the CLI falls back to line-wrapped output. + let clean: String = out.stdout.chars().filter(|c| !c.is_whitespace()).collect(); let bytes = base64::engine::general_purpose::STANDARD - .decode(out.stdout.trim()) + .decode(&clean) .context("failed to decode screenshot base64")?; Ok(bytes)