Skip to content

Commit 9d7c0af

Browse files
Expanded test coverage for binary content (#4332)
* Expanded test coverage for binary git diffs * reverted old changes and added binary test in chunker * revert more * added filesystem binary file scan test
1 parent 9b59e90 commit 9d7c0af

File tree

3 files changed

+111
-4
lines changed

3 files changed

+111
-4
lines changed

pkg/gitparse/gitparse_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ package gitparse
22

33
import (
44
"bytes"
5+
"strings"
6+
"testing"
7+
"time"
8+
59
"github.com/google/go-cmp/cmp"
610
"github.com/google/go-cmp/cmp/cmpopts"
711
"github.com/stretchr/testify/assert"
812
"github.com/stretchr/testify/require"
9-
"strings"
10-
"testing"
11-
"time"
1213

1314
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
1415
"github.com/trufflesecurity/trufflehog/v3/pkg/process"
@@ -778,8 +779,8 @@ func assertDiffEqualToExpected(t *testing.T, expected *Diff, actual *Diff) {
778779
assert.NoError(t, err)
779780
assert.Equal(t, expectedDiffStr, actualDiffStr)
780781
}
781-
// TODO - Add test coverage for binary diffs (if it isn't already elsewhere)
782782

783+
// TODO - Add test coverage for binary diffs (if it isn't already elsewhere)
783784
}
784785

785786
func TestCommitParsing(t *testing.T) {

pkg/sources/chunker_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,38 @@ func TestNewChunkedReader(t *testing.T) {
9797
wantChunks: []string{strings.Repeat("a", 2048), strings.Repeat("a", 2048), strings.Repeat("a", 2048), strings.Repeat("a", 1024)},
9898
wantErr: false,
9999
},
100+
{
101+
name: "binary data - bin",
102+
input: string(generateBinaryContent("bin")),
103+
chunkSize: DefaultChunkSize,
104+
peekSize: DefaultPeekSize,
105+
wantChunks: []string{"TuffleHog"},
106+
wantErr: false,
107+
},
108+
{
109+
name: "binary data - exe",
110+
input: string(generateBinaryContent("exe")),
111+
chunkSize: DefaultChunkSize,
112+
peekSize: DefaultPeekSize,
113+
wantChunks: []string{"MZ\x90\x03\x00\x04\x00\xff\x00\xb8:\xf2~\x11]\x9b\xc8O\xa1g0\xeb\x94,\rzV\x88\xfa\x19+\xc3\xd0nTuffleHog\xab\xcd8\x04W\xf1j\x9e\x03\xd8A\xb6/u\xcc\v\x94\xe7P8\xad\x1fc{\x0e\xf5)\xc4m\x82\x10"},
114+
wantErr: false,
115+
},
116+
{
117+
name: "binary data - dmg",
118+
input: string(generateBinaryContent("dmg")),
119+
chunkSize: DefaultChunkSize,
120+
peekSize: DefaultPeekSize,
121+
wantChunks: []string{"\x00\x00\x00\x00TruffleHog\x00\x00\x00\x00koly"},
122+
wantErr: false,
123+
},
124+
{
125+
name: "binary data - tag.gz",
126+
input: string(generateBinaryContent("tar.gz")),
127+
chunkSize: DefaultChunkSize,
128+
peekSize: DefaultPeekSize,
129+
wantChunks: []string{"\x1f\x8b\bthis is binary content - trufflehog\x00\x00\x00\x00"},
130+
wantErr: false,
131+
},
100132
}
101133

102134
for _, tt := range tests {
@@ -212,3 +244,43 @@ func TestReadInChunksWithCancellation(t *testing.T) {
212244
}
213245
}
214246
}
247+
248+
// https://en.wikipedia.org/wiki/List_of_file_signatures
249+
func generateBinaryContent(contentType string) []byte {
250+
switch contentType {
251+
case "tar.gz":
252+
return []byte{
253+
0x1F, 0x8B, 0x08, // GZIP magic + compression method
254+
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
255+
0x62, 0x69, 0x6E, 0x61, 0x72, 0x79, 0x20, 0x63,
256+
0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x2D,
257+
0x20, 0x74, 0x72, 0x75, 0x66, 0x66, 0x6C, 0x65,
258+
0x68, 0x6F, 0x67, 0x00, 0x00, 0x00, 0x00,
259+
}
260+
case "exe":
261+
return []byte{
262+
// https://superuser.com/questions/1334140/how-to-check-if-a-binary-is-16-bit-on-windows
263+
0x4D, 0x5A, // 'MZ' magic number for EXE
264+
0x90, 0x03, 0x00, 0x04, 0x00, 0xff, 0x00, 0xb8,
265+
0x3a, 0xf2, 0x7e, 0x11, 0x5d, 0x9b, 0xc8, 0x4f,
266+
0xa1, 0x67, 0x30, 0xeb, 0x94, 0x2c, 0x0d, 0x7a,
267+
0x56, 0x88, 0xfa, 0x19, 0x2b, 0xc3, 0xd0, 0x6e,
268+
0x54, 0x75, 0x66, 0x66, 0x6C, 0x65, 0x48, 0x6F,
269+
0x67, 0xab, 0xcd, 0x38, 0x04, 0x57, 0xf1, 0x6a,
270+
0x9e, 0x03, 0xd8, 0x41, 0xb6, 0x2f, 0x75, 0xcc,
271+
0x0b, 0x94, 0xe7, 0x50, 0x38, 0xad, 0x1f, 0x63,
272+
0x7b, 0x0e, 0xf5, 0x29, 0xc4, 0x6d, 0x82, 0x10,
273+
}
274+
case "bin":
275+
return []byte{0x54, 0x75, 0x66, 0x66, 0x6C, 0x65, 0x48, 0x6F, 0x67}
276+
case "dmg":
277+
return []byte{
278+
0x00, 0x00, 0x00, 0x00,
279+
0x54, 0x72, 0x75, 0x66, 0x66, 0x6C, 0x65, 0x48, 0x6F, 0x67,
280+
0x00, 0x00, 0x00, 0x00,
281+
0x6B, 0x6F, 0x6C, 0x79, // "koly" magic number for dmg
282+
}
283+
}
284+
285+
return nil
286+
}

