gitdiff report "parser" can cause an infinite wait on parser error
groboclown opened this issue · comments
Describe the bug
If the underlying git parser encounters a problem, then this causes the NewGitDiffCmd
caller to never properly handle the error.
To Reproduce
Steps to reproduce the behavior:
I encountered this when the Git diff command returned a header like:
@@ -231,18446744073709551615 +231,1 @@
(I have no idea why Git generates this, but it did.) The long number there looks like Git attempted to turn a "-1" into a uint64 value. This caused the parseRange
function to generate an error, which then bubbled up to the parser.
The parser includes the code
if (err != nil) {
return
}
This causes the error to be lost.
Additionally, the DetectGit
seems to hang. The logic there contains:
select {
case gitdiffFile, open := <-diffFilesCh:
if !open {
diffFilesCh = nil
break
}
The !open
block runs after the error is detected, but the block remains open, and the errCh
never returns an error, which leaves the block listening forever.
One possible fix is to change the NewGitDiffCmd
function to call the parser like:
errCh := make(chan error)
go listenForStdErr(stderr, errCh)
gitdiffFiles, err := gitdiff.Parse(stdout, errCh)
and change the Parse
to accept the error channel, and change the on-error return
to now send the error to the error channel + return.
Unfortunately, this is a backwards-incompatible change for the go-gitdiff command.
Along with this, it looks like the DetectGit
function's case err, open := <-errCh
can cause the function to hang unless the d.Sema
is dealt with.
@groboclown thanks for bringing up this issue. Do you have a repo I can test with?
@zricethezav Unfortunately, I have not been able to trace the actions that lead to this behavior. I was seeing it with a complicated private repository. If I could find the way to generate it, it would also lead to a better bug report to the Git folks.