From e2a407babb16cacb5b5040af129ee8c3118b24c3 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sat, 31 Jan 2015 21:18:51 +0100 Subject: [PATCH] Create large buffer when encrypting a large tree This fixes #80 --- key_test.go | 20 ++++++++++++++++++++ server.go | 17 +++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/key_test.go b/key_test.go index 77919f046..f5c9005f5 100644 --- a/key_test.go +++ b/key_test.go @@ -80,6 +80,26 @@ func TestEncryptDecrypt(t *testing.T) { } } +func TestSmallBuffer(t *testing.T) { + s := setupBackend(t) + defer teardownBackend(t, s) + k := setupKey(t, s, testPassword) + + size := 600 + data := make([]byte, size) + f, err := os.Open("/dev/urandom") + ok(t, err) + + _, err = io.ReadFull(f, data) + ok(t, err) + + ciphertext := make([]byte, size/2) + _, err = k.Encrypt(ciphertext, data) + // this must throw an error, since the target slice is too small + assert(t, err != nil && err == restic.ErrBufferTooSmall, + "expected restic.ErrBufferTooSmall, got %#v", err) +} + func TestLargeEncrypt(t *testing.T) { if !*testLargeCrypto { t.SkipNow() diff --git a/server.go b/server.go index 5c1f5f64a..d288872ae 100644 --- a/server.go +++ b/server.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/restic/restic/backend" + "github.com/restic/restic/debug" ) type Server struct { @@ -143,8 +144,20 @@ func (s Server) Save(t backend.Type, data []byte, id backend.ID) (Blob, error) { Size: uint64(len(data)), } - ciphertext := GetChunkBuf("ch.Save()") - defer FreeChunkBuf("ch.Save()", ciphertext) + var ciphertext []byte + + // if the data is small enough, use a slice from the pool + if len(data) <= maxCiphertextSize-ivSize-hmacSize { + ciphertext = GetChunkBuf("ch.Save()") + defer FreeChunkBuf("ch.Save()", ciphertext) + } else { + l := len(data) + ivSize + hmacSize + + debug.Log("Server.Save", "create large slice of %d bytes for ciphertext", l) + + // use a new slice + ciphertext = make([]byte, l) + } // encrypt blob n, err := s.Encrypt(ciphertext, data)