diff --git a/integration_tests/resume_test.sh b/integration_tests/resume_test.sh index 4924bd2..4989300 100755 --- a/integration_tests/resume_test.sh +++ b/integration_tests/resume_test.sh @@ -8,7 +8,7 @@ fixture pushd ${TEST_REPO} ${DUPLICACY} init integration-tests $TEST_STORAGE -c 4 -# Create 10 20 files +# Create 10 small files add_file file1 20 add_file file2 20 add_file file3 20 @@ -25,6 +25,8 @@ env DUPLICACY_FAIL_CHUNK=10 ${DUPLICACY} backup # Try it again to test the multiple-resume case env DUPLICACY_FAIL_CHUNK=5 ${DUPLICACY} backup +add_file file1 20 +add_file file2 20 # Fail the backup before uploading the snapshot env DUPLICACY_FAIL_SNAPSHOT=true ${DUPLICACY} backup diff --git a/src/duplicacy_chunk.go b/src/duplicacy_chunk.go index 5b1644f..2bbb072 100644 --- a/src/duplicacy_chunk.go +++ b/src/duplicacy_chunk.go @@ -154,6 +154,18 @@ func (chunk *Chunk) GetID() string { return chunk.id } +func (chunk *Chunk) VerifyID() { + hasher := chunk.config.NewKeyedHasher(chunk.config.HashKey) + hasher.Write(chunk.buffer.Bytes()) + hash := hasher.Sum(nil) + hasher = chunk.config.NewKeyedHasher(chunk.config.IDKey) + hasher.Write([]byte(hash)) + chunkID := hex.EncodeToString(hasher.Sum(nil)) + if chunkID != chunk.GetID() { + LOG_ERROR("CHUNK_ID", "The chunk id should be %s instead of %s, length: %d", chunkID, chunk.GetID(), len(chunk.buffer.Bytes())) + } +} + // Encrypt encrypts the plain data stored in the chunk buffer. If derivationKey is not nil, the actual // encryption key will be HMAC-SHA256(encryptionKey, derivationKey). func (chunk *Chunk) Encrypt(encryptionKey []byte, derivationKey string) (err error) { diff --git a/src/duplicacy_chunkuploader.go b/src/duplicacy_chunkuploader.go index 8aafc85..7373017 100644 --- a/src/duplicacy_chunkuploader.go +++ b/src/duplicacy_chunkuploader.go @@ -92,6 +92,11 @@ func (uploader *ChunkUploader) Upload(threadIndex int, task ChunkUploadTask) boo chunkSize := chunk.GetLength() chunkID := chunk.GetID() + // For a snapshot chunk, verify that its chunk id is correct + if uploader.snapshotCache != nil { + chunk.VerifyID() + } + if uploader.snapshotCache != nil && uploader.storage.IsCacheNeeded() { // Save a copy to the local snapshot. chunkPath, exist, _, err := uploader.snapshotCache.FindChunk(threadIndex, chunkID, false)