diff --git a/table/table.go b/table/table.go index cd6d86dc2..f671333db 100644 --- a/table/table.go +++ b/table/table.go @@ -553,7 +553,7 @@ func (t *Table) block(idx int, useCache bool) (*Block, error) { if blk.data, err = t.read(blk.offset, int(ko.Len())); err != nil { return nil, y.Wrapf(err, "failed to read from file: %s at offset: %d, len: %d", - t.Fd.Name(), blk.offset, ko.Len()) + t.Filename(), blk.offset, ko.Len()) } if t.shouldDecrypt() { @@ -568,7 +568,7 @@ func (t *Table) block(idx int, useCache bool) (*Block, error) { if err = t.decompress(blk); err != nil { return nil, y.Wrapf(err, "failed to decode compressed data in file: %s at offset: %d, len: %d", - t.Fd.Name(), blk.offset, ko.Len()) + t.Filename(), blk.offset, ko.Len()) } // Read meta data related to block. @@ -659,7 +659,12 @@ func (t *Table) Smallest() []byte { return t.smallest } func (t *Table) Biggest() []byte { return t.biggest } // Filename is NOT the file name. Just kidding, it is. -func (t *Table) Filename() string { return t.Fd.Name() } +func (t *Table) Filename() string { + if t.Fd == nil { + return IDToFilename(t.id) + } + return t.Fd.Name() +} // ID is the table's ID number (used to make the file name). func (t *Table) ID() uint64 { return t.id } diff --git a/table/table_test.go b/table/table_test.go index 18a950323..3d9a235e0 100644 --- a/table/table_test.go +++ b/table/table_test.go @@ -24,6 +24,7 @@ import ( "github.com/dgraph-io/badger/v4/options" "github.com/dgraph-io/badger/v4/y" "github.com/dgraph-io/ristretto/v2" + "github.com/dgraph-io/ristretto/v2/z" ) func key(prefix string, i int) string { @@ -896,3 +897,39 @@ func TestMaxVersion(t *testing.T) { require.NoError(t, err) require.Equal(t, N, int(table.MaxVersion())) } + +func TestInMemoryTableBlockErrorNoPanic(t *testing.T) { + opts := getTestTableOptions() + src := buildTestTable(t, "key", 500, opts) + + data := make([]byte, len(src.Data)) + copy(data, src.Data) + srcID := src.ID() + require.NoError(t, src.DecrRef()) + + tbl, err := OpenInMemoryTable(data, srcID, &opts) + require.NoError(t, err) + defer func() { require.NoError(t, tbl.DecrRef()) }() + + corruptEnd := tbl.indexStart + if corruptEnd > 256 { + corruptEnd = 256 + } + for i := 0; i < corruptEnd; i++ { + data[i] = 0xFF + } + + require.NotPanics(t, func() { + _, err = tbl.block(0, false) + }) + require.Error(t, err) +} + +func TestInMemoryTableFilename(t *testing.T) { + tbl := &Table{ + MmapFile: &z.MmapFile{Data: []byte{}, Fd: nil}, + id: 777, + opt: &Options{}, + } + require.Equal(t, IDToFilename(777), tbl.Filename()) +}