pkg/sources/filesystem/filesystem_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,40 @@ func TestScanFile(t *testing.T) {
124124
assert.Contains(t, foundSecret, secretPart1+secretPart2)
125125
}
126126

127+
func TestScanBinaryFile(t *testing.T) {
128+
tmpfile, err := os.CreateTemp("", "example.bin")
129+
require.NoError(t, err)
130+
defer os.Remove(tmpfile.Name())
131+
132+
// binary data that decodes to "TuffleHog"
133+
fileContents := []byte{0x54, 0x75, 0x66, 0x66, 0x6C, 0x65, 0x48, 0x6F, 0x67}
134+
_, err = tmpfile.Write(fileContents)
135+
require.NoError(t, err)
136+
require.NoError(t, tmpfile.Close())
137+
138+
source := &Source{}
139+
chunksChan := make(chan *sources.Chunk, 2)
140+
errChan := make(chan error, 1)
141+
142+
ctx := context.WithLogger(context.Background(), logr.Discard())
143+
144+
go func() {
145+
defer close(chunksChan)
146+
errChan <- source.scanFile(ctx, tmpfile.Name(), chunksChan)
147+
}()
148+
149+
err = <-errChan
150+
require.NoError(t, err)
151+
152+
var data string
153+
for chunk := range chunksChan {
154+
require.NotNil(t, chunk)
155+
data += string(chunk.Data)
156+
}
157+
158+
assert.Contains(t, data, "TuffleHog")
159+
}
160+
127161
func TestEnumerate(t *testing.T) {
128162
// TODO: refactor to allow a virtual filesystem.
129163
t.Parallel()

0 commit comments

Comments
 (0)