Maison > développement back-end > Golang > le corps du texte

Comment puis-je simplifier et sécuriser la décompression de fichiers à l'aide du package zip de Go ?

Barbara Streisand
Libérer: 2024-11-14 14:54:02
original
355 Les gens l'ont consulté

How can I simplify and secure file decompression using Go's zip package?

Simple and Effective File Decompression in Go

Decompressing ZIP archives in Go can be a straightforward process. One approach, as demonstrated by the original code, involves manually handling the decompression for each file within the archive.

However, there's a more seamless and efficient way to accomplish this using the following updated solution:

func Unzip(src, dest string) error {
    r, err := zip.OpenReader(src)
    if err != nil {
        return err
    }
    defer func() {
        if err := r.Close(); err != nil {
            panic(err)
        }
    }()

    os.MkdirAll(dest, 0755)

    // Closure to wrap file extraction and writing, avoiding deferred stack overflow
    extractAndWriteFile := func(f *zip.File) error {
        rc, err := f.Open()
        if err != nil {
            return err
        }
        defer func() {
            if err := rc.Close(); err != nil {
                panic(err)
            }
        }()

        path := filepath.Join(dest, f.Name)

        // Check for directory traversal (ZipSlip) vulnerability
        if !strings.HasPrefix(path, filepath.Clean(dest)+string(os.PathSeparator)) {
            return fmt.Errorf("illegal file path: %s", path)
        }

        if f.FileInfo().IsDir() {
            os.MkdirAll(path, f.Mode())
        } else {
            os.MkdirAll(filepath.Dir(path), f.Mode())
            f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
            if err != nil {
                return err
            }
            defer func() {
                if err := f.Close(); err != nil {
                    panic(err)
                }
            }()

            _, err = io.Copy(f, rc)
            if err != nil {
                return err
            }
        }

        return nil
    }

    for _, f := range r.File {
        err := extractAndWriteFile(f)
        if err != nil {
            return err
        }
    }

    return nil
}
Copier après la connexion

This updated solution offers several advantages:

  • Deferred Close() Errors Handled: It gracefully handles potential errors in closing both the file reader (rc) and the archive reader (r), ensuring proper cleanup even in the face of failures.
  • Closure-Wrapped File Extraction: The extraction and writing process for each file is encapsulated within a closure, eliminating the need for stacking and cleaning up multiple defer .Close() calls for each file.
  • Directory Creation: The solution ensures that the destination directory exists before extracting files, preventing any extraction failures.
  • ZipSlip Prevention: It includes a security check to prevent potential directory traversal (ZipSlip) vulnerabilities by verifying that files are not extracted outside the expected destination directory.

With these enhancements, this code provides a simple, robust, and secure method for unzipping files in Go.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal