51 lines
1.0 KiB
Go
51 lines
1.0 KiB
Go
package boxstore
|
|
|
|
import (
|
|
"archive/zip"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func AddFileToZip(zipWriter *zip.Writer, boxID string, filename string) error {
|
|
path, ok := SafeBoxFilePath(boxID, filename)
|
|
if !ok {
|
|
return fmt.Errorf("Invalid file")
|
|
}
|
|
if err := ensureRegularFile(path); err != nil {
|
|
return err
|
|
}
|
|
zipName, ok := safeZipEntryName(filename)
|
|
if !ok {
|
|
return fmt.Errorf("Invalid zip entry")
|
|
}
|
|
|
|
source, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer source.Close()
|
|
|
|
destination, err := zipWriter.Create(zipName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = io.Copy(destination, source)
|
|
return err
|
|
}
|
|
func safeZipEntryName(filename string) (string, bool) {
|
|
filename = strings.TrimSpace(filename)
|
|
if filename == "" || filepath.IsAbs(filename) {
|
|
return "", false
|
|
}
|
|
|
|
cleaned := filepath.ToSlash(filepath.Clean(filename))
|
|
if cleaned == "." || cleaned == ".." || strings.HasPrefix(cleaned, "../") || strings.HasPrefix(cleaned, "/") {
|
|
return "", false
|
|
}
|
|
return cleaned, true
|
|
}
|