diff options
author | Santiago M. Mola <santi@mola.io> | 2017-06-02 14:51:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-02 14:51:35 +0200 |
commit | b25c5ead44698a4a036435c8977581ea34f761dd (patch) | |
tree | c775ac6b264d260393e711b75432c250583fe06f /plumbing | |
parent | 87d2475dd70169bbcb49a70d79ca6cfdff492c38 (diff) | |
parent | f8480053f659120bc3fd33cbf92521cab11b06a6 (diff) | |
download | go-git-b25c5ead44698a4a036435c8977581ea34f761dd.tar.gz |
Merge pull request #411 from src-d/fix/delta-copy-operations
packfile: A copy operation cannot be bigger than 64kb
Diffstat (limited to 'plumbing')
-rw-r--r-- | plumbing/format/packfile/delta_test.go | 17 | ||||
-rw-r--r-- | plumbing/format/packfile/diff_delta.go | 19 |
2 files changed, 35 insertions, 1 deletions
diff --git a/plumbing/format/packfile/delta_test.go b/plumbing/format/packfile/delta_test.go index 43253b0..9ee3499 100644 --- a/plumbing/format/packfile/delta_test.go +++ b/plumbing/format/packfile/delta_test.go @@ -2,6 +2,7 @@ package packfile import ( "fmt" + "math/rand" . "gopkg.in/check.v1" ) @@ -61,9 +62,25 @@ func (s *DeltaSuite) SetUpSuite(c *C) { {"4", 400}, {"5", 23}}, target: []piece{{"1", 30}, {"2", 20}, {"7", 40}, {"4", 400}, {"5", 10}}, + }, { + description: "A copy operation bigger tan 64kb", + base: []piece{{bigRandStr, 1}, {"1", 200}}, + target: []piece{{bigRandStr, 1}}, }} } +var bigRandStr = randStringBytes(100 * 1024) + +const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +func randStringBytes(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand.Intn(len(letterBytes))] + } + return string(b) +} + func (s *DeltaSuite) TestAddDelta(c *C) { for _, t := range s.testCases { baseBuf := genBytes(t.base) diff --git a/plumbing/format/packfile/diff_delta.go b/plumbing/format/packfile/diff_delta.go index e3438aa..60a04d9 100644 --- a/plumbing/format/packfile/diff_delta.go +++ b/plumbing/format/packfile/diff_delta.go @@ -15,6 +15,10 @@ import ( const ( // Standard chunk size used to generate fingerprints s = 16 + + // https://github.com/git/git/blob/f7466e94375b3be27f229c78873f0acf8301c0a5/diff-delta.c#L428 + // Max size of a copy operation (64KB) + maxCopySize = 64 * 1024 ) // GetDelta returns an EncodedObject of type OFSDeltaObject. Base and Target object, @@ -70,7 +74,20 @@ func DiffDelta(src []byte, tgt []byte) []byte { ibuf.WriteByte(tgt[i]) } else { encodeInsertOperation(ibuf, buf) - buf.Write(encodeCopyOperation(offset, l)) + + rl := l + aOffset := offset + for { + if rl < maxCopySize { + buf.Write(encodeCopyOperation(aOffset, rl)) + break + } + + buf.Write(encodeCopyOperation(aOffset, maxCopySize)) + rl -= maxCopySize + aOffset += maxCopySize + } + i += l - 1 } } |