diff --git a/physical/file/file.go b/physical/file/file.go index b02efc78c..f7f51928a 100644 --- a/physical/file/file.go +++ b/physical/file/file.go @@ -247,10 +247,16 @@ func (b *FileBackend) ListInternal(prefix string) ([]string, error) { } for i, name := range names { - if name[0] == '_' { - names[i] = name[1:] - } else { + fi, err := os.Stat(filepath.Join(path, name)) + if err != nil { + return nil, err + } + if fi.IsDir() { names[i] = name + "/" + } else { + if name[0] == '_' { + names[i] = name[1:] + } } } diff --git a/physical/file/file_test.go b/physical/file/file_test.go index 6438e213c..da9b6de0e 100644 --- a/physical/file/file_test.go +++ b/physical/file/file_test.go @@ -173,5 +173,66 @@ func TestFileBackend(t *testing.T) { } physical.ExerciseBackend(t, b) + + // Underscores should not trip things up; ref GH-3476 + e := &physical.Entry{Key: "_zip", Value: []byte("foobar")} + err = b.Put(e) + if err != nil { + t.Fatalf("err: %v", err) + } + e = &physical.Entry{Key: "_zip/_zap", Value: []byte("boofar")} + err = b.Put(e) + if err != nil { + t.Fatalf("err: %v", err) + } + e, err = b.Get("_zip/_zap") + if err != nil { + t.Fatalf("err: %v", err) + } + if e == nil { + t.Fatal("got nil entry") + } + vals, err := b.List("") + if err != nil { + t.Fatal(err) + } + if len(vals) != 2 || vals[0] == vals[1] { + t.Fatalf("bad: %v", vals) + } + for _, val := range vals { + if val != "_zip/" && val != "_zip" { + t.Fatalf("bad val: %v", val) + } + } + vals, err = b.List("_zip/") + if err != nil { + t.Fatal(err) + } + if len(vals) != 1 || vals[0] != "_zap" { + t.Fatalf("bad: %v", vals) + } + err = b.Delete("_zip/_zap") + if err != nil { + t.Fatal(err) + } + vals, err = b.List("") + if err != nil { + t.Fatal(err) + } + if len(vals) != 1 || vals[0] != "_zip" { + t.Fatalf("bad: %v", vals) + } + err = b.Delete("_zip") + if err != nil { + t.Fatal(err) + } + vals, err = b.List("") + if err != nil { + t.Fatal(err) + } + if len(vals) != 0 { + t.Fatalf("bad: %v", vals) + } + physical.ExerciseBackend_ListPrefix(t, b) }