Merge pull request #167 from thaJeztah/18.09_backport_cp_longname

[18.09 backport] pkg/archive:CopyTo(): fix for long dest filename
Upstream-commit: 2f867e6b4cbdb9844d7b6548c9b341b1e8452f33
Component: engine
This commit is contained in:
Andrew Hsu
2019-03-06 08:07:18 -08:00
committed by GitHub
2 changed files with 32 additions and 0 deletions
+8
View File
@@ -336,6 +336,14 @@ func RebaseArchiveEntries(srcContent io.Reader, oldBase, newBase string) io.Read
return
}
// srcContent tar stream, as served by TarWithOptions(), is
// definitely in PAX format, but tar.Next() mistakenly guesses it
// as USTAR, which creates a problem: if the newBase is >100
// characters long, WriteHeader() returns an error like
// "archive/tar: cannot encode header: Format specifies USTAR; and USTAR cannot encode Name=...".
//
// To fix, set the format to PAX here. See docker/for-linux issue #484.
hdr.Format = tar.FormatPAX
hdr.Name = strings.Replace(hdr.Name, oldBase, newBase, 1)
if hdr.Typeflag == tar.TypeLink {
hdr.Linkname = strings.Replace(hdr.Linkname, oldBase, newBase, 1)
@@ -257,6 +257,30 @@ func TestCopyErrDstNotDir(t *testing.T) {
}
}
// Test to check if CopyTo works with a long (>100 characters) destination file name.
// This is a regression (see https://github.com/docker/for-linux/issues/484).
func TestCopyLongDstFilename(t *testing.T) {
const longName = "a_very_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_long_filename_that_is_101_characters"
tmpDirA, tmpDirB := getTestTempDirs(t)
defer removeAllPaths(tmpDirA, tmpDirB)
// Load A with some sample files and directories.
createSampleDir(t, tmpDirA)
srcInfo := CopyInfo{Path: filepath.Join(tmpDirA, "file1"), Exists: true, IsDir: false}
content, err := TarResource(srcInfo)
if err != nil {
t.Fatalf("unexpected error %T: %s", err, err)
}
defer content.Close()
err = CopyTo(content, srcInfo, filepath.Join(tmpDirB, longName))
if err != nil {
t.Fatalf("unexpected error %T: %s", err, err)
}
}
// Possibilities are reduced to the remaining 10 cases:
//
// case | srcIsDir | onlyDirContents | dstExists | dstIsDir | dstTrSep | action