From 78d2c617edad58da6ba537c9b65a80ac0d1b3574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6ran=20Karl?= <3951388+JoeKar@users.noreply.github.com> Date: Mon, 14 Jul 2025 22:38:41 +0200 Subject: [PATCH] util: Hash the path in `DetermineEscapePath()` ...in case the escaped path exceeds the file name length limit --- internal/util/util.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/internal/util/util.go b/internal/util/util.go index d0f20022..86351853 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -3,6 +3,7 @@ package util import ( "archive/zip" "bytes" + "crypto/md5" "errors" "fmt" "io" @@ -450,6 +451,10 @@ func AppendBackupSuffix(path string) string { return path + ".micro-backup" } +func HashStringMd5(str string) string { + return fmt.Sprintf("%x", md5.Sum([]byte(str))) +} + // EscapePathUrl encodes the path in URL query form func EscapePathUrl(path string) string { return url.QueryEscape(filepath.ToSlash(path)) @@ -469,6 +474,8 @@ func EscapePathLegacy(path string) string { // using URL encoding (preferred, since it encodes unambiguously) or // legacy encoding with '%' (for backward compatibility, if the legacy-escaped // path exists in the given directory). +// In case the length of the escaped path (plus the backup extension) exceeds +// the filename length limit, a hash of the path is returned instead. func DetermineEscapePath(dir string, path string) string { url := filepath.Join(dir, EscapePathUrl(path)) if _, err := os.Stat(url); err == nil { @@ -480,6 +487,10 @@ func DetermineEscapePath(dir string, path string) string { return legacy } + if len(url)+len(".micro-backup") > 255 { + return filepath.Join(dir, HashStringMd5(path)) + } + return url }