@@ -304,6 +304,65 @@ func TestMsgWriter_addFiles(t *testing.T) {
304304 charset : CharsetUTF8 ,
305305 encoder : getEncoder (EncodingQP ),
306306 }
307+ tests := []struct {
308+ name string
309+ filename string
310+ expect string
311+ }{
312+ {"normal US-ASCII filename" , "test.txt" , "test.txt" },
313+ {"normal US-ASCII filename with space" , "test file.txt" , "test file.txt" },
314+ {"filename with new lines" , "test\r \n .txt" , "test__.txt" },
315+ {"filename with disallowed character:\x22 " , "test\x22 .txt" , "test_.txt" },
316+ {"filename with disallowed character:\x2f " , "test\x2f .txt" , "test_.txt" },
317+ {"filename with disallowed character:\x3a " , "test\x3a .txt" , "test_.txt" },
318+ {"filename with disallowed character:\x3c " , "test\x3c .txt" , "test_.txt" },
319+ {"filename with disallowed character:\x3e " , "test\x3e .txt" , "test_.txt" },
320+ {"filename with disallowed character:\x3f " , "test\x3f .txt" , "test_.txt" },
321+ {"filename with disallowed character:\x5c " , "test\x5c .txt" , "test_.txt" },
322+ {"filename with disallowed character:\x7c " , "test\x7c .txt" , "test_.txt" },
323+ {"filename with disallowed character:\x7f " , "test\x7f .txt" , "test_.txt" },
324+ {
325+ "japanese characters filename" , "添付ファイル.txt" ,
326+ "=?UTF-8?q?=E6=B7=BB=E4=BB=98=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB.txt?=" ,
327+ },
328+ {
329+ "simplified chinese characters filename" , "测试附件文件.txt" ,
330+ "=?UTF-8?q?=E6=B5=8B=E8=AF=95=E9=99=84=E4=BB=B6=E6=96=87=E4=BB=B6.txt?=" ,
331+ },
332+ {
333+ "cyrillic characters filename" , "Тестовый прикрепленный файл.txt" ,
334+ "=?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=D0=BE=D0=B2=D1=8B=D0=B9_=D0=BF=D1=80?= " +
335+ "=?UTF-8?q?=D0=B8=D0=BA=D1=80=D0=B5=D0=BF=D0=BB=D0=B5=D0=BD=D0=BD=D1=8B?= " +
336+ "=?UTF-8?q?=D0=B9_=D1=84=D0=B0=D0=B9=D0=BB.txt?=" ,
337+ },
338+ }
339+ for _ , tt := range tests {
340+ t .Run ("addFile with filename sanitization: " + tt .name , func (t * testing.T ) {
341+ buffer := bytes .NewBuffer (nil )
342+ msgwriter .writer = buffer
343+ message := testMessage (t )
344+ message .AttachFile ("testdata/attachment.txt" , WithFileName (tt .filename ))
345+ msgwriter .writeMsg (message )
346+ if msgwriter .err != nil {
347+ t .Errorf ("msgWriter failed to write: %s" , msgwriter .err )
348+ }
349+
350+ var ctExpect string
351+ cdExpect := fmt .Sprintf (`Content-Disposition: attachment; filename="%s"` , tt .expect )
352+ switch runtime .GOOS {
353+ case "freebsd" :
354+ ctExpect = fmt .Sprintf (`Content-Type: application/octet-stream; name="%s"` , tt .expect )
355+ default :
356+ ctExpect = fmt .Sprintf (`Content-Type: text/plain; charset=utf-8; name="%s"` , tt .expect )
357+ }
358+ if ! strings .Contains (buffer .String (), ctExpect ) {
359+ t .Errorf ("expected content-type: %q, got: %q" , ctExpect , buffer .String ())
360+ }
361+ if ! strings .Contains (buffer .String (), cdExpect ) {
362+ t .Errorf ("expected content-disposition: %q, got: %q" , cdExpect , buffer .String ())
363+ }
364+ })
365+ }
307366 t .Run ("message with a single file attached" , func (t * testing.T ) {
308367 buffer := bytes .NewBuffer (nil )
309368 msgwriter .writer = buffer
@@ -676,3 +735,33 @@ func TestMsgWriter_writeBody(t *testing.T) {
676735 }
677736 })
678737}
738+
739+ func TestMsgWriter_sanitizeFilename (t * testing.T ) {
740+ tests := []struct {
741+ given string
742+ want string
743+ }{
744+ {"test.txt" , "test.txt" },
745+ {"test file.txt" , "test file.txt" },
746+ {"test\\ file.txt" , "test_ file.txt" },
747+ {`"test" file.txt` , "_test_ file.txt" },
748+ {`test file .txt` , "test_file_.txt" },
749+ {"test\r \n file.txt" , "test__file.txt" },
750+ {"test\x22 file.txt" , "test_file.txt" },
751+ {"test\x2f file.txt" , "test_file.txt" },
752+ {"test\x3a file.txt" , "test_file.txt" },
753+ {"test\x3c file.txt" , "test_file.txt" },
754+ {"test\x3e file.txt" , "test_file.txt" },
755+ {"test\x3f file.txt" , "test_file.txt" },
756+ {"test\x5c file.txt" , "test_file.txt" },
757+ {"test\x7c file.txt" , "test_file.txt" },
758+ {"test\x7f file.txt" , "test_file.txt" },
759+ }
760+ for _ , tt := range tests {
761+ t .Run (tt .given + "=>" + tt .want , func (t * testing.T ) {
762+ if got := sanitizeFilename (tt .given ); got != tt .want {
763+ t .Errorf ("sanitizeFilename failed, expected: %q, got: %q" , tt .want , got )
764+ }
765+ })
766+ }
767+ }
0 commit comments