Skip to content

Commit 9601489

Browse files
authored
Merge pull request gitleaks#5 from trufflesecurity/master
Pull in Trufflehog improvements
2 parents 9c699f1 + 4617960 commit 9601489

File tree

3 files changed

+127
-8
lines changed

3 files changed

+127
-8
lines changed

gitdiff/apply_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"io"
77
"io/ioutil"
8+
"os/exec"
89
"path/filepath"
910
"testing"
1011
)
@@ -231,10 +232,16 @@ type applyTest struct {
231232
func (at applyTest) run(t *testing.T, apply func(io.Writer, *Applier, *File) error) {
232233
src, patch, out := at.Files.Load(t)
233234

234-
files, _, err := Parse(bytes.NewReader(patch))
235+
cmd := exec.Command("echo", "hello")
236+
237+
fileChan, err := Parse(cmd, io.NopCloser(bytes.NewReader(patch)))
235238
if err != nil {
236239
t.Fatalf("failed to parse patch file: %v", err)
237240
}
241+
var files []*File
242+
for file := range fileChan {
243+
files = append(files, file)
244+
}
238245
if len(files) != 1 {
239246
t.Fatalf("patch should contain exactly one file, but it has %d", len(files))
240247
}

gitdiff/parser.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"bufio"
88
"fmt"
99
"io"
10+
"os/exec"
1011
"strings"
1112
)
1213

@@ -15,7 +16,7 @@ const commitPrefix = "commit"
1516
// Parse parses a patch with changes to one or more files. Any content before
1617
// the first file is returned as the second value. If an error occurs while
1718
// parsing, it returns all files parsed before the error.
18-
func Parse(r io.Reader) (<-chan *File, error) {
19+
func Parse(cmd *exec.Cmd, r io.ReadCloser) (<-chan *File, error) {
1920
p := newParser(r)
2021
out := make(chan *File)
2122

@@ -27,8 +28,10 @@ func Parse(r io.Reader) (<-chan *File, error) {
2728
return out, err
2829
}
2930

30-
go func() {
31+
go func(cmd *exec.Cmd, out chan *File, r io.ReadCloser) {
3132
defer close(out)
33+
defer cmd.Wait()
34+
defer r.Close()
3235

3336
ph := &PatchHeader{}
3437
for {
@@ -65,7 +68,7 @@ func Parse(r io.Reader) (<-chan *File, error) {
6568
file.PatchHeader = ph
6669
out <- file
6770
}
68-
}()
71+
}(cmd, out, r)
6972

7073
return out, nil
7174
}

gitdiff/parser_test.go

Lines changed: 113 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ import (
44
"bytes"
55
"encoding/binary"
66
"encoding/json"
7+
"fmt"
78
"io"
89
"os"
10+
"os/exec"
911
"reflect"
12+
"strings"
1013
"testing"
14+
"time"
1115
)
1216

1317
func TestLineOperations(t *testing.T) {
@@ -394,6 +398,16 @@ Date: Tue Apr 2 22:55:40 2019 -0700
394398
InputFile: "testdata/one_file.patch",
395399
Output: []*File{
396400
{
401+
PatchHeader: &PatchHeader{
402+
SHA: "5d9790fec7d95aa223f3d20936340bf55ff3dcbe",
403+
Author: &PatchIdentity{
404+
Name: "Morton Haypenny",
405+
Email: "mhaypenny@example.com",
406+
},
407+
AuthorDate: asTime("2019-04-02T22:55:40-07:00"),
408+
Title: "A file with multiple fragments.",
409+
Body: "The content is arbitrary.",
410+
},
397411
OldName: "dir/file1.txt",
398412
NewName: "dir/file1.txt",
399413
OldMode: os.FileMode(0100644),
@@ -408,6 +422,16 @@ Date: Tue Apr 2 22:55:40 2019 -0700
408422
InputFile: "testdata/two_files.patch",
409423
Output: []*File{
410424
{
425+
PatchHeader: &PatchHeader{
426+
SHA: "5d9790fec7d95aa223f3d20936340bf55ff3dcbe",
427+
Author: &PatchIdentity{
428+
Name: "Morton Haypenny",
429+
Email: "mhaypenny@example.com",
430+
},
431+
AuthorDate: asTime("2019-04-02T22:55:40-07:00"),
432+
Title: "A file with multiple fragments.",
433+
Body: "The content is arbitrary.",
434+
},
411435
OldName: "dir/file1.txt",
412436
NewName: "dir/file1.txt",
413437
OldMode: os.FileMode(0100644),
@@ -416,6 +440,16 @@ Date: Tue Apr 2 22:55:40 2019 -0700
416440
TextFragments: textFragments,
417441
},
418442
{
443+
PatchHeader: &PatchHeader{
444+
SHA: "5d9790fec7d95aa223f3d20936340bf55ff3dcbe",
445+
Author: &PatchIdentity{
446+
Name: "Morton Haypenny",
447+
Email: "mhaypenny@example.com",
448+
},
449+
AuthorDate: asTime("2019-04-02T22:55:40-07:00"),
450+
Title: "A file with multiple fragments.",
451+
Body: "The content is arbitrary.",
452+
},
419453
OldName: "dir/file2.txt",
420454
NewName: "dir/file2.txt",
421455
OldMode: os.FileMode(0100644),
@@ -430,6 +464,15 @@ Date: Tue Apr 2 22:55:40 2019 -0700
430464
InputFile: "testdata/new_binary_file.patch",
431465
Output: []*File{
432466
{
467+
PatchHeader: &PatchHeader{
468+
SHA: "5d9790fec7d95aa223f3d20936340bf55ff3dcbe",
469+
Author: &PatchIdentity{
470+
Name: "Morton Haypenny",
471+
Email: "mhaypenny@example.com",
472+
},
473+
AuthorDate: asTime("2019-04-02T22:55:40-07:00"),
474+
Title: "A binary file with the first 10 fibonacci numbers.",
475+
},
433476
OldName: "",
434477
NewName: "dir/ten.bin",
435478
NewMode: os.FileMode(0100644),
@@ -460,7 +503,9 @@ Date: Tue Apr 2 22:55:40 2019 -0700
460503
t.Fatalf("unexpected error opening input file: %v", err)
461504
}
462505

463-
files, pre, err := Parse(f)
506+
cmd := exec.Command("echo", "hello")
507+
508+
fileChan, err := Parse(cmd, f)
464509
if test.Err {
465510
if err == nil || err == io.EOF {
466511
t.Fatalf("expected error parsing patch, but got %v", err)
@@ -470,13 +515,14 @@ Date: Tue Apr 2 22:55:40 2019 -0700
470515
if err != nil {
471516
t.Fatalf("unexpected error parsing patch: %v", err)
472517
}
518+
var files []*File
519+
for file := range fileChan {
520+
files = append(files, file)
521+
}
473522

474523
if len(test.Output) != len(files) {
475524
t.Fatalf("incorrect number of parsed files: expected %d, actual %d", len(test.Output), len(files))
476525
}
477-
if test.Preamble != pre {
478-
t.Errorf("incorrect preamble\nexpected: %q\n actual: %q", test.Preamble, pre)
479-
}
480526
for i := range test.Output {
481527
if !reflect.DeepEqual(test.Output[i], files[i]) {
482528
exp, _ := json.MarshalIndent(test.Output[i], "", " ")
@@ -488,10 +534,73 @@ Date: Tue Apr 2 22:55:40 2019 -0700
488534
}
489535
}
490536

537+
func BenchmarkParse(b *testing.B) {
538+
var inputDiff string
539+
{
540+
builder := strings.Builder{}
541+
builder.WriteString(`commit 5d9790fec7d95aa223f3d20936340bf55ff3dcbe
542+
Author: Morton Haypenny <mhaypenny@example.com>
543+
Date: Tue Apr 2 22:55:40 2019 -0700
544+
545+
A file with multiple fragments.
546+
547+
The content is arbitrary.
548+
549+
`)
550+
fileDiff := func(i int) string {
551+
return fmt.Sprintf(`diff --git a/dir/file%[1]d.txt b/dir/file%[1]d.txt
552+
index ebe9fa54..fe103e1d 100644
553+
--- a/dir/file%[1]d.txt
554+
+++ b/dir/file%[1]d.txt
555+
@@ -3,6 +3,8 @@ fragment 1
556+
context line
557+
-old line 1
558+
-old line 2
559+
context line
560+
+new line 1
561+
+new line 2
562+
+new line 3
563+
context line
564+
-old line 3
565+
+new line 4
566+
+new line 5
567+
@@ -31,2 +33,2 @@ fragment 2
568+
context line
569+
-old line 4
570+
+new line 6
571+
`, i)
572+
}
573+
for i := 0; i < 1000; i++ {
574+
_, err := builder.WriteString(fileDiff(i))
575+
if err != nil {
576+
panic(err)
577+
}
578+
}
579+
inputDiff = builder.String()
580+
}
581+
for i := 0; i < b.N; i++ {
582+
reader := io.NopCloser(strings.NewReader(inputDiff))
583+
ch, err := Parse(&exec.Cmd{}, reader)
584+
if err != nil {
585+
panic(err)
586+
}
587+
for range ch {
588+
}
589+
}
590+
}
591+
491592
func newTestParser(input string, init bool) *parser {
492593
p := newParser(bytes.NewBufferString(input))
493594
if init {
494595
_ = p.Next()
495596
}
496597
return p
497598
}
599+
600+
func asTime(s string) time.Time {
601+
t, err := time.Parse(time.RFC3339, s)
602+
if err != nil {
603+
panic(err)
604+
}
605+
return t
606+
}

0 commit comments

Comments
 (0)