Skip to content

fix(execd): encode filename* with RFC 8187 attr-chars only - #2516

Open
acodercat wants to merge 1 commit into
opensandbox-group:mainfrom
acodercat:fix/execd-content-disposition-rfc8187
Open

acodercat wants to merge 1 commit into
opensandbox-group:mainfrom
acodercat:fix/execd-content-disposition-rfc8187

Conversation

@acodercat

Copy link
Copy Markdown
Contributor

For file names that need encoding (non-ASCII, " or \), formatContentDisposition builds filename*=UTF-8'' + url.PathEscape(name). The same helper serves both /files/download and the isolated session download.

url.PathEscape encodes for a URL path segment, so it keeps characters such as =, :, @, &, +, $ and '. RFC 8187's ext-value only allows attr-char unencoded. ' in particular is the delimiter between the charset and language fields. For a file named ü=1.txt, execd sends

attachment; filename="%C3%BC=1.txt"; filename*=UTF-8''%C3%BC=1.txt

and Go's mime.ParseMediaType rejects it with mime: invalid media parameter. Strict clients fail to read the name the same way.

Summary

  • Add encodeExtValue, which percent-encodes every byte outside the RFC 8187 attr-char set, and use it instead of url.PathEscape.
  • The output format is unchanged: the quoted filename fallback and filename* still carry the same encoded value. Names that only needed %XX for non-ASCII bytes, and spaces, encode exactly as before, so the existing expected values all still hold.

Testing

  • Not run (explain why)

  • Unit tests

  • Integration tests

  • e2e / manual verification

  • New TestFormatContentDispositionRoundTrips checks that mime.ParseMediaType parses the header and returns the original name for ü=1.txt, 报告:v1@2.txt, 测试 文件.txt, a"b.txt and a'b(1).txt. On current main the first two fail to parse.

  • The existing TestFormatContentDisposition table passes unchanged.

  • All execd packages pass (GOOS=linux), golangci-lint is clean, and darwin and windows builds succeed.

Breaking Changes

  • None
  • Yes (describe impact and migration path)

Checklist

  • Linked Issue or clearly described motivation
  • Added/updated docs (if needed)
  • Added/updated tests (if needed)
  • Security impact considered
  • Backward compatibility considered

formatContentDisposition built filename* with url.PathEscape, which
leaves characters such as '=', ':', '@' and the "'" delimiter unencoded.
An ext-value may only contain attr-chars, so for a name like "ü=1.txt"
the header was invalid and mime.ParseMediaType rejected it. Percent-encode
every byte outside the attr-char set instead.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-31T04:54:41.997864Z c5f78d5 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added component/execd size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Oct 31, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/execd size/S Denotes a PR that changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant