lib/db: Don't put truncated files (ref #6855, ref #6501) (#6888)

This commit is contained in:
Simon Frei
2020-08-18 09:20:12 +02:00
committed by GitHub
parent 9c2117f08e
commit 8f5215878b
5 changed files with 158 additions and 25 deletions
+72 -2
View File
@@ -306,6 +306,7 @@ func TestRepairSequence(t *testing.T) {
{Name: "missing", Blocks: genBlocks(3)},
{Name: "overwriting", Blocks: genBlocks(4)},
{Name: "inconsistent", Blocks: genBlocks(5)},
{Name: "inconsistentNotIndirected", Blocks: genBlocks(2)},
}
for i, f := range files {
files[i].Version = f.Version.Update(short)
@@ -322,7 +323,7 @@ func TestRepairSequence(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if err := trans.putFile(dk, f, false); err != nil {
if err := trans.putFile(dk, f); err != nil {
t.Fatal(err)
}
sk, err := trans.keyer.GenerateSequenceKey(nil, folder, seq)
@@ -367,10 +368,13 @@ func TestRepairSequence(t *testing.T) {
files[3].Sequence = seq
addFile(files[3], seq)
// Inconistent file
// Inconistent files
seq++
files[4].Sequence = 101
addFile(files[4], seq)
seq++
files[5].Sequence = 102
addFile(files[5], seq)
// And a sequence entry pointing at nothing because why not
sk, err = trans.keyer.GenerateSequenceKey(nil, folder, 100001)
@@ -725,6 +729,72 @@ func TestGCIndirect(t *testing.T) {
}
}
func TestUpdateTo14(t *testing.T) {
db := NewLowlevel(backend.OpenMemory())
defer db.Close()
folderStr := "default"
folder := []byte(folderStr)
name := []byte("foo")
file := protocol.FileInfo{Name: string(name), Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(blocksIndirectionCutoff - 1)}
file.BlocksHash = protocol.BlocksHash(file.Blocks)
fileWOBlocks := file
fileWOBlocks.Blocks = nil
meta := db.loadMetadataTracker(folderStr)
// Initally add the correct file the usual way, all good here.
if err := db.updateLocalFiles(folder, []protocol.FileInfo{file}, meta); err != nil {
t.Fatal(err)
}
// Simulate the previous bug, where .putFile could write a file info without
// blocks, even though the file has them (and thus a non-nil BlocksHash).
trans, err := db.newReadWriteTransaction()
if err != nil {
t.Fatal(err)
}
defer trans.close()
key, err := db.keyer.GenerateDeviceFileKey(nil, folder, protocol.LocalDeviceID[:], name)
if err != nil {
t.Fatal(err)
}
fiBs := mustMarshal(&fileWOBlocks)
if err := trans.Put(key, fiBs); err != nil {
t.Fatal(err)
}
if err := trans.Commit(); err != nil {
t.Fatal(err)
}
trans.close()
// Run migration, pretending were still on schema 13.
if err := (&schemaUpdater{db}).updateSchemaTo14(13); err != nil {
t.Fatal(err)
}
// checks
ro, err := db.newReadOnlyTransaction()
if err != nil {
t.Fatal(err)
}
defer ro.close()
if f, ok, err := ro.getFileByKey(key); err != nil {
t.Fatal(err)
} else if !ok {
t.Error("file missing")
} else if !f.MustRescan() {
t.Error("file not marked as MustRescan")
}
if vl, err := ro.getGlobalVersions(nil, folder, name); err != nil {
t.Fatal(err)
} else if fv, ok := vl.GetGlobal(); !ok {
t.Error("missing global")
} else if !fv.IsInvalid() {
t.Error("global not marked as invalid")
}
}
func numBlockLists(db *Lowlevel) (int, error) {
it, err := db.Backend.NewPrefixIterator([]byte{KeyTypeBlockList})
if err != nil {