| 7 | ) |
| 8 | |
| 9 | func resolveExtractPath(base, entry string) (string, error) { |
| 10 | normalized := strings.ReplaceAll(entry, "\\", string(filepath.Separator)) |
| 11 | cleaned := filepath.Clean(normalized) |
| 12 | if cleaned == "." || cleaned == "" { |
| 13 | return "", fmt.Errorf("invalid archive entry path %q", entry) |
| 14 | } |
| 15 | |
| 16 | if filepath.IsAbs(cleaned) { |
| 17 | return "", fmt.Errorf("archive entry path %q is absolute", entry) |
| 18 | } |
| 19 | |
| 20 | target := filepath.Join(base, cleaned) |
| 21 | rel, err := filepath.Rel(base, target) |
| 22 | if err != nil { |
| 23 | return "", err |
| 24 | } |
| 25 | |
| 26 | if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) { |
| 27 | return "", fmt.Errorf("archive entry path %q escapes target directory", entry) |
| 28 | } |
| 29 | |
| 30 | return target, nil |
| 31 | } |