From b0d92ccbd8aebe082c6bee88f48f30e584870e72 Mon Sep 17 00:00:00 2001 From: atlas Date: Wed, 30 Sep 2026 19:17:59 +0200 Subject: [PATCH] fix(forge): pass avatar image via files, not argv (E2BIG over 128 KiB) forge-avatar-sync passed the base64-encoded icon as a jq --arg and then as a curl -d command-line argument. Linux caps a single exec argument at MAX_ARG_STRLEN (128 KiB), so any icon whose rasterized PNG base64-encodes past that (red's does, at 133300 bytes) makes jq fail with E2BIG before curl is ever reached, and the avatar upload silently never happens. The base64 and the JSON payload now go through temp files instead of argv. Closes #4839 --- nix/agent-modules/forge.nix | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/nix/agent-modules/forge.nix b/nix/agent-modules/forge.nix index 19dc9649..775f794d 100644 --- a/nix/agent-modules/forge.nix +++ b/nix/agent-modules/forge.nix @@ -246,16 +246,22 @@ in exit 0 fi TOKEN=$(cat "$TOKEN_FILE") - IMAGE=$(base64 -w 0 < ${iconPng}) + # The base64'd icon can exceed Linux's MAX_ARG_STRLEN (128 KiB + # per exec argument), so it must never be passed on a command + # line — not to jq as --arg, not to curl as -d. Route it through + # files instead. + IMAGE_FILE=$(mktemp) + PAYLOAD_FILE=$(mktemp) + trap 'rm -f "$IMAGE_FILE" "$PAYLOAD_FILE"' EXIT + base64 -w 0 < ${iconPng} > "$IMAGE_FILE" # Forgejo POST /user/avatar expects {"image":""} — just the # raw base64 string, NOT a data URI (data:image/png;base64,...). - # Use jq to build the payload so the large base64 value is safely quoted. - PAYLOAD=$(jq -n --arg img "$IMAGE" '{image:$img}') + jq -n --rawfile img "$IMAGE_FILE" '{image:($img|rtrimstr("\n"))}' > "$PAYLOAD_FILE" RESP=$(curl -sf --max-time 10 \ -X POST "$FORGE_URL/api/v1/user/avatar" \ -H "Authorization: token $TOKEN" \ -H "Content-Type: application/json" \ - -d "$PAYLOAD" \ + --data-binary @"$PAYLOAD_FILE" \ -w "\n%{http_code}" 2>/dev/null || true) CODE=$(printf '%s' "$RESP" | tail -1) if [ "$CODE" = "204" ] || [ "$CODE" = "200" ]; then