Skip to content

Commit

Permalink
Create NewLocalDirectory with path.Parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Nils Wireklint authored and Nils Wireklint committed Jun 17, 2024
1 parent e920afa commit 829d800
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 31 deletions.
1 change: 1 addition & 0 deletions pkg/blobstore/configuration/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ go_library(
"//pkg/digest",
"//pkg/eviction",
"//pkg/filesystem",
"//pkg/filesystem/path",
"//pkg/grpc",
"//pkg/http",
"//pkg/program",
Expand Down
7 changes: 6 additions & 1 deletion pkg/blobstore/configuration/new_blob_access.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/buildbarn/bb-storage/pkg/digest"
"github.com/buildbarn/bb-storage/pkg/eviction"
"github.com/buildbarn/bb-storage/pkg/filesystem"
"github.com/buildbarn/bb-storage/pkg/filesystem/path"
"github.com/buildbarn/bb-storage/pkg/grpc"
"github.com/buildbarn/bb-storage/pkg/program"
pb "github.com/buildbarn/bb-storage/pkg/proto/configuration/blobstore"
Expand Down Expand Up @@ -217,7 +218,11 @@ func (nc *simpleNestedBlobAccessCreator) newNestedBlobAccessBare(configuration *
} else {
// Persistency is enabled. Reload previous
// persistent state from disk.
persistentStateDirectory, err := filesystem.NewLocalDirectory(persistent.StateDirectoryPath)
parser, err := path.NewLocalParser(persistent.StateDirectoryPath)
if err != nil {
return BlobAccessInfo{}, "", util.StatusWrapf(err, "Failed to parse persistent state directory path %#v", persistent.StateDirectoryPath)
}
persistentStateDirectory, err := filesystem.NewLocalDirectory(parser)
if err != nil {
return BlobAccessInfo{}, "", util.StatusWrapf(err, "Failed to open persistent state directory %#v", persistent.StateDirectoryPath)
}
Expand Down
8 changes: 6 additions & 2 deletions pkg/filesystem/local_directory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ import (
)

func openTmpDir(t *testing.T) filesystem.DirectoryCloser {
d, err := filesystem.NewLocalDirectory(t.TempDir())
parser, err := path.NewLocalParser(t.TempDir())
require.NoError(t, err)
d, err := filesystem.NewLocalDirectory(parser)
require.NoError(t, err)
return d
}

func TestLocalDirectoryCreationFailure(t *testing.T) {
_, err := filesystem.NewLocalDirectory("/nonexistent")
parser, err := path.NewLocalParser("/nonexistent")
require.NoError(t, err)
_, err = filesystem.NewLocalDirectory(parser)
require.True(t, os.IsNotExist(err))
}

Expand Down
13 changes: 11 additions & 2 deletions pkg/filesystem/local_directory_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,17 @@ func newLocalDirectoryFromFileDescriptor(fd int) (*localDirectory, error) {

// NewLocalDirectory creates a directory handle that corresponds to a
// local path on the system.
func NewLocalDirectory(path string) (DirectoryCloser, error) {
fd, err := unix.Openat(unix.AT_FDCWD, path, unix.O_DIRECTORY|unix.O_NOFOLLOW|unix.O_RDONLY, 0)
func NewLocalDirectory(directoryParser path.Parser) (DirectoryCloser, error) {
directoryPath, scopeWalker := path.EmptyBuilder.Join(path.VoidScopeWalker)
if err := path.Resolve(directoryParser, scopeWalker); err != nil {
return nil, util.StatusWrap(err, "Failed to resolve directory")
}
pathString, err := path.GetLocalString(directoryPath)
if err != nil {
return nil, util.StatusWrap(err, "Failed to create local representation of build directory")
}

fd, err := unix.Openat(unix.AT_FDCWD, pathString, unix.O_DIRECTORY|unix.O_NOFOLLOW|unix.O_RDONLY, 0)
if err != nil {
return nil, err
}
Expand Down
12 changes: 10 additions & 2 deletions pkg/filesystem/local_directory_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,16 @@ func newLocalDirectory(absPath string, openReparsePoint bool) (DirectoryCloser,
return newLocalDirectoryFromHandle(handle)
}

func NewLocalDirectory(path string) (DirectoryCloser, error) {
absPath := "\\??\\" + path
func NewLocalDirectory(directoryParser path.Parser) (DirectoryCloser, error) {
directoryPath, scopeWalker := path.EmptyBuilder.Join(path.VoidScopeWalker)
if err := path.Resolve(directoryParser, scopeWalker); err != nil {
return nil, util.StatusWrap(err, "Failed to resolve directory")
}
pathString, err := path.GetLocalString(directoryPath)
if err != nil {
return nil, util.StatusWrap(err, "Failed to create local representation of build directory")
}
absPath := "\\??\\" + pathString
return newLocalDirectory(absPath, true)
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/filesystem/path/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ var EmptyBuilder = Builder{
// Builder that use this path as their starting point can be created by
// calling RootBuilder.Join().
var RootBuilder = Builder{
absolute: true,
suffix: "/",
absolute: true,
suffix: "/",
}

// NewDriveLetterBuilder returns a builder rooted at a Windows drive.
Expand Down Expand Up @@ -99,7 +99,7 @@ func (b *Builder) GetWindowsString() (string, error) {
if byte(c) < 31 {
return "", status.Errorf(codes.InvalidArgument, "Path component contains a control character %#v.", component)
}
for _, forbidden := range []rune {
for _, forbidden := range []rune{
'<',
'>',
':',
Expand Down
32 changes: 16 additions & 16 deletions pkg/filesystem/path/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ func TestBuilder(t *testing.T) {

t.Run("WindowsParseUNIXPaths", func(t *testing.T) {
for _, data := range [][]string{
{".", "."},
{"..", ".."},
{"/", "\\"},
{"hello", "hello"},
{"hello/", "hello\\"},
{"hello/..", "hello\\.."},
{"/hello/", "\\hello\\"},
{"/hello/..", "\\hello\\.."},
{"/hello/../world", "\\hello\\..\\world"},
{"/hello/../world/", "\\hello\\..\\world\\"},
{".", "."},
{"..", ".."},
{"/", "\\"},
{"hello", "hello"},
{"hello/", "hello\\"},
{"hello/..", "hello\\.."},
{"/hello/", "\\hello\\"},
{"/hello/..", "\\hello\\.."},
{"/hello/../world", "\\hello\\..\\world"},
{"/hello/../world/", "\\hello\\..\\world\\"},
{"/hello/../world/foo", "\\hello\\..\\world\\foo"},
} {
p := data[0]
Expand Down Expand Up @@ -102,12 +102,12 @@ func TestBuilder(t *testing.T) {

t.Run("WindowsParseAndWriteUNIXPaths", func(t *testing.T) {
for _, data := range [][]string{
{"C:\\", "/", },
{"C:\\hello\\", "/hello/", },
{"C:\\hello\\..", "/hello/..", },
{"C:\\hello\\..\\world", "/hello/../world", },
{"C:\\hello\\..\\world\\", "/hello/../world/", },
{"C:\\hello\\..\\world\\foo", "/hello/../world/foo", },
{"C:\\", "/"},
{"C:\\hello\\", "/hello/"},
{"C:\\hello\\..", "/hello/.."},
{"C:\\hello\\..\\world", "/hello/../world"},
{"C:\\hello\\..\\world\\", "/hello/../world/"},
{"C:\\hello\\..\\world\\foo", "/hello/../world/foo"},
} {
p := data[0]
expected := data[1]
Expand Down
2 changes: 1 addition & 1 deletion pkg/filesystem/path/unix_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (p unixParser) ParseScope(scopeWalker ScopeWalker) (next ComponentWalker, r
}

type relativeParser struct {
path string
path string
}

func (rp relativeParser) ParseFirstComponent(componentWalker ComponentWalker, mustBeDirectory bool) (next GotDirectoryOrSymlink, remainder RelativeParser, err error) {
Expand Down
7 changes: 3 additions & 4 deletions pkg/filesystem/path/windows_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ import (
)

type windowsParser struct {
path string
path string
}

type windowsRelativeParser struct {
path string
path string
}


// NewWindowsParser creates a Parser for Windows paths that can be used in Resolve.
func NewWindowsParser(path string) (Parser, error) {
// Windows paths are generally passed to system calls that
Expand Down Expand Up @@ -82,7 +81,7 @@ func (rp windowsRelativeParser) ParseFirstComponent(componentWalker ComponentWal
separator = slash
if backslash > 0 {
separator = backslash
if slash > 0 && backslash < slash{
if slash > 0 && backslash < slash {
separator = backslash
}
}
Expand Down

0 comments on commit 829d800

Please sign in to comment.