Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for Symlinks in all Tar decompressors #171

Merged
merged 1 commit into from
Mar 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions decompress_bzip2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func TestBzip2Decompressor(t *testing.T) {
false,
false,
nil,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
Expand All @@ -21,6 +22,7 @@ func TestBzip2Decompressor(t *testing.T) {
true,
true,
nil,
nil,
"",
nil,
},
Expand Down
2 changes: 2 additions & 0 deletions decompress_gzip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func TestGzipDecompressor(t *testing.T) {
false,
false,
nil,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
Expand All @@ -21,6 +22,7 @@ func TestGzipDecompressor(t *testing.T) {
true,
true,
nil,
nil,
"",
nil,
},
Expand Down
9 changes: 9 additions & 0 deletions decompress_tar.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ func untar(input io.Reader, dst, src string, dir bool) error {
path = filepath.Join(path, hdr.Name)
}

if hdr.Typeflag == tar.TypeSymlink {
// If the type is a symlink we re-write it and
// continue instead of attempting to copy the contents
if err := os.Symlink(hdr.Linkname, path); err != nil {
return fmt.Errorf("failed writing symbolic link: %s", err)
}
continue
}

if hdr.FileInfo().IsDir() {
if !dir {
return fmt.Errorf("expected a single file: %s", src)
Expand Down
12 changes: 12 additions & 0 deletions decompress_tar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func TestTar(t *testing.T) {
true,
false,
[]string{"directory/", "directory/a", "directory/b"},
nil,
"",
nil,
},
Expand All @@ -22,6 +23,7 @@ func TestTar(t *testing.T) {
true,
false,
[]string{"directory/", "directory/sub/", "directory/sub/a", "directory/sub/b"},
nil,
"",
nil,
},
Expand All @@ -30,6 +32,16 @@ func TestTar(t *testing.T) {
true,
false,
[]string{"directory/", "directory/sub/", "directory/sub/a", "directory/sub/b"},
nil,
"",
&mtime,
},
{
"with-symlinks.tar",
true,
false,
[]string{"baz", "foo"},
map[string]string{"bar": "baz"},
"",
&mtime,
},
Expand Down
6 changes: 6 additions & 0 deletions decompress_tbz2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func TestTarBzip2Decompressor(t *testing.T) {
false,
true,
nil,
nil,
"",
nil,
},
Expand All @@ -23,6 +24,7 @@ func TestTarBzip2Decompressor(t *testing.T) {
false,
false,
nil,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
Expand All @@ -32,6 +34,7 @@ func TestTarBzip2Decompressor(t *testing.T) {
true,
false,
[]string{"file"},
nil,
"",
nil,
},
Expand All @@ -41,6 +44,7 @@ func TestTarBzip2Decompressor(t *testing.T) {
true,
false,
[]string{"file1", "file2"},
nil,
"",
nil,
},
Expand All @@ -50,6 +54,7 @@ func TestTarBzip2Decompressor(t *testing.T) {
false,
true,
nil,
nil,
"",
nil,
},
Expand All @@ -60,6 +65,7 @@ func TestTarBzip2Decompressor(t *testing.T) {
true,
false,
orderingPaths,
nil,
"",
nil,
},
Expand Down
65 changes: 52 additions & 13 deletions decompress_testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ import (

// TestDecompressCase is a single test case for testing decompressors
type TestDecompressCase struct {
Input string // Input is the complete path to the input file
Dir bool // Dir is whether or not we're testing directory mode
Err bool // Err is whether we expect an error or not
DirList []string // DirList is the list of files for Dir mode
FileMD5 string // FileMD5 is the expected MD5 for a single file
Mtime *time.Time // Mtime is the optionally expected mtime for a single file (or all files if in Dir mode)
Input string // Input is the complete path to the input file
Dir bool // Dir is whether or not we're testing directory mode
Err bool // Err is whether we expect an error or not
DirList []string // DirList is the list of files for Dir mode
Symlinks map[string]string // Optional map of symlinks to test
FileMD5 string // FileMD5 is the expected MD5 for a single file
Mtime *time.Time // Mtime is the optionally expected mtime for a single file (or all files if in Dir mode)
}

// TestDecompressor is a helper function for testing generic decompressors.
Expand Down Expand Up @@ -97,11 +98,17 @@ func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) {

// Directory, check for the correct contents
actual := testListDir(t, dst)
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad %s\n\n%#v\n\n%#v", tc.Input, actual, expected)
if !reflect.DeepEqual(actual.files, expected) {
t.Fatalf("bad %s\n\n%#v\n\n%#v", tc.Input, actual.files, expected)
}

// Symlinks, check that symlinks match
if tc.Symlinks != nil && !reflect.DeepEqual(actual.symlinks, tc.Symlinks) {
t.Fatalf("bad %s\n\n%#v\n\n%#v", tc.Input, actual.symlinks, tc.Symlinks)
}

// Check for correct atime/mtime
for _, dir := range actual {
for _, dir := range actual.files {
path := filepath.Join(dst, dir)
if tc.Mtime != nil {
fi, err := os.Stat(path)
Expand All @@ -124,8 +131,32 @@ func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) {
}
}

func testListDir(t testing.T, path string) []string {
var result []string
type testResult struct {
files []string
symlinks map[string]string
}

func (tr *testResult) AddFile(name string) {
tr.files = append(tr.files, name)
}

func (tr *testResult) AddSymlink(name, link string) {
tr.symlinks[name] = link
}

func (tr *testResult) SortFiles() {
sort.Strings(tr.files)
}

func newTestResult() *testResult {
return &testResult{
files: make([]string, 0),
symlinks: make(map[string]string),
}
}

func testListDir(t testing.T, path string) *testResult {
result := newTestResult()
err := filepath.Walk(path, func(sub string, info os.FileInfo, err error) error {
if err != nil {
return err
Expand All @@ -140,16 +171,24 @@ func testListDir(t testing.T, path string) []string {
// If it is a dir, add trailing sep
if info.IsDir() {
sub += string(os.PathSeparator)
result.AddFile(sub)
} else if info.Mode()&os.ModeSymlink != 0 {
link, err := os.Readlink(filepath.Join(path, info.Name()))
if err != nil {
return err
}
result.AddSymlink(sub, link)
} else {
result.AddFile(sub)
}

result = append(result, sub)
return nil
})
if err != nil {
t.Fatalf("err: %s", err)
}

sort.Strings(result)
result.SortFiles()
return result
}

Expand Down
8 changes: 8 additions & 0 deletions decompress_tgz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ func TestTarGzipDecompressor(t *testing.T) {
false,
true,
nil,
nil,
"",
nil,
},
Expand All @@ -25,6 +26,7 @@ func TestTarGzipDecompressor(t *testing.T) {
false,
false,
nil,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
Expand All @@ -34,6 +36,7 @@ func TestTarGzipDecompressor(t *testing.T) {
true,
false,
[]string{"file"},
nil,
"",
nil,
},
Expand All @@ -43,6 +46,7 @@ func TestTarGzipDecompressor(t *testing.T) {
true,
false,
[]string{"file1", "file2"},
nil,
"",
nil,
},
Expand All @@ -52,6 +56,7 @@ func TestTarGzipDecompressor(t *testing.T) {
false,
true,
nil,
nil,
"",
nil,
},
Expand All @@ -61,6 +66,7 @@ func TestTarGzipDecompressor(t *testing.T) {
true,
false,
multiplePaths,
nil,
"",
nil,
},
Expand All @@ -71,6 +77,7 @@ func TestTarGzipDecompressor(t *testing.T) {
true,
false,
orderingPaths,
nil,
"",
nil,
},
Expand All @@ -82,6 +89,7 @@ func TestTarGzipDecompressor(t *testing.T) {
true,
true,
nil,
nil,
"",
nil,
},
Expand Down
7 changes: 7 additions & 0 deletions decompress_txz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ func TestTarXzDecompressor(t *testing.T) {
false,
true,
nil,
nil,
"",
nil,
},
Expand All @@ -25,6 +26,7 @@ func TestTarXzDecompressor(t *testing.T) {
false,
false,
nil,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
Expand All @@ -34,6 +36,7 @@ func TestTarXzDecompressor(t *testing.T) {
true,
false,
[]string{"file"},
nil,
"",
nil,
},
Expand All @@ -43,6 +46,7 @@ func TestTarXzDecompressor(t *testing.T) {
true,
false,
[]string{"file1", "file2"},
nil,
"",
nil,
},
Expand All @@ -52,6 +56,7 @@ func TestTarXzDecompressor(t *testing.T) {
false,
true,
nil,
nil,
"",
nil,
},
Expand All @@ -61,6 +66,7 @@ func TestTarXzDecompressor(t *testing.T) {
true,
false,
multiplePaths,
nil,
"",
nil,
},
Expand All @@ -71,6 +77,7 @@ func TestTarXzDecompressor(t *testing.T) {
true,
false,
orderingPaths,
nil,
"",
nil,
},
Expand Down
2 changes: 2 additions & 0 deletions decompress_xz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func TestXzDecompressor(t *testing.T) {
false,
false,
nil,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
Expand All @@ -21,6 +22,7 @@ func TestXzDecompressor(t *testing.T) {
true,
true,
nil,
nil,
"",
nil,
},
Expand Down
Loading