7 mathrand "math/rand/v2"
12func TestCompress(t *testing.T) {
16 tc.login("mjl@mox.example", password0)
18 tc.transactf("bad", "compress")
19 tc.transactf("bad", "compress bogus ")
20 tc.transactf("no", "compress bogus")
22 tc.client.CompressDeflate()
23 tc.transactf("no", "compress deflate") // Cannot have multiple.
24 tc.xcodeWord("COMPRESSIONACTIVE")
26 tc.client.Select("inbox")
27 tc.transactf("ok", "append inbox (\\seen) {%d+}\r\n%s", len(exampleMsg), exampleMsg)
28 tc.transactf("ok", "noop")
29 tc.transactf("ok", "fetch 1 body.peek[1]")
32func TestCompressStartTLS(t *testing.T) {
36 tc.client.StartTLS(&tls.Config{InsecureSkipVerify: true})
37 tc.login("mjl@mox.example", password0)
38 tc.client.CompressDeflate()
39 tc.client.Select("inbox")
40 tc.transactf("ok", "append inbox (\\seen) {%d+}\r\n%s", len(exampleMsg), exampleMsg)
41 tc.transactf("ok", "noop")
42 tc.transactf("ok", "fetch 1 body.peek[1]")
45func TestCompressBreak(t *testing.T) {
46 // Close the client connection when the server is writing. That causes writes in
47 // the server to fail (panic), jumping out of the flate writer and leaving its
48 // state inconsistent. We must not call into the flate writer again because due to
49 // its broken internal state it may cause array out of bounds accesses.
55 // Add random data (so it is not compressible). Don't know why, but only
56 // reproducible with large writes. As if setting socket buffers had no effect.
57 buf := make([]byte, 64*1024)
58 _, err := io.ReadFull(mathrand.NewChaCha8([32]byte{}), buf)
59 tcheck(t, err, "read random")
60 text := base64.StdEncoding.EncodeToString(buf)
62 n := min(76, len(text))
63 msg += text[:n] + "\r\n"
67 tc.login("mjl@mox.example", password0)
68 tc.client.CompressDeflate()
69 tc.client.Select("inbox")
70 tc.transactf("ok", "append inbox (\\seen) {%d+}\r\n%s", len(msg), msg)
71 tc.transactf("ok", "noop")
73 // Write request. Close connection instead of reading data. Write will panic,
74 // coming through flate writer leaving its state inconsistent. Server must not try
75 // to Flush/Write again on flate writer or it may panic.
76 tc.client.Writelinef("x fetch 1 body.peek[1]")
78 // Close client connection and prevent cleanup from closing the client again.
79 time.Sleep(time.Second / 10)
81 tc.conn.Close() // Simulate client disappearing.