fix(ec): detect truncated .ecx instead of treating it as clean EOF (#10217)

This commit is contained in:
qzhello
2026-07-03 11:18:46 -07:00
committed by GitHub
parent 2480c2521a
commit 1d8a6e832c
2 changed files with 23 additions and 6 deletions
+7 -6
View File
@@ -150,12 +150,13 @@ func iterateEcxFile(baseFileName string, processNeedleFn func(key types.NeedleId
buf := make([]byte, types.NeedleMapEntrySize)
for {
n, err := ecxFile.Read(buf)
if n != types.NeedleMapEntrySize {
if err == io.EOF {
return nil
}
return err
// .ecx is a sealed index: a partial trailing record means corruption, not a torn append.
_, err := io.ReadFull(ecxFile, buf)
if err == io.EOF {
return nil
}
if err != nil {
return fmt.Errorf("read ecx %s.ecx: %w", baseFileName, err)
}
key, offset, size := idx.IdxFileEntry(buf)
if processNeedleFn != nil {
@@ -73,6 +73,22 @@ func TestHasLiveNeedles_EmptyFileIsFalse(t *testing.T) {
}
}
func TestHasLiveNeedles_TruncatedEcxErrors(t *testing.T) {
dir := t.TempDir()
base := filepath.Join(dir, "foo_1")
entry := makeNeedleMapEntry(types.NeedleId(1), types.Offset{}, types.TombstoneFileSize)
truncated := append(entry, entry[:types.NeedleIdSize]...)
if err := os.WriteFile(base+".ecx", truncated, 0644); err != nil {
t.Fatalf("write ecx: %v", err)
}
if _, err := erasure_coding.HasLiveNeedles(base); err == nil {
t.Fatalf("expected error for truncated ecx")
}
}
func makeNeedleMapEntry(key types.NeedleId, offset types.Offset, size types.Size) []byte {
b := make([]byte, types.NeedleIdSize+types.OffsetSize+types.SizeSize)
types.NeedleIdToBytes(b[0:types.NeedleIdSize], key)