mirror of
https://github.com/mjl-/mox.git
synced 2025-07-10 07:14:40 +03:00
mox!
This commit is contained in:
140
imapserver/fuzz_test.go
Normal file
140
imapserver/fuzz_test.go
Normal file
@ -0,0 +1,140 @@
|
||||
package imapserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/mjl-/mox/imapclient"
|
||||
"github.com/mjl-/mox/mox-"
|
||||
"github.com/mjl-/mox/store"
|
||||
)
|
||||
|
||||
// Fuzz the server. For each fuzz string, we set up servers in various connection states, and write the string as command.
|
||||
func FuzzServer(f *testing.F) {
|
||||
seed := []string{
|
||||
fmt.Sprintf("authenticate plain %s", base64.StdEncoding.EncodeToString([]byte("\u0000mjl@mox.example\u0000testtest"))),
|
||||
"*",
|
||||
"capability",
|
||||
"noop",
|
||||
"logout",
|
||||
"select inbox",
|
||||
"examine inbox",
|
||||
"unselect",
|
||||
"close",
|
||||
"expunge",
|
||||
"subscribe inbox",
|
||||
"unsubscribe inbox",
|
||||
`lsub "" "*"`,
|
||||
`list "" ""`,
|
||||
`namespace`,
|
||||
"enable utf8=accept",
|
||||
"create inbox",
|
||||
"create tmpbox",
|
||||
"rename tmpbox ntmpbox",
|
||||
"delete ntmpbox",
|
||||
"status inbox (uidnext messages uidvalidity deleted size unseen recent)",
|
||||
"append inbox (\\seen) {2+}\r\nhi",
|
||||
"fetch 1 all",
|
||||
"fetch 1 body",
|
||||
"fetch 1 (bodystructure)",
|
||||
`store 1 flags (\seen \answered)`,
|
||||
`store 1 +flags ($junk)`,
|
||||
`store 1 -flags ($junk)`,
|
||||
"noop",
|
||||
"copy 1Trash",
|
||||
"copy 1 Trash",
|
||||
"move 1 Trash",
|
||||
"search 1 all",
|
||||
}
|
||||
for _, cmd := range seed {
|
||||
const tag = "x "
|
||||
f.Add(tag + cmd)
|
||||
}
|
||||
|
||||
mox.Context = context.Background()
|
||||
mox.ConfigStaticPath = "../testdata/imap/mox.conf"
|
||||
mox.MustLoadConfig()
|
||||
dataDir := mox.ConfigDirPath(mox.Conf.Static.DataDir)
|
||||
os.RemoveAll(dataDir)
|
||||
acc, err := store.OpenAccount("mjl")
|
||||
if err != nil {
|
||||
f.Fatalf("open account: %v", err)
|
||||
}
|
||||
defer acc.Close()
|
||||
err = acc.SetPassword("testtest")
|
||||
if err != nil {
|
||||
f.Fatalf("set password: %v", err)
|
||||
}
|
||||
done := store.Switchboard()
|
||||
defer close(done)
|
||||
|
||||
comm := store.RegisterComm(acc)
|
||||
defer comm.Unregister()
|
||||
|
||||
var cid int64 = 1
|
||||
|
||||
var fl *os.File
|
||||
if false {
|
||||
fl, err = os.Create("fuzz.log")
|
||||
if err != nil {
|
||||
f.Fatalf("fuzz log")
|
||||
}
|
||||
defer fl.Close()
|
||||
}
|
||||
flog := func(err error, msg string) {
|
||||
if fl != nil && err != nil {
|
||||
fmt.Fprintf(fl, "%s: %v\n", msg, err)
|
||||
}
|
||||
}
|
||||
|
||||
f.Fuzz(func(t *testing.T, s string) {
|
||||
run := func(cmds []string) {
|
||||
serverConn, clientConn := net.Pipe()
|
||||
defer serverConn.Close()
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
x := recover()
|
||||
// Protocol can become botched, when fuzzer sends literals.
|
||||
if x == nil {
|
||||
return
|
||||
}
|
||||
err, ok := x.(error)
|
||||
if !ok || !errors.Is(err, os.ErrDeadlineExceeded) {
|
||||
panic(x)
|
||||
}
|
||||
}()
|
||||
|
||||
defer clientConn.Close()
|
||||
|
||||
err := clientConn.SetDeadline(time.Now().Add(time.Second))
|
||||
flog(err, "set client deadline")
|
||||
client, _ := imapclient.New(clientConn, true)
|
||||
|
||||
for _, cmd := range cmds {
|
||||
client.Commandf("", "%s", cmd)
|
||||
client.Response()
|
||||
}
|
||||
client.Commandf("", "%s", s)
|
||||
client.Response()
|
||||
}()
|
||||
|
||||
err = serverConn.SetDeadline(time.Now().Add(time.Second))
|
||||
flog(err, "set server deadline")
|
||||
serve("test", cid, nil, serverConn, false, true)
|
||||
cid++
|
||||
}
|
||||
|
||||
run([]string{})
|
||||
run([]string{"login mjl@mox.example testtest"})
|
||||
run([]string{"login mjl@mox.example testtest", "select inbox"})
|
||||
xappend := fmt.Sprintf("append inbox () {%d+}\r\n%s", len(exampleMsg), exampleMsg)
|
||||
run([]string{"login mjl@mox.example testtest", "select inbox", xappend})
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user