@@ -128,6 +128,99 @@ func TestDecodeContent(t *testing.T) {
128128 })
129129}
130130
131+ func TestConvertToUTF8 (t * testing.T ) {
132+ t .Run ("utf-8 passthrough" , func (t * testing.T ) {
133+ input := []byte ("Привет мир" )
134+ got := convertToUTF8 (input , "utf-8" )
135+ if string (got ) != "Привет мир" {
136+ t .Errorf ("got %q" , got )
137+ }
138+ })
139+
140+ t .Run ("empty charset passthrough" , func (t * testing.T ) {
141+ input := []byte ("hello" )
142+ got := convertToUTF8 (input , "" )
143+ if string (got ) != "hello" {
144+ t .Errorf ("got %q" , got )
145+ }
146+ })
147+
148+ t .Run ("windows-1250 czech" , func (t * testing.T ) {
149+ // "týmu se vám ozve" in windows-1250
150+ win1250 := []byte {0x74 , 0xFD , 0x6D , 0x75 , 0x20 , 0x73 , 0x65 , 0x20 , 0x76 , 0xE1 , 0x6D , 0x20 , 0x6F , 0x7A , 0x76 , 0x65 }
151+ got := convertToUTF8 (win1250 , "windows-1250" )
152+ want := "týmu se vám ozve"
153+ if string (got ) != want {
154+ t .Errorf ("got %q, want %q" , got , want )
155+ }
156+ })
157+
158+ t .Run ("iso-8859-1 latin" , func (t * testing.T ) {
159+ // "café" in iso-8859-1: 0x63 0x61 0x66 0xe9
160+ latin1 := []byte {0x63 , 0x61 , 0x66 , 0xe9 }
161+ got := convertToUTF8 (latin1 , "iso-8859-1" )
162+ if string (got ) != "café" {
163+ t .Errorf ("got %q, want %q" , got , "café" )
164+ }
165+ })
166+
167+ t .Run ("unknown charset passthrough" , func (t * testing.T ) {
168+ input := []byte ("data" )
169+ got := convertToUTF8 (input , "x-nonexistent-999" )
170+ if string (got ) != "data" {
171+ t .Errorf ("got %q" , got )
172+ }
173+ })
174+ }
175+
176+ func TestParseEmail_CharsetConversion (t * testing.T ) {
177+ t .Run ("single part windows-1250" , func (t * testing.T ) {
178+ // "café" in windows-1250: 0x63 0x61 0x66 0xe9
179+ body := string ([]byte {0x63 , 0x61 , 0x66 , 0xe9 })
180+ raw := []byte ("From: sender@example.com\r \n To: recipient@example.com\r \n Subject: Test\r \n Content-Type: text/plain; charset=windows-1250\r \n \r \n " + body )
181+
182+ parsed , _ , err := parseEmail (raw , []string {"recipient@example.com" })
183+ if err != nil {
184+ t .Fatal (err )
185+ }
186+ if parsed .Text != "café" {
187+ t .Errorf ("Text = %q, want %q" , parsed .Text , "café" )
188+ }
189+ })
190+
191+ t .Run ("single part html iso-8859-2" , func (t * testing.T ) {
192+ // "Vaše zpráva" in iso-8859-2: V=56 a=61 š=B9 e=65 sp=20 z=7A p=70 r=72 á=E1 v=76 a=61
193+ body := string ([]byte {0x56 , 0x61 , 0xB9 , 0x65 , 0x20 , 0x7A , 0x70 , 0x72 , 0xE1 , 0x76 , 0x61 })
194+ raw := []byte ("From: sender@example.com\r \n To: recipient@example.com\r \n Subject: Test\r \n Content-Type: text/html; charset=iso-8859-2\r \n \r \n " + body )
195+
196+ parsed , _ , err := parseEmail (raw , []string {"recipient@example.com" })
197+ if err != nil {
198+ t .Fatal (err )
199+ }
200+ want := "Vaše zpráva"
201+ if parsed .HTML != want {
202+ t .Errorf ("HTML = %q, want %q" , parsed .HTML , want )
203+ }
204+ })
205+
206+ t .Run ("multipart with charset" , func (t * testing.T ) {
207+ // "café" in iso-8859-1
208+ body := string ([]byte {0x63 , 0x61 , 0x66 , 0xe9 })
209+ raw := []byte ("From: sender@example.com\r \n To: recipient@example.com\r \n Subject: Test\r \n Content-Type: multipart/alternative; boundary=\" bnd\" \r \n \r \n --bnd\r \n Content-Type: text/plain; charset=iso-8859-1\r \n \r \n " + body + "\r \n --bnd\r \n Content-Type: text/html; charset=iso-8859-1\r \n \r \n <p>" + body + "</p>\r \n --bnd--" )
210+
211+ parsed , _ , err := parseEmail (raw , []string {"recipient@example.com" })
212+ if err != nil {
213+ t .Fatal (err )
214+ }
215+ if ! strings .Contains (parsed .Text , "café" ) {
216+ t .Errorf ("Text = %q, want to contain %q" , parsed .Text , "café" )
217+ }
218+ if ! strings .Contains (parsed .HTML , "café" ) {
219+ t .Errorf ("HTML = %q, want to contain %q" , parsed .HTML , "café" )
220+ }
221+ })
222+ }
223+
131224func TestParseAddresses (t * testing.T ) {
132225 t .Run ("name and email" , func (t * testing.T ) {
133226 header := make (map [string ][]string )
0 commit comments