summaryrefslogtreecommitdiff
path: root/internal/extract/fuzz_test.go
blob: 5f707d2a86acaf6304b91adf138e2e8f1c4f5e2d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// SPDX-License-Identifier: GPL-3.0-or-later

package extract

import (
	"archive/zip"
	"bytes"
	"context"
	"os"
	"path/filepath"
	"testing"
)

// FuzzStripMarkup: decoding and stripping any bytes as HTML never panics.
func FuzzStripMarkup(f *testing.F) {
	for _, s := range []string{"<p>a &amp; b</p>", "<script>x</script>y", "<!-- c", "<", "&#x110000;", "<a href='>'>t</a>", "\xff\xfe<\x00p\x00>\x00", "\xef\xbb\xbf\xff"} {
		f.Add([]byte(s))
	}
	f.Fuzz(func(t *testing.T, data []byte) {
		stripMarkup(decode(data))
	})
}

// FuzzZipText: reading any bytes as a .docx never panics and never returns
// more text than the budget allows - each entry adds at most one separating
// newline beyond it, and an entry takes more than one byte of the archive.
func FuzzZipText(f *testing.F) {
	var buf bytes.Buffer
	zw := zip.NewWriter(&buf)
	w, err := zw.Create("word/document.xml")
	if err != nil {
		f.Fatal(err)
	}
	if _, err := w.Write([]byte(`<w:document><w:body><w:p><w:r><w:t>acme ltd</w:t></w:r></w:p></w:body></w:document>`)); err != nil {
		f.Fatal(err)
	}
	if err := zw.Close(); err != nil {
		f.Fatal(err)
	}
	f.Add(buf.Bytes())
	f.Add([]byte("PK\x03\x04"))
	f.Add([]byte{})
	old := zipBudget
	zipBudget = 4 << 10
	f.Cleanup(func() { zipBudget = old })
	f.Fuzz(func(t *testing.T, data []byte) {
		p := filepath.Join(t.TempDir(), "f.docx")
		if err := os.WriteFile(p, data, 0o600); err != nil {
			t.Fatal(err)
		}
		text, err := zipText(context.Background(), p, "docx", 0)
		if err == nil && int64(len(text)) > zipBudget+int64(len(data)) {
			t.Fatalf("%d bytes of text from a %d-byte archive, budget %d", len(text), len(data), zipBudget)
		}
	})
}