Skip to content

refactor: fix #722 properly#1250

Merged
zricethezav merged 5 commits intogitleaks:masterfrom
savely-krasovsky:proper-fix-722
Aug 22, 2023
Merged

refactor: fix #722 properly#1250
zricethezav merged 5 commits intogitleaks:masterfrom
savely-krasovsky:proper-fix-722

Conversation

@savely-krasovsky
Copy link
Contributor

@savely-krasovsky savely-krasovsky commented Aug 11, 2023

Description:

This PR fixes #722 issue properly.

Currently git package is poorly written in my humble opinion. Probably this is why git_test.go commented out entirely, it just hard to test because of it.

Main problem: *exec.Cmd requires you to run Start() and then Wait() to release resources. But both git.GitDiff() and git.GitLog() return chan with git diff files, later consumer handles chan elements and parser (!) calls Wait() and closes stdout pipe. This is why you can't just defer cmd.Wait() in these functions, because otherwise you will get blocked, consumer don't consume diff files at this moment yet.

In order to fix this we need to merge this: gitleaks/go-gitdiff#6

We shouldn't get parser know about our implementation, it should just read from somethings, that's it.

Then we can use bytes.Buffer to copy stdout and defer both cmd.Wait() and stdout.Close() in git package directly. Also for some reason currently we don't even close stderr, this PR also fixes it.

To properly handle deferred stderrErr I use named return variables.

I understand that it slightly increases memory footprint, but I am sure it's worth it.

Checklist:

  • Does your PR pass tests?
  • Have you written new tests for your changes?
  • Have you lint your code locally prior to submission?

@savely-krasovsky savely-krasovsky marked this pull request as ready for review August 11, 2023 20:55
@zricethezav
Copy link
Collaborator

Then we can use bytes.Buffer to copy stdout and defer both cmd.Wait() and stdout.Close() in git package directly. Also for some reason currently we don't even close stderr, this PR also fixes it.

@L11r what's the point of copying? Can't we just pass stdout directly to gitdiff.Parse?

@savely-krasovsky
Copy link
Contributor Author

savely-krasovsky commented Aug 11, 2023

@zricethezav cmd.Wait() will complete only after both stderr and stdout will empty. Otherwise it will be blocked forever, because we didn't start to read stdout yet. With this buffer both stdout and stderr are empty, so cmd.Wait() completes successfully and then parser reads diffs from buffer easily.

It's not ideal, but much better than current implementation in my opinion.

@savely-krasovsky
Copy link
Contributor Author

savely-krasovsky commented Aug 12, 2023

Probably another option is to introduce some git.Client with struct which embeds *exec.Cmd and other stuff.

client := git.NewClient(opts...)
diffs := client.Log()
defer client.Close()
go func() {
  for diff := range diffs { /* handle findings */ }
}()
if client.Err() != nil {}

@savely-krasovsky
Copy link
Contributor Author

@zricethezav have pushed second refactor. It should look much better now, I didn't use copy this time.

@savely-krasovsky
Copy link
Contributor Author

I will send PR with tests for git package if it will be merged.

@savely-krasovsky
Copy link
Contributor Author

@zricethezav any comments? I know you are probably busy, but still think it's good to fix this issue properly.

@zricethezav
Copy link
Collaborator

@L11r these changes look good to me. I'm just running some memory profiles to make sure nothing is exploding

@savely-krasovsky
Copy link
Contributor Author

@zricethezav sure!

@zricethezav
Copy link
Collaborator

solid PR, thanks for the contribution @L11r

@zricethezav zricethezav merged commit 4526655 into gitleaks:master Aug 22, 2023
@savely-krasovsky savely-krasovsky deleted the proper-fix-722 branch August 23, 2023 18:42
savely-krasovsky added a commit to savely-krasovsky/gitleaks that referenced this pull request Aug 23, 2023
alayne222 pushed a commit to alayne222/gitleaks that referenced this pull request May 28, 2025
* refactor: fix gitleaks#722 properly

* fix(deps): update go-gitdiff to v0.9.0

* refactor: second attempt

* refactor: better git package api

* fix: add comments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gitleaks exits with exit code 0 when ambiguous argument to log-opts are provided

2 participants