package internal import ( "fmt" "path/filepath" "regexp" "strings" "time" ) var ( descMax = 64 allowedDesc = regexp.MustCompile(`[^A-Za-z0-9 _-]`) // to be replaced by `_` dateOnly = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}$`) // UI sends YYYY-MM-DD finalNameValidate = regexp.MustCompile(`^\d{4}\.\d{2}\.\d{2}\.[A-Za-z0-9_-]{1,64}\.[A-Za-z0-9]{1,8}$`) ) func SanitizeDesc(in string) string { s := strings.TrimSpace(in) if s == "" { s = "upload" } s = allowedDesc.ReplaceAllString(s, "_") s = strings.Join(strings.Fields(s), "_") // collapse whitespace if len(s) > descMax { s = s[:descMax] } return s } func ComposeFinalName(dateStr, desc, origFilename string) (string, error) { ext := strings.ToLower(strings.TrimPrefix(filepath.Ext(origFilename), ".")) if ext == "" { ext = "bin" } var t time.Time var err error if dateOnly.MatchString(dateStr) { t, err = time.Parse("2006-01-02", dateStr) } else { t = time.Now() } if err != nil { return "", fmt.Errorf("bad date") } final := fmt.Sprintf("%04d.%02d.%02d.%s.%s", t.Year(), int(t.Month()), t.Day(), SanitizeDesc(desc), ext) if !finalNameValidate.MatchString(final) { return "", fmt.Errorf("invalid final name") } return final, nil }