mirror of
https://github.com/outline/outline.git
synced 2026-08-03 13:27:25 +03:00
fix: Decode percent-encoded filenames from URLs (#12906)
getFileNameFromUrl returned the raw URL path segment, so attachments created from a URL were stored with encoded names (e.g. "My%20File.pdf"). Decode the filename, falling back to the raw value on malformed encoding. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d3c085462d
commit
236eabdcc8
@@ -82,4 +82,22 @@ describe("getFileNameFromUrl", () => {
|
||||
).toBe("file.txt");
|
||||
expect(getFileNameFromUrl("https://example.com/")).toBe("");
|
||||
});
|
||||
|
||||
it("decodes percent-encoded filenames", () => {
|
||||
expect(getFileNameFromUrl("https://example.com/My%20Report.pdf")).toBe(
|
||||
"My Report.pdf"
|
||||
);
|
||||
expect(getFileNameFromUrl("https://example.com/caf%C3%A9%20menu.png")).toBe(
|
||||
"café menu.png"
|
||||
);
|
||||
expect(
|
||||
getFileNameFromUrl("https://example.com/report%20final.pdf?v=2#top")
|
||||
).toBe("report final.pdf");
|
||||
});
|
||||
|
||||
it("falls back to the raw filename on malformed encoding", () => {
|
||||
expect(getFileNameFromUrl("https://example.com/bad%name.txt")).toBe(
|
||||
"bad%name.txt"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -157,7 +157,14 @@ export function getFileNameFromUrl(url: string) {
|
||||
const urlObj = new URL(url);
|
||||
const pathname = urlObj.pathname;
|
||||
const filename = pathname.substring(pathname.lastIndexOf("/") + 1);
|
||||
return filename;
|
||||
|
||||
try {
|
||||
// Decode percent-encoding so the name is human readable (e.g. "My%20File.pdf" → "My File.pdf").
|
||||
return decodeURIComponent(filename);
|
||||
} catch (_err) {
|
||||
// Malformed percent-encoding, fall back to the raw filename.
|
||||
return filename;
|
||||
}
|
||||
} catch (_err) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user