1 package asciisanitizer
2
3 import (
4 "bytes"
5 "testing"
6 "testing/iotest"
7
8 "github.com/stretchr/testify/require"
9 "golang.org/x/text/transform"
10 )
11
12 func TestSanitizerTransform(t *testing.T) {
13 tests := []struct {
14 name string
15 json bool
16 input string
17 want string
18 }{
19 {
20 name: "No control characters",
21 input: "The quick brown fox jumped over the lazy dog",
22 want: "The quick brown fox jumped over the lazy dog",
23 },
24 {
25 name: "JSON sanitization maintains valid JSON",
26 json: true,
27 input: `\u001B \\u001B \\\u001B \\\\u001B \\u001B\\u001B`,
28 want: `^[ \\^[ \\^[ \\\\^[ \\^[\\^[`,
29 },
30 {
31 name: "JSON C0 control character",
32 json: true,
33 input: `0\u0000`,
34 want: "0^@",
35 },
36 {
37 name: "JSON C0 control characters",
38 json: true,
39 input: `0\u0000 1\u0001 2\u0002 3\u0003 4\u0004 5\u0005 6\u0006 7\u0007 8\u0008 9\u0009 ` +
40 `A\u000a B\u000b C\u000c D\u000d E\u000e F\u000f ` +
41 `10\u0010 11\u0011 12\u0012 13\u0013 14\u0014 15\u0015 16\u0016 17\u0017 18\u0018 19\u0019 ` +
42 `1A\u001a 1B\u001b 1C\u001c 1D\u001d 1E\u001e 1F\u001f`,
43 want: `0^@ 1^A 2^B 3^C 4^D 5^E 6^F 7^G 8^H 9\u0009 ` +
44 `A\u000a B\u000b C^L D\u000d E^N F^O ` +
45 `10^P 11^Q 12^R 13^S 14^T 15^U 16^V 17^W 18^X 19^Y ` +
46 `1A^Z 1B^[ 1C^\\ 1D^] 1E^^ 1F^_`,
47 },
48 {
49 name: "JSON C1 control characters",
50 json: true,
51 input: `80\u0080 81\u0081 82\u0082 83\u0083 84\u0084 85\u0085 86\u0086 87\u0087 88\u0088 89\u0089 ` +
52 `8A\u008a 8B\u008b 8C\u008c 8D\u008d 8E\u008e 8F\u008f ` +
53 `90\u0090 91\u0091 92\u0092 93\u0093 94\u0094 95\u0095 96\u0096 97\u0097 98\u0098 99\u0099 ` +
54 `9A\u009a 9B\u009b 9C\u009c 9D\u009d 9E\u009e 9F\u009f`,
55 want: `80^@ 81^A 82^B 83^C 84^D 85^E 86^F 87^G 88^H 89^I ` +
56 `8A^J 8B^K 8C^L 8D^M 8E^N 8F^O ` +
57 `90^P 91^Q 92^R 93^S 94^T 95^U 96^V 97^W 98^X 99^Y ` +
58 `9A^Z 9B^[ 9C^\\ 9D^] 9E^^ 9F^_`,
59 },
60 {
61 name: "C0 control character",
62 input: "0\x00",
63 want: "0^@",
64 },
65 {
66 name: "C0 control characters",
67 input: "0\x00 1\x01 2\x02 3\x03 4\x04 5\x05 6\x06 7\x07 8\x08 9\x09 " +
68 "A\x0A B\x0B C\x0C D\x0D E\x0E F\x0F " +
69 "10\x10 11\x11 12\x12 13\x13 14\x14 15\x15 16\x16 17\x17 18\x18 19\x19 " +
70 "1A\x1A 1B\x1B 1C\x1C 1D\x1D 1E\x1E 1F\x1F",
71 want: "0^@ 1^A 2^B 3^C 4^D 5^E 6^F 7^G 8^H 9\t " +
72 "A\n B\v C^L D\r E^N F^O " +
73 "10^P 11^Q 12^R 13^S 14^T 15^U 16^V 17^W 18^X 19^Y " +
74 "1A^Z 1B^[ 1C^\\\\ 1D^] 1E^^ 1F^_",
75 },
76 {
77 name: "C1 control character",
78 input: "80\xC2\x80",
79 want: "80^@",
80 },
81 {
82 name: "C1 control characters",
83 input: "80\xC2\x80 81\xC2\x81 82\xC2\x82 83\xC2\x83 84\xC2\x84 85\xC2\x85 86\xC2\x86 87\xC2\x87 88\xC2\x88 89\xC2\x89 " +
84 "8A\xC2\x8A 8B\xC2\x8B 8C\xC2\x8C 8D\xC2\x8D 8E\xC2\x8E 8F\xC2\x8F " +
85 "90\xC2\x90 91\xC2\x91 92\xC2\x92 93\xC2\x93 94\xC2\x94 95\xC2\x95 96\xC2\x96 97\xC2\x97 98\xC2\x98 99\xC2\x99 " +
86 "9A\xC2\x9A 9B\xC2\x9B 9C\xC2\x9C 9D\xC2\x9D 9E\xC2\x9E 9F\xC2\x9F",
87 want: "80^@ 81^A 82^B 83^C 84^D 85^E 86^F 87^G 88^H 89^I " +
88 "8A^J 8B^K 8C^L 8D^M 8E^N 8F^O " +
89 "90^P 91^Q 92^R 93^S 94^T 95^U 96^V 97^W 98^X 99^Y " +
90 "9A^Z 9B^[ 9C^\\\\ 9D^] 9E^^ 9F^_",
91 },
92 }
93 for _, tt := range tests {
94 t.Run(tt.name, func(t *testing.T) {
95 sanitizer := &Sanitizer{JSON: tt.json}
96 reader := bytes.NewReader([]byte(tt.input))
97 transformReader := transform.NewReader(reader, sanitizer)
98 err := iotest.TestReader(transformReader, []byte(tt.want))
99 require.NoError(t, err)
100 })
101 }
102 }
103
View as plain text