Skip to content

Commit

Permalink
fix(status): underlying slice corruption issue
Browse files Browse the repository at this point in the history
I believe this should fix issues #26 #34 and #35.
  • Loading branch information
mroth committed May 23, 2019
1 parent cf89d54 commit 8c55c0d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 3 deletions.
14 changes: 11 additions & 3 deletions commands/status/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,17 @@ func ProcessChanges(s *bufio.Scanner, root string) ([]*StatusItem, error) {
// ...if chunk represents a rename or copy op, need to append another chunk
// to get the full change item, with NUL manually reinserted because scanner
// will extract past it.
if (chunk[0] == 'R' || chunk[0] == 'C') && s.Scan() {
chunk = append(chunk, '\x00')
chunk = append(chunk, s.Bytes()...)
//
// Note that the underlying slice from previous scanner.Bytes() MAY be
// overridden by subsequent scans, so need to copy it to a new slice
// first before scanning to get the next token.
if chunk[0] == 'R' || chunk[0] == 'C' {
composite := make([]byte, len(chunk))
copy(composite, chunk)
s.Scan()
composite = append(composite, '\x00')
composite = append(composite, s.Bytes()...)
chunk = composite
}
statuses, err := processChange(chunk, wd, root)
if err != nil {
Expand Down
25 changes: 25 additions & 0 deletions commands/status/process_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,28 @@ func TestExtractBranch(t *testing.T) {
})
}
}

/*
// Test to verify https://github.com/mroth/scmpuff/issues/26.
//
// Leaving commented out since unlikely to encounter this exact issue again in
// future, and I'm not sure about importing the user's datafile into this repo.
//
// If needed again, the data file is attached to the issue as `output.txt`.
func TestBrokenProcessChanges(t *testing.T) {
dat, err := ioutil.ReadFile("testdata/cjfuller_sample.dat")
if err != nil {
t.Fatal(err)
}
s := bufio.NewScanner(bytes.NewReader(dat))
s.Split(nulSplitFunc)
actual, err := ProcessChanges(s, "")
if err != nil {
t.Fatal(err)
}
if len(actual) != 270 { // `git status -s | wc -l` in replicated repo
t.Errorf("expected %v changes, got %v", 270, len(actual))
}
}
*/

0 comments on commit 8c55c0d

Please sign in to comment.