fix: handle non-ISO-8859-1 characters in fetch headers and Content-Disposition (#1673)

* fix: handle non-ISO-8859-1 characters in fetch headers and Content-Disposition

Browser Headers API rejects characters above U+00FF. The x-opencode-directory header carries raw filesystem paths, which breaks when paths contain Chinese/CJK characters. Also fixes Content-Disposition for non-ASCII filenames per RFC 5987.

* refactor: export header sanitization helpers, deduplicate, add tests

Export isLatin1Safe and sanitizeHeadersForBrowser from runtime-fetch.ts so VS Code webview can import them instead of duplicating the logic. Add tests: isLatin1Safe boundary checks, sanitizeHeadersForBrowser encoding/deduplication, runtimeFetch round-trip encode/decode, and Content-Disposition RFC 5987 output for both ASCII and non-ASCII filenames.

* fix: mark encoded directory headers

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
FanFan4204
2026-06-23 19:49:44 +03:00
committed by GitHub
co-authored by Bohdan Triapitsyn
parent 43f677d56d
commit efd621b087
7 changed files with 289 additions and 8 deletions
+7 -1
View File
@@ -883,7 +883,13 @@ export const registerFsRoutes = (app, dependencies) => {
const download = req.query.download === 'true';
if (download) {
const fileName = path.basename(canonicalPath);
res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
// RFC 5987: use filename*= for non-ASCII filenames, with ASCII-only
// filename= as fallback for older clients.
const asciiOnly = fileName.replace(/[^\u0000-\u007F]/g, '');
const fallback = asciiOnly || 'file';
// Percent-encode the raw UTF-8 bytes for filename*=
const encoded = encodeURIComponent(fileName);
res.setHeader('Content-Disposition', `attachment; filename="${fallback}"; filename*=UTF-8''${encoded}`);
}
const content = await fsPromises.readFile(canonicalPath);