A function that should work to get the full extension of a file, with sanitization:
// GetFullExtensionSanitized returns the full extension of a file (such as .tar.gz), as compared to
// filepath.Ext, which only returns the last part of the extension (such as .gz).
func GetFullExtensionSanitized(filename string) string {
filename = filepath.Base(filename)
extension := ""
for {
ext := filepath.Ext(filename)
if ext == "" {
break
}
extension = ext + extension
filename = strings.TrimSuffix(filename, ext)
}
if len(extension) > 15 { // no extension is likely to be >15 characters, so we reject these
return ""
}
var builder strings.Builder
builder.Grow(len(extension))
var prev rune
for _, r := range extension {
if r == '.' && prev == '.' {
continue
}
if !slices.Contains([]rune(".abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"), r) {
continue
}
builder.WriteRune(r)
prev = r
}
extension = builder.String()
return extension
}