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
This commit is contained in:
parent
9e06e191a3
commit
b0d92ccbd8
1 changed files with 10 additions and 4 deletions
|
|
@ -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":"<base64>"} — 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
|
||||
|
|
|
|||
Loading…
Reference in a new issue