@@ -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.
322324func 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
0 commit comments