فهرست منبع

Future proofing: handle file records with unknown flags

Jakob Borg 12 سال پیش
والد
کامیت
71f78f0d62
2فایلهای تغییر یافته به همراه51 افزوده شده و 17 حذف شده
  1. 22 17
      model/model.go
  2. 29 0
      model/model_test.go

+ 22 - 17
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) {

+ 29 - 0
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)
+	}
+}