Files
EMLy/backend/utils/mail/tnef_diag8_test.go
Flavio Fois 54a3dff1c2 Add TNEF handling and email loading improvements
- Implement TNEF extraction and recursive parsing in new `tnef_reader.go` and associated tests.
- Create tests for TNEF extraction scenarios in `tnef_diag_test.go`, `tnef_diag7_test.go`, and `tnef_diag8_test.go`.
2026-02-14 09:03:41 +01:00

98 lines
2.8 KiB
Go

package internal
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"os"
"strings"
"testing"
"github.com/teamwork/tnef"
)
func TestTNEFDeepAttachment(t *testing.T) {
testFile := `H:\Dev\Gits\EMLy\EML_TNEF.eml`
if _, err := os.Stat(testFile); os.IsNotExist(err) {
t.Skip("test EML file not present")
}
f, _ := os.Open(testFile)
defer f.Close()
outerEmail, _ := Parse(f)
var innerData []byte
for _, att := range outerEmail.Attachments {
if strings.Contains(strings.ToLower(att.Filename), "postacert.eml") {
innerData, _ = io.ReadAll(att.Data)
break
}
}
innerEmail, _ := Parse(bytes.NewReader(innerData))
for _, att := range innerEmail.Attachments {
rawData, _ := io.ReadAll(att.Data)
if strings.ToLower(att.Filename) != "winmail.dat" {
continue
}
// Dig to level 2: top → embedded[0] → embedded[0]
streams0 := findEmbeddedTNEFStreams(rawData)
if len(streams0) == 0 {
t.Fatal("no embedded streams at level 0")
}
streams1 := findEmbeddedTNEFStreams(streams0[0])
if len(streams1) == 0 {
t.Fatal("no embedded streams at level 1")
}
// Decode level 2
decoded2, err := tnef.Decode(streams1[0])
if err != nil {
t.Fatalf("level 2 decode: %v", err)
}
fmt.Printf("Level 2 attachments: %d\n", len(decoded2.Attachments))
for i, a := range decoded2.Attachments {
fmt.Printf(" [%d] title=%q size=%d\n", i, a.Title, len(a.Data))
if len(a.Data) > 20 {
fmt.Printf(" first 20 bytes: %x\n", a.Data[:20])
// Check for EML, MSG, TNEF signatures
if len(a.Data) >= 4 {
sig := binary.LittleEndian.Uint32(a.Data[0:4])
if sig == 0x223E9F78 {
fmt.Println(" -> TNEF stream!")
}
}
if len(a.Data) >= 8 && bytes.Equal(a.Data[:8], []byte{0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}) {
fmt.Println(" -> MSG (OLE2) file!")
}
// Check if text/EML
if a.Data[0] < 128 && a.Data[0] >= 32 {
preview := string(a.Data[:min2(200, len(a.Data))])
if strings.Contains(preview, "From:") || strings.Contains(preview, "Content-Type") || strings.Contains(preview, "MIME") || strings.Contains(preview, "Received:") {
fmt.Printf(" -> Looks like an EML file! First 200 chars: %s\n", preview)
} else {
fmt.Printf(" -> Text data: %.200s\n", preview)
}
}
}
}
// Also check level 2's attAttachment for embedded msgs
streams2 := findEmbeddedTNEFStreams(streams1[0])
fmt.Printf("\nLevel 2 embedded TNEF streams: %d\n", len(streams2))
// Check all MAPI attributes at level 2
fmt.Println("\nLevel 2 MAPI attributes:")
for _, attr := range decoded2.Attributes {
fmt.Printf(" 0x%04X: %d bytes\n", attr.Name, len(attr.Data))
// PR_BODY
if attr.Name == 0x1000 && len(attr.Data) < 500 {
fmt.Printf(" PR_BODY: %s\n", string(attr.Data))
}
}
}
}