From 221b6361e1782acb258afc37f4a8642ac333e301 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sat, 22 Jun 2024 21:33:51 +0200 Subject: [PATCH] Don't discard the drive letter when joining with an absolute path When encountering a symlink that contains an absolute target without a drive letter, assume the target resides on the same drive. --- pkg/filesystem/path/builder.go | 7 ++++--- pkg/filesystem/path/builder_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/pkg/filesystem/path/builder.go b/pkg/filesystem/path/builder.go index 84adfa58..7784426f 100644 --- a/pkg/filesystem/path/builder.go +++ b/pkg/filesystem/path/builder.go @@ -189,9 +189,10 @@ func (w *buildingScopeWalker) OnAbsolute() (ComponentWalker, error) { return nil, err } *w.b = Builder{ - absolute: true, - components: w.b.components[:0], - suffix: "/", + absolute: true, + driveLetter: w.b.driveLetter, + components: w.b.components[:0], + suffix: "/", } return w.b.getComponentWalker(componentWalker), nil } diff --git a/pkg/filesystem/path/builder_test.go b/pkg/filesystem/path/builder_test.go index 7ba58ca0..d976f70d 100644 --- a/pkg/filesystem/path/builder_test.go +++ b/pkg/filesystem/path/builder_test.go @@ -325,4 +325,28 @@ func TestBuilder(t *testing.T) { require.NoError(t, path.Resolve(path.NewUNIXParser(".."), s2)) require.Equal(t, "/hello/..", builder2.GetUNIXString()) }) + + // When encountering a symlink target that is an absolute path + // without a drive letter, we should assume the path resolves to + // a location on the same drive. + t.Run("DriveLetterWithAbsoluteSymlink", func(t *testing.T) { + scopeWalker1 := mock.NewMockScopeWalker(ctrl) + componentWalker1 := mock.NewMockComponentWalker(ctrl) + scopeWalker1.EXPECT().OnDriveLetter('C').Return(componentWalker1, nil) + scopeWalker2 := mock.NewMockScopeWalker(ctrl) + componentWalker1.EXPECT().OnTerminal(path.MustNewComponent("hello")).Return( + &path.GotSymlink{ + Parent: scopeWalker2, + Target: path.NewWindowsParser("\\world"), + }, + nil, + ) + componentWalker2 := mock.NewMockComponentWalker(ctrl) + scopeWalker2.EXPECT().OnAbsolute().Return(componentWalker2, nil) + componentWalker2.EXPECT().OnTerminal(path.MustNewComponent("world")) + + builder1, s1 := path.EmptyBuilder.Join(scopeWalker1) + require.NoError(t, path.Resolve(path.NewWindowsParser("C:\\hello"), s1)) + require.Equal(t, "C:\\world", mustGetWindowsString(builder1)) + }) }