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
This commit is contained in:
@@ -2,13 +2,14 @@ package gitparse
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/google/go-cmp/cmp/cmpopts"
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
||||||
"github.com/trufflesecurity/trufflehog/v3/pkg/process"
|
"github.com/trufflesecurity/trufflehog/v3/pkg/process"
|
||||||
@@ -778,8 +779,8 @@ func assertDiffEqualToExpected(t *testing.T, expected *Diff, actual *Diff) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, expectedDiffStr, actualDiffStr)
|
assert.Equal(t, expectedDiffStr, actualDiffStr)
|
||||||
}
|
}
|
||||||
// TODO - Add test coverage for binary diffs (if it isn't already elsewhere)
|
|
||||||
|
|
||||||
|
// TODO - Add test coverage for binary diffs (if it isn't already elsewhere)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCommitParsing(t *testing.T) {
|
func TestCommitParsing(t *testing.T) {
|
||||||
|
|||||||
@@ -97,6 +97,38 @@ func TestNewChunkedReader(t *testing.T) {
|
|||||||
wantChunks: []string{strings.Repeat("a", 2048), strings.Repeat("a", 2048), strings.Repeat("a", 2048), strings.Repeat("a", 1024)},
|
wantChunks: []string{strings.Repeat("a", 2048), strings.Repeat("a", 2048), strings.Repeat("a", 2048), strings.Repeat("a", 1024)},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "binary data - bin",
|
||||||
|
input: string(generateBinaryContent("bin")),
|
||||||
|
chunkSize: DefaultChunkSize,
|
||||||
|
peekSize: DefaultPeekSize,
|
||||||
|
wantChunks: []string{"TuffleHog"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "binary data - exe",
|
||||||
|
input: string(generateBinaryContent("exe")),
|
||||||
|
chunkSize: DefaultChunkSize,
|
||||||
|
peekSize: DefaultPeekSize,
|
||||||
|
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"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "binary data - dmg",
|
||||||
|
input: string(generateBinaryContent("dmg")),
|
||||||
|
chunkSize: DefaultChunkSize,
|
||||||
|
peekSize: DefaultPeekSize,
|
||||||
|
wantChunks: []string{"\x00\x00\x00\x00TruffleHog\x00\x00\x00\x00koly"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "binary data - tag.gz",
|
||||||
|
input: string(generateBinaryContent("tar.gz")),
|
||||||
|
chunkSize: DefaultChunkSize,
|
||||||
|
peekSize: DefaultPeekSize,
|
||||||
|
wantChunks: []string{"\x1f\x8b\bthis is binary content - trufflehog\x00\x00\x00\x00"},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@@ -212,3 +244,43 @@ func TestReadInChunksWithCancellation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/List_of_file_signatures
|
||||||
|
func generateBinaryContent(contentType string) []byte {
|
||||||
|
switch contentType {
|
||||||
|
case "tar.gz":
|
||||||
|
return []byte{
|
||||||
|
0x1F, 0x8B, 0x08, // GZIP magic + compression method
|
||||||
|
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
|
||||||
|
0x62, 0x69, 0x6E, 0x61, 0x72, 0x79, 0x20, 0x63,
|
||||||
|
0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x2D,
|
||||||
|
0x20, 0x74, 0x72, 0x75, 0x66, 0x66, 0x6C, 0x65,
|
||||||
|
0x68, 0x6F, 0x67, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
}
|
||||||
|
case "exe":
|
||||||
|
return []byte{
|
||||||
|
// https://superuser.com/questions/1334140/how-to-check-if-a-binary-is-16-bit-on-windows
|
||||||
|
0x4D, 0x5A, // 'MZ' magic number for EXE
|
||||||
|
0x90, 0x03, 0x00, 0x04, 0x00, 0xff, 0x00, 0xb8,
|
||||||
|
0x3a, 0xf2, 0x7e, 0x11, 0x5d, 0x9b, 0xc8, 0x4f,
|
||||||
|
0xa1, 0x67, 0x30, 0xeb, 0x94, 0x2c, 0x0d, 0x7a,
|
||||||
|
0x56, 0x88, 0xfa, 0x19, 0x2b, 0xc3, 0xd0, 0x6e,
|
||||||
|
0x54, 0x75, 0x66, 0x66, 0x6C, 0x65, 0x48, 0x6F,
|
||||||
|
0x67, 0xab, 0xcd, 0x38, 0x04, 0x57, 0xf1, 0x6a,
|
||||||
|
0x9e, 0x03, 0xd8, 0x41, 0xb6, 0x2f, 0x75, 0xcc,
|
||||||
|
0x0b, 0x94, 0xe7, 0x50, 0x38, 0xad, 0x1f, 0x63,
|
||||||
|
0x7b, 0x0e, 0xf5, 0x29, 0xc4, 0x6d, 0x82, 0x10,
|
||||||
|
}
|
||||||
|
case "bin":
|
||||||
|
return []byte{0x54, 0x75, 0x66, 0x66, 0x6C, 0x65, 0x48, 0x6F, 0x67}
|
||||||
|
case "dmg":
|
||||||
|
return []byte{
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x54, 0x72, 0x75, 0x66, 0x66, 0x6C, 0x65, 0x48, 0x6F, 0x67,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x6B, 0x6F, 0x6C, 0x79, // "koly" magic number for dmg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -124,6 +124,40 @@ func TestScanFile(t *testing.T) {
|
|||||||
assert.Contains(t, foundSecret, secretPart1+secretPart2)
|
assert.Contains(t, foundSecret, secretPart1+secretPart2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestScanBinaryFile(t *testing.T) {
|
||||||
|
tmpfile, err := os.CreateTemp("", "example.bin")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.Remove(tmpfile.Name())
|
||||||
|
|
||||||
|
// binary data that decodes to "TuffleHog"
|
||||||
|
fileContents := []byte{0x54, 0x75, 0x66, 0x66, 0x6C, 0x65, 0x48, 0x6F, 0x67}
|
||||||
|
_, err = tmpfile.Write(fileContents)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, tmpfile.Close())
|
||||||
|
|
||||||
|
source := &Source{}
|
||||||
|
chunksChan := make(chan *sources.Chunk, 2)
|
||||||
|
errChan := make(chan error, 1)
|
||||||
|
|
||||||
|
ctx := context.WithLogger(context.Background(), logr.Discard())
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer close(chunksChan)
|
||||||
|
errChan <- source.scanFile(ctx, tmpfile.Name(), chunksChan)
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = <-errChan
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var data string
|
||||||
|
for chunk := range chunksChan {
|
||||||
|
require.NotNil(t, chunk)
|
||||||
|
data += string(chunk.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Contains(t, data, "TuffleHog")
|
||||||
|
}
|
||||||
|
|
||||||
func TestEnumerate(t *testing.T) {
|
func TestEnumerate(t *testing.T) {
|
||||||
// TODO: refactor to allow a virtual filesystem.
|
// TODO: refactor to allow a virtual filesystem.
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|||||||
Reference in New Issue
Block a user