Add filename sanitization tests for attachments

Introduced tests to validate filename sanitization for attachments, ensuring disallowed characters are handled correctly. These tests cover various scenarios, including different character sets such as Japanese, Chinese, and Cyrillic.
This commit is contained in:
Winni Neessen 2024-11-26 16:17:34 +01:00
parent b051471f8d
commit fe765cd49e
Signed by: wneessen
GPG key ID: 385AC9889632126E

View file

@ -10,6 +10,7 @@ import (
"fmt"
"io"
"mime"
"os"
"runtime"
"strings"
"testing"
@ -304,6 +305,81 @@ func TestMsgWriter_addFiles(t *testing.T) {
charset: CharsetUTF8,
encoder: getEncoder(EncodingQP),
}
tests := []struct {
name string
filename string
expect string
}{
{"normal US-ASCII filename", "test.txt", "test.txt"},
{"normal US-ASCII filename with space", "test file.txt", "test file.txt"},
{"filename with new lines", "test\r\n.txt", "test__.txt"},
{"filename with disallowed character:\x22", "test\x22.txt", "test_.txt"},
{"filename with disallowed character:\x2f", "test\x2f.txt", "test_.txt"},
{"filename with disallowed character:\x3a", "test\x3a.txt", "test_.txt"},
{"filename with disallowed character:\x3c", "test\x3c.txt", "test_.txt"},
{"filename with disallowed character:\x3e", "test\x3e.txt", "test_.txt"},
{"filename with disallowed character:\x3f", "test\x3f.txt", "test_.txt"},
{"filename with disallowed character:\x5c", "test\x5c.txt", "test_.txt"},
{"filename with disallowed character:\x7c", "test\x7c.txt", "test_.txt"},
{"filename with disallowed character:\x7f", "test\x7f.txt", "test_.txt"},
{
"japanese characters filename", "添付ファイル.txt",
"=?UTF-8?q?=E6=B7=BB=E4=BB=98=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB.txt?=",
},
{
"simplified chinese characters filename", "测试附件文件.txt",
"=?UTF-8?q?=E6=B5=8B=E8=AF=95=E9=99=84=E4=BB=B6=E6=96=87=E4=BB=B6.txt?=",
},
{
"cyrillic characters filename", "Тестовый прикрепленный файл.txt",
"=?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=D0=BE=D0=B2=D1=8B=D0=B9_=D0=BF=D1=80?= " +
"=?UTF-8?q?=D0=B8=D0=BA=D1=80=D0=B5=D0=BF=D0=BB=D0=B5=D0=BD=D0=BD=D1=8B?= " +
"=?UTF-8?q?=D0=B9_=D1=84=D0=B0=D0=B9=D0=BB.txt?=",
},
}
for _, tt := range tests {
t.Run("addFile with filename sanitization: "+tt.name, func(t *testing.T) {
buffer := bytes.NewBuffer(nil)
msgwriter.writer = buffer
message := testMessage(t)
tmpfile, err := os.CreateTemp("", "attachment.*.tmp")
if err != nil {
t.Fatalf("failed to create tempfile: %s", err)
}
t.Cleanup(func() {
if err = os.Remove(tmpfile.Name()); err != nil {
t.Errorf("failed to remove tempfile: %s", err)
}
})
source, err := os.Open("testdata/attachment.txt")
if err != nil {
t.Fatalf("failed to open source file: %s", err)
}
if _, err = io.Copy(tmpfile, source); err != nil {
t.Fatalf("failed to copy source file: %s", err)
}
if err = tmpfile.Close(); err != nil {
t.Fatalf("failed to close tempfile: %s", err)
}
if err = source.Close(); err != nil {
t.Fatalf("failed to close source file: %s", err)
}
message.AttachFile(tmpfile.Name(), WithFileName(tt.filename))
msgwriter.writeMsg(message)
if msgwriter.err != nil {
t.Errorf("msgWriter failed to write: %s", msgwriter.err)
}
ctExpect := fmt.Sprintf(`Content-Type: text/plain; charset=utf-8; name="%s"`, tt.expect)
cdExpect := fmt.Sprintf(`Content-Disposition: attachment; filename="%s"`, tt.expect)
if !strings.Contains(buffer.String(), ctExpect) {
t.Errorf("expected content-type: %q, got: %q", ctExpect, buffer.String())
}
if !strings.Contains(buffer.String(), cdExpect) {
t.Errorf("expected content-disposition: %q, got: %q", cdExpect, buffer.String())
}
})
}
t.Run("message with a single file attached", func(t *testing.T) {
buffer := bytes.NewBuffer(nil)
msgwriter.writer = buffer