diff --git a/app/extract_plugin_tar.go b/app/extract_plugin_tar.go index b81a4552cb..65c8646a7e 100644 --- a/app/extract_plugin_tar.go +++ b/app/extract_plugin_tar.go @@ -68,12 +68,20 @@ func extractTarGz(gzipStream io.Reader, dst string) error { return err } - outFile, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.FileMode(header.Mode)) - if err != nil { - return err + copyFile := func() error { + outFile, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.FileMode(header.Mode)) + if err != nil { + return err + } + defer outFile.Close() + if _, err := io.Copy(outFile, tarReader); err != nil { + return err + } + + return nil } - defer outFile.Close() - if _, err := io.Copy(outFile, tarReader); err != nil { + + if err := copyFile(); err != nil { return err } } diff --git a/app/extract_plugin_tar_test.go b/app/extract_plugin_tar_test.go index 8fba0ef4d7..3cacff7272 100644 --- a/app/extract_plugin_tar_test.go +++ b/app/extract_plugin_tar_test.go @@ -72,6 +72,24 @@ func TestExtractTarGz(t *testing.T) { require.Error(t, err) }) + t.Run("huge tar", func(t *testing.T) { + files := make([]*tar.Header, 0, 10000) + for i := 0; i < 10000; i++ { + files = append(files, &tar.Header{ + Name: fmt.Sprintf("%d.txt", i), + Typeflag: tar.TypeReg, + }) + } + + dst, err := ioutil.TempDir("", "TestExtractTarGz") + require.NoError(t, err) + defer os.RemoveAll(dst) + + archive := makeArchive(t, files) + err = extractTarGz(&archive, dst) + require.NoError(t, err) + }) + testCases := []struct { Files []*tar.Header ExpectedError bool