Skip to content

Commit

Permalink
*: switch to golang.org/x/sys/unix
Browse files Browse the repository at this point in the history
Go modules mean adding dependencies is less painful than it was when we
started this project, and we will need some syscalls from unix for
implementing a safe MkdirAll.

Signed-off-by: Aleksa Sarai <[email protected]>
  • Loading branch information
cyphar committed Jun 25, 2024
1 parent b04d326 commit 94c9f5b
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 14 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/cyphar/filepath-securejoin

go 1.13

require golang.org/x/sys v0.21.0 // indirect
7 changes: 4 additions & 3 deletions join.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import (
"os"
"path/filepath"
"strings"
"syscall"

"golang.org/x/sys/unix"

Check failure on line 19 in join.go

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 1.14)

found packages unix (affinity_linux.go) and main (mkasm.go) in /home/runner/go/pkg/mod/golang.org/x/[email protected]/unix

Check failure on line 19 in join.go

View workflow job for this annotation

GitHub Actions / test (windows-latest, 1.14)

found packages unix (aliases.go) and main (mkasm.go) in C:\Users\runneradmin\go\pkg\mod\golang.org\x\[email protected]\unix
)

const maxSymlinkLimit = 255
Expand All @@ -26,7 +27,7 @@ const maxSymlinkLimit = 255
func IsNotExist(err error) bool {
// Check that it's not actually an ENOTDIR, which in some cases is a more
// convoluted case of ENOENT (usually involving weird paths).
return errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) || errors.Is(err, syscall.ENOENT)
return errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.ENOTDIR) || errors.Is(err, unix.ENOENT)
}

// SecureJoinVFS joins the two given path components (similar to Join) except
Expand Down Expand Up @@ -97,7 +98,7 @@ func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) {
// to the yet-unparsed path.
linksWalked++
if linksWalked > maxSymlinkLimit {
return "", &os.PathError{Op: "SecureJoin", Path: root + string(filepath.Separator) + unsafePath, Err: syscall.ELOOP}
return "", &os.PathError{Op: "SecureJoin", Path: root + string(filepath.Separator) + unsafePath, Err: unix.ELOOP}
}

dest, err := vfs.Readlink(fullPath)
Expand Down
23 changes: 12 additions & 11 deletions join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import (
"os"
"path/filepath"
"runtime"
"syscall"
"testing"

"golang.org/x/sys/unix"
)

// TODO: These tests won't work on plan9 because it doesn't have symlinks, and
Expand Down Expand Up @@ -197,7 +198,7 @@ func TestSymlinkLoop(t *testing.T) {
{dir, "/self/././.."},
} {
got, err := SecureJoin(test.root, test.unsafe)
if !errors.Is(err, syscall.ELOOP) {
if !errors.Is(err, unix.ELOOP) {
t.Errorf("securejoin(%q, %q): expected ELOOP, got %q & %v", test.root, test.unsafe, got, err)
continue
}
Expand Down Expand Up @@ -241,15 +242,15 @@ func TestIsNotExist(t *testing.T) {
err error
expected bool
}{
{&os.PathError{Op: "test1", Err: syscall.ENOENT}, true},
{&os.LinkError{Op: "test1", Err: syscall.ENOENT}, true},
{&os.SyscallError{Syscall: "test1", Err: syscall.ENOENT}, true},
{&os.PathError{Op: "test2", Err: syscall.ENOTDIR}, true},
{&os.LinkError{Op: "test2", Err: syscall.ENOTDIR}, true},
{&os.SyscallError{Syscall: "test2", Err: syscall.ENOTDIR}, true},
{&os.PathError{Op: "test3", Err: syscall.EACCES}, false},
{&os.LinkError{Op: "test3", Err: syscall.EACCES}, false},
{&os.SyscallError{Syscall: "test3", Err: syscall.EACCES}, false},
{&os.PathError{Op: "test1", Err: unix.ENOENT}, true},
{&os.LinkError{Op: "test1", Err: unix.ENOENT}, true},
{&os.SyscallError{Syscall: "test1", Err: unix.ENOENT}, true},
{&os.PathError{Op: "test2", Err: unix.ENOTDIR}, true},
{&os.LinkError{Op: "test2", Err: unix.ENOTDIR}, true},
{&os.SyscallError{Syscall: "test2", Err: unix.ENOTDIR}, true},
{&os.PathError{Op: "test3", Err: unix.EACCES}, false},
{&os.LinkError{Op: "test3", Err: unix.EACCES}, false},
{&os.SyscallError{Syscall: "test3", Err: unix.EACCES}, false},
{errors.New("not a proper error"), false},
} {
got := IsNotExist(test.err)
Expand Down

0 comments on commit 94c9f5b

Please sign in to comment.