MM-35945: handle lots of files in ExtractTarGz (#17669)
* MM-35945: handle lots of files in ExtractTarGz `ExtractTarGz` can fail on archives with a largish number or files, complaining about too many open file handles. Clean up as we go to avoid this. Fixes: https://mattermost.atlassian.net/browse/MM-35945 * use closure to allow defer
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
a5a22cdd12
Коммит
4f0f038e0b
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Ссылка в новой задаче
Block a user