Add a few functions to calculate Blob buffer len

This commit is contained in:
Alexander Neumann 2017-01-13 12:57:05 +01:00
parent 91dcb958e0
commit 32a5c2c1f6
8 changed files with 41 additions and 25 deletions

View File

@ -5,7 +5,6 @@ import (
"io"
"math/rand"
"restic"
"restic/crypto"
"restic/repository"
"testing"
)
@ -45,7 +44,7 @@ func checkSavedFile(t *testing.T, repo restic.Repository, treeID restic.ID, name
t.Fatal(err)
}
buf := make([]byte, int(size), int(size)+crypto.Extension)
buf := restic.NewBlobBuffer(int(size))
n := loadBlob(t, repo, id, buf)
if n != len(buf) {
t.Errorf("wrong number of bytes read, want %d, got %d", len(buf), n)

21
src/restic/buffer.go Normal file
View File

@ -0,0 +1,21 @@
package restic
import "restic/crypto"
// NewBlobBuffer returns a buffer that is large enough to hold a blob of size
// plaintext bytes, including the crypto overhead.
func NewBlobBuffer(size int) []byte {
return make([]byte, size, size+crypto.Extension)
}
// PlaintextLength returns the plaintext length of a blob with ciphertextSize
// bytes.
func PlaintextLength(ciphertextSize int) int {
return ciphertextSize - crypto.Extension
}
// CiphertextLength returns the encrypted length of a blob with plaintextSize
// bytes.
func CiphertextLength(plaintextSize int) int {
return plaintextSize + crypto.Extension
}

View File

@ -10,7 +10,6 @@ import (
"syscall"
"time"
"restic/crypto"
"restic/errors"
"runtime"
@ -209,7 +208,7 @@ func (node Node) createFileAt(path string, repo Repository) error {
buf = buf[:cap(buf)]
if uint(len(buf)) < size {
buf = make([]byte, size, size+crypto.Extension)
buf = NewBlobBuffer(int(size))
}
n, err := repo.LoadBlob(DataBlob, id, buf)

View File

@ -85,15 +85,15 @@ func (p *Packer) Finalize() (uint, error) {
return 0, errors.Wrap(err, "Write")
}
hdrBytes := bytesHeader + crypto.Extension
if uint(n) != hdrBytes {
hdrBytes := restic.CiphertextLength(int(bytesHeader))
if n != hdrBytes {
return 0, errors.New("wrong number of bytes written")
}
bytesWritten += hdrBytes
bytesWritten += uint(hdrBytes)
// write length
err = binary.Write(p.wr, binary.LittleEndian, uint32(uint(len(p.blobs))*entrySize+crypto.Extension))
err = binary.Write(p.wr, binary.LittleEndian, uint32(restic.CiphertextLength(len(p.blobs)*int(entrySize))))
if err != nil {
return 0, errors.Wrap(err, "binary.Write")
}

View File

@ -54,10 +54,9 @@ func verifyBlobs(t testing.TB, bufs []Buf, k *crypto.Key, rd io.ReaderAt, packSi
}
// header length
written += binary.Size(uint32(0))
// header
written += len(bufs) * (binary.Size(restic.BlobType(0)) + binary.Size(uint32(0)) + len(restic.ID{}))
// header crypto
written += crypto.Extension
// header + header crypto
headerSize := len(bufs) * (binary.Size(restic.BlobType(0)) + binary.Size(uint32(0)) + len(restic.ID{}))
written += restic.CiphertextLength(headerSize)
// check length
Equals(t, uint(written), packSize)

View File

@ -10,7 +10,6 @@ import (
"restic/errors"
"restic/crypto"
"restic/debug"
)
@ -177,15 +176,15 @@ func (idx *Index) Has(id restic.ID, tpe restic.BlobType) bool {
return false
}
// LookupSize returns the length of the cleartext content behind the
// given id
func (idx *Index) LookupSize(id restic.ID, tpe restic.BlobType) (cleartextLength uint, err error) {
// LookupSize returns the length of the plaintext content of the blob with the
// given id.
func (idx *Index) LookupSize(id restic.ID, tpe restic.BlobType) (plaintextLength uint, err error) {
blobs, err := idx.Lookup(id, tpe)
if err != nil {
return 0, err
}
return blobs[0].Length - crypto.Extension, nil
return uint(restic.PlaintextLength(int(blobs[0].Length))), nil
}
// Supersedes returns the list of indexes this index supersedes, if any.

View File

@ -213,7 +213,7 @@ func (r *Repository) SaveJSONUnpacked(t restic.FileType, item interface{}) (rest
// SaveUnpacked encrypts data and stores it in the backend. Returned is the
// storage hash.
func (r *Repository) SaveUnpacked(t restic.FileType, p []byte) (id restic.ID, err error) {
ciphertext := make([]byte, len(p)+crypto.Extension)
ciphertext := restic.NewBlobBuffer(len(p))
ciphertext, err = r.Encrypt(ciphertext, p)
if err != nil {
return restic.ID{}, err
@ -528,8 +528,8 @@ func (r *Repository) LoadBlob(t restic.BlobType, id restic.ID, buf []byte) (int,
}
buf = buf[:cap(buf)]
if len(buf) < int(size)+crypto.Extension {
return 0, errors.Errorf("buffer is too small for data blob (%d < %d)", len(buf), size+crypto.Extension)
if len(buf) < restic.CiphertextLength(int(size)) {
return 0, errors.Errorf("buffer is too small for data blob (%d < %d)", len(buf), restic.CiphertextLength(int(size)))
}
n, err := r.loadBlob(id, t, buf)
@ -563,7 +563,7 @@ func (r *Repository) LoadTree(id restic.ID) (*restic.Tree, error) {
}
debug.Log("size is %d, create buffer", size)
buf := make([]byte, size+crypto.Extension)
buf := restic.NewBlobBuffer(int(size))
n, err := r.loadBlob(id, restic.TreeBlob, buf)
if err != nil {

View File

@ -11,7 +11,6 @@ import (
"restic"
"restic/archiver"
"restic/crypto"
"restic/repository"
. "restic/test"
)
@ -41,7 +40,7 @@ func TestSave(t *testing.T) {
// OK(t, repo.SaveIndex())
// read back
buf := make([]byte, size, size+crypto.Extension)
buf := restic.NewBlobBuffer(size)
n, err := repo.LoadBlob(restic.DataBlob, id, buf)
OK(t, err)
Equals(t, len(buf), n)
@ -75,7 +74,7 @@ func TestSaveFrom(t *testing.T) {
OK(t, repo.Flush())
// read back
buf := make([]byte, size, size+crypto.Extension)
buf := restic.NewBlobBuffer(size)
n, err := repo.LoadBlob(restic.DataBlob, id, buf)
OK(t, err)
Equals(t, len(buf), n)
@ -153,7 +152,7 @@ func BenchmarkLoadBlob(b *testing.B) {
defer cleanup()
length := 1000000
buf := make([]byte, length, length+crypto.Extension)
buf := restic.NewBlobBuffer(length)
_, err := io.ReadFull(rnd, buf)
OK(b, err)