From 8d2aebd0518fc7c7be96db7f6b46d933881134f2 Mon Sep 17 00:00:00 2001 From: Drew Smirnoff Date: Tue, 21 Apr 2026 22:37:37 +0400 Subject: [PATCH] fix: limit filename length (#825) Co-authored-by: Daniel Purnomo --- main.go | 11 +++++++++++ main_test.go | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/main.go b/main.go index ab11e2f6bd6e04b57a986a7e6bdf45310553d8c9..9a30a30c165db1b9db79e2b46d700390d64b9e4e 100644 --- a/main.go +++ b/main.go @@ -2584,6 +2584,16 @@ func sanitizeFilename(name string) string { if name == "" || name == "." || strings.HasPrefix(name, ".") { name = "attachment" } + // Sanitize filename: enforce length limit to prevent filesystem errors + // with extremely long names from untrusted email headers. + const maxFilenameLen = 255 + if len(name) > maxFilenameLen { + ext := filepath.Ext(name) + if len(ext) > maxFilenameLen { + ext = ext[:maxFilenameLen] + } + name = name[:maxFilenameLen-len(ext)] + ext + } return name } @@ -2602,6 +2612,7 @@ func downloadAttachmentCmd(account *config.Account, uid uint32, msg tui.Download default: data, err = fetcher.FetchAttachment(account, uid, msg.PartID, msg.Encoding) } + if err != nil { return tui.AttachmentDownloadedMsg{Err: err} } diff --git a/main_test.go b/main_test.go index c98cc4bc886982d1cb0ab8799dd07b1b8f8367f7..5744c10f1631de65b85eecfc2b6b915a230cb1da 100644 --- a/main_test.go +++ b/main_test.go @@ -1,6 +1,7 @@ package main import ( + "strings" "testing" ) @@ -26,6 +27,10 @@ func TestSanitizeFilename(t *testing.T) { {"null bytes removed", "file\x00name.txt", "file\x00name.txt"}, {"unicode filename", "日本語.txt", "日本語.txt"}, {"long traversal chain", "a/b/c/../../../d/e/f.txt", "f.txt"}, + {"exact 255 chars", strings.Repeat("a", 255), strings.Repeat("a", 255)}, + {"256 chars", strings.Repeat("a", 256), strings.Repeat("a", 255)}, + {"long with extension", strings.Repeat("b", 260) + ".txt", strings.Repeat("b", 251) + ".txt"}, + {"long extension only", "a." + strings.Repeat("c", 260), "." + strings.Repeat("c", 254)}, } for _, tt := range tests {