From 71f78f0d6213f75e1f14b31d2d9aa4d4b63da41e Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Thu, 9 Jan 2014 10:59:09 +0100 Subject: [PATCH] Future proofing: handle file records with unknown flags --- model/model.go | 39 ++++++++++++++++++++++----------------- model/model_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/model/model.go b/model/model.go index a70f0635..d23949c1 100644 --- a/model/model.go +++ b/model/model.go @@ -225,17 +225,11 @@ func (m *Model) Index(nodeID string, fs []protocol.FileInfo) { log.Printf("NET IDX(in): %s: %d files", nodeID, len(fs)) } - m.remote[nodeID] = make(map[string]File) + repo := make(map[string]File) for _, f := range fs { - m.remote[nodeID][f.Name] = fileFromFileInfo(f) - if m.trace["idx"] { - var flagComment string - if f.Flags&protocol.FlagDeleted != 0 { - flagComment = " (deleted)" - } - log.Printf("IDX(in): %q m=%d f=%o%s v=%d (%d blocks)", f.Name, f.Modified, f.Flags, flagComment, f.Version, len(f.Blocks)) - } + m.indexUpdate(repo, f) } + m.remote[nodeID] = repo m.recomputeGlobal() m.recomputeNeed() @@ -253,24 +247,35 @@ func (m *Model) IndexUpdate(nodeID string, fs []protocol.FileInfo) { repo, ok := m.remote[nodeID] if !ok { + log.Printf("WARNING: Index update from node %s that does not have an index", nodeID) return } for _, f := range fs { - repo[f.Name] = fileFromFileInfo(f) - if m.trace["idx"] { - var flagComment string - if f.Flags&protocol.FlagDeleted != 0 { - flagComment = " (deleted)" - } - log.Printf("IDX(in-up): %q m=%d f=%o%s v=%d (%d blocks)", f.Name, f.Modified, f.Flags, flagComment, f.Version, len(f.Blocks)) - } + m.indexUpdate(repo, f) } m.recomputeGlobal() m.recomputeNeed() } +func (m *Model) indexUpdate(repo map[string]File, f protocol.FileInfo) { + if m.trace["idx"] { + var flagComment string + if f.Flags&protocol.FlagDeleted != 0 { + flagComment = " (deleted)" + } + log.Printf("IDX(in): %q m=%d f=%o%s v=%d (%d blocks)", f.Name, f.Modified, f.Flags, flagComment, f.Version, len(f.Blocks)) + } + + if extraFlags := f.Flags &^ (protocol.FlagInvalid | protocol.FlagDeleted | 0xfff); extraFlags != 0 { + log.Printf("WARNING: IDX(in): Unknown flags 0x%x in index record %+v", extraFlags, f) + return + } + + repo[f.Name] = fileFromFileInfo(f) +} + // Close removes the peer from the model and closes the underlyign connection if possible. // Implements the protocol.Model interface. func (m *Model) Close(node string, err error) { diff --git a/model/model_test.go b/model/model_test.go index 4ee1dd09..cb2cae83 100644 --- a/model/model_test.go +++ b/model/model_test.go @@ -377,3 +377,32 @@ func TestSuppression(t *testing.T) { } } } + +func TestIgnoreWithUnknownFlags(t *testing.T) { + m := NewModel("testdata") + fs, _ := m.Walk(false) + m.ReplaceLocal(fs) + + valid := protocol.FileInfo{ + Name: "valid", + Modified: time.Now().Unix(), + Blocks: []protocol.BlockInfo{{100, []byte("some hash bytes")}}, + Flags: protocol.FlagDeleted | 0755, + } + + invalid := protocol.FileInfo{ + Name: "invalid", + Modified: time.Now().Unix(), + Blocks: []protocol.BlockInfo{{100, []byte("some hash bytes")}}, + Flags: 1<<27 | protocol.FlagDeleted | 0755, + } + + m.Index("42", []protocol.FileInfo{valid, invalid}) + + if _, ok := m.global[valid.Name]; !ok { + t.Error("Model should include", valid) + } + if _, ok := m.global[invalid.Name]; ok { + t.Error("Model not should include", invalid) + } +}