From ffc76de937829665961ad31bed5d7b2ffadf69f8 Mon Sep 17 00:00:00 2001 From: Frank Dierolf Date: Mon, 3 Nov 2025 14:39:58 +0100 Subject: [PATCH] fix: correct clipboard image encoding and binary handling (#3816) Fixes clipboard image paste failures on Linux and Windows by addressing two critical bugs in clipboard.ts: 1. Binary Data Corruption (Linux): - Changed .text() to .arrayBuffer() for Wayland and X11 clipboard reads - Using .text() on binary PNG data corrupts it via UTF-8 decoding - Added byteLength > 0 validation 2. Encoding Mismatch (All platforms): - Changed base64url encoding to standard base64 - Data URLs require standard base64 per RFC 2397 - Affects Linux (Wayland, X11) and Windows clipboard handling These changes align Linux/Windows clipboard handling with the correct approach already used in macOS (line 25). Fixes #3816 --- .../opencode/src/cli/cmd/tui/util/clipboard.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/util/clipboard.ts b/packages/opencode/src/cli/cmd/tui/util/clipboard.ts index 7603b4c38991..aac172141a18 100644 --- a/packages/opencode/src/cli/cmd/tui/util/clipboard.ts +++ b/packages/opencode/src/cli/cmd/tui/util/clipboard.ts @@ -30,13 +30,13 @@ export namespace Clipboard { } if (os === "linux") { - const wayland = await $`wl-paste -t image/png`.nothrow().text() - if (wayland) { - return { data: Buffer.from(wayland).toString("base64url"), mime: "image/png" } + const wayland = await $`wl-paste -t image/png`.nothrow().arrayBuffer() + if (wayland && wayland.byteLength > 0) { + return { data: Buffer.from(wayland).toString("base64"), mime: "image/png" } } - const x11 = await $`xclip -selection clipboard -t image/png -o`.nothrow().text() - if (x11) { - return { data: Buffer.from(x11).toString("base64url"), mime: "image/png" } + const x11 = await $`xclip -selection clipboard -t image/png -o`.nothrow().arrayBuffer() + if (x11 && x11.byteLength > 0) { + return { data: Buffer.from(x11).toString("base64"), mime: "image/png" } } } @@ -47,7 +47,7 @@ export namespace Clipboard { if (base64) { const imageBuffer = Buffer.from(base64.trim(), "base64") if (imageBuffer.length > 0) { - return { data: imageBuffer.toString("base64url"), mime: "image/png" } + return { data: imageBuffer.toString("base64"), mime: "image/png" } } } }