Fix binary chunk decoding and inflating

Git uses a unique Base85 encoding with different characters than the
ascii85 encoding implemented by Go, so add a custom decoding function.
Once decoded, use zlib instead of the raw DEFLATE algorithm to
decompress the data.

These issues were caught by some basic parsing tests which are added
here as well.
This commit is contained in:
Billy Keyes
2019-04-13 22:24:49 -07:00
parent 22fb5076be
commit 8ce8cba533
3 changed files with 136 additions and 23 deletions
+61
View File
@@ -1,6 +1,7 @@
package gitdiff
import (
"encoding/binary"
"io"
"reflect"
"testing"
@@ -108,3 +109,63 @@ func TestParseBinaryFragmentHeader(t *testing.T) {
})
}
}
func TestParseBinaryChunk(t *testing.T) {
tests := map[string]struct {
Input string
Fragment BinaryFragment
Output []byte
Err bool
}{
"newFile": {
Input: "gcmZQzU|?i`U?w2V48*KJ%mKu_Kr9NxN<eH500b)lkN^Mx\n\n",
Fragment: BinaryFragment{
Size: 40,
},
Output: fib(10),
},
"newFileMultiline": {
Input: "zcmZQzU|?i`U?w2V48*KJ%mKu_Kr9NxN<eH5#F0Qe0f=7$l~*z_FeL$%-)3N7vt?l5\n" +
"zl3-vE2xVZ9%4J~CI>f->s?WfX|B-=Vs{#X~svra7Ekg#T|4s}nH;WnAZ)|1Y*`&cB\n" +
"s(sh?X(Uz6L^!Ou&aF*u`J!eibJifSrv0z>$Q%Hd(^HIJ<Y?5`S0gT5UE&u=k\n\n",
Fragment: BinaryFragment{
Size: 160,
},
Output: fib(40),
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
p := newTestParser(test.Input, true)
frag := test.Fragment
err := p.ParseBinaryChunk(&frag)
if test.Err {
if err == nil || err == io.EOF {
t.Fatalf("expected error parsing binary chunk, but got %v", err)
}
return
}
if err != nil {
t.Fatalf("unexpected error parsing binary chunk: %v", err)
}
if !reflect.DeepEqual(test.Output, frag.Data) {
t.Errorf("incorrect binary chunk\nexpected: %+v\n actual: %+v", test.Output, frag.Data)
}
})
}
}
func fib(n int) []byte {
seq := []uint32{1, 1}
for i := 2; i < n; i++ {
seq = append(seq, seq[i-1]+seq[i-2])
}
buf := make([]byte, 4*n)
for i, v := range seq[:n] {
binary.BigEndian.PutUint32(buf[i*4:], v)
}
return buf
}