Skip to content

Commit 985efe8

Browse files
committed
fixup! RebaseArchiveEntries: fix archive path rebasing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent bf0959f commit 985efe8

2 files changed

Lines changed: 43 additions & 13 deletions

File tree

copy.go

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -317,26 +317,35 @@ func PrepareArchiveCopy(srcContent io.Reader, srcInfo, dstInfo CopyInfo) (dstDir
317317
}
318318

319319
// rebaseName replaces oldBase with newBase at the beginning of a POSIX-style
320-
// archive entry name. oldBase and newBase must use forward slashes. It preserves
321-
// the remainder of the name verbatim and does not clean or canonicalize paths.
320+
// archive entry name. oldBase and newBase must use forward slashes. When
321+
// rebasing from the archive root, it removes all leading slashes from the name.
322+
// It otherwise preserves the remainder verbatim and does not clean or
323+
// canonicalize paths.
322324
func rebaseName(name, oldBase, newBase string) string {
325+
var remainder string
326+
323327
if oldBase == "/" {
324-
name = strings.TrimPrefix(name, "/")
325-
if newBase == "" {
328+
remainder = strings.TrimLeft(name, "/")
329+
} else {
330+
oldBase = strings.TrimSuffix(oldBase, "/")
331+
switch {
332+
case name == oldBase:
333+
remainder = ""
334+
case strings.HasPrefix(name, oldBase+"/"):
335+
remainder = strings.TrimPrefix(name, oldBase+"/")
336+
default:
326337
return name
327338
}
328-
329-
// Do not use path.Join; it would clean the archive entry name.
330-
return strings.TrimSuffix(newBase, "/") + "/" + name
331339
}
332340

333-
oldBase = strings.TrimSuffix(oldBase, "/")
334-
suffix, ok := strings.CutPrefix(name, oldBase)
335-
if !ok || suffix != "" && !strings.HasPrefix(suffix, "/") {
336-
return name
341+
newBase = strings.TrimSuffix(newBase, "/")
342+
if newBase == "" {
343+
return remainder
337344
}
338-
339-
return strings.TrimSuffix(newBase, "/") + suffix
345+
if remainder == "" {
346+
return newBase
347+
}
348+
return newBase + "/" + remainder
340349
}
341350

342351
// RebaseArchiveEntries rewrites the given srcContent archive replacing

copy_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@ func TestRebaseArchiveEntriesPlatformPaths(t *testing.T) {
3434
headerName: "/foo/bar",
3535
wantName: "prefix/foo/bar",
3636
},
37+
{
38+
name: "rebase name with multiple leading slashes from root",
39+
oldBase: "/",
40+
newBase: "prefix",
41+
headerName: "///foo/bar",
42+
wantName: "prefix/foo/bar",
43+
},
44+
{
45+
name: "rebase absolute name from root to empty",
46+
oldBase: "/",
47+
newBase: "",
48+
headerName: "/foo/bar",
49+
wantName: "foo/bar",
50+
},
3751
{
3852
name: "rebase absolute name from root to empty",
3953
oldBase: "/",
@@ -82,6 +96,13 @@ func TestRebaseArchiveEntriesPlatformPaths(t *testing.T) {
8296
headerName: "foo/../bar",
8397
wantName: "prefix/foo/../bar",
8498
},
99+
{
100+
name: "do not rebase partial path component match",
101+
oldBase: "foo",
102+
newBase: "prefix",
103+
headerName: "foobar/baz",
104+
wantName: "foobar/baz",
105+
},
85106
{
86107
name: "hardlink",
87108
oldBase: filepath.Join("origin", "subdir"),

0 commit comments

Comments
 (0)