Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: fix #722 properly #1250

Merged
merged 5 commits into from
Aug 22, 2023

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?

go.mod Outdated Show resolved Hide resolved
@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
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