From 7286f34104bf930350ee7673f8fd30d902106cb4 Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Fri, 12 Dec 2025 08:49:10 +0200 Subject: [PATCH] trim normalized file extension --- CHANGELOG.md | 2 ++ tools/filesystem/file.go | 8 ++++---- tools/filesystem/file_test.go | 2 ++ tools/filesystem/filesystem_test.go | 6 ++++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 214a56fa..003999b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ - Store the correct `image/png` as attrs content type when generating a thumb fallback _(e.g. for `webp`)_. +- Trimmed the normalized file extension to ensure that there is only one beginning `.` character. + ## v0.34.2 diff --git a/tools/filesystem/file.go b/tools/filesystem/file.go index c1771975..5f4e94d3 100644 --- a/tools/filesystem/file.go +++ b/tools/filesystem/file.go @@ -196,19 +196,19 @@ func normalizeName(fr FileReader, name string) string { // extension // --- originalExt := extractExtension(name) - cleanExt := extInvalidCharsRegex.ReplaceAllString(originalExt, "") - if cleanExt == "" { + cleanExt := "." + strings.Trim(extInvalidCharsRegex.ReplaceAllString(originalExt, ""), ".") + if cleanExt == "." { // try to detect the extension from the file content cleanExt, _ = detectExtension(fr) } if extLength := len(cleanExt); extLength > 20 { // keep only the last 20 characters (it is multibyte safe after the regex replace) - cleanExt = "." + cleanExt[extLength-20:] + cleanExt = "." + strings.Trim(cleanExt[extLength-20:], ".") } // name // --- - cleanName := inflector.Snakecase(strings.TrimSuffix(name, originalExt)) + cleanName := inflector.Snakecase(strings.TrimSuffix(strings.TrimSuffix(name, originalExt), ".")) if length := len(cleanName); length < 3 { // the name is too short so we concatenate an additional random part cleanName += security.RandomStringWithAlphabet(10, randomAlphabet) diff --git a/tools/filesystem/file_test.go b/tools/filesystem/file_test.go index e3bb00fb..10d73680 100644 --- a/tools/filesystem/file_test.go +++ b/tools/filesystem/file_test.go @@ -211,6 +211,8 @@ func TestFileNameNormalizations(t *testing.T) { {".png", `^\w{10}_\w{10}\.png$`}, {".tar.gz", `^\w{10}_\w{10}\.tar\.gz$`}, {"a.tar.gz", `^a\w{10}_\w{10}\.tar\.gz$`}, + {"....abc", `^\w{10}_\w{10}\.abc$`}, + {"a.b.c.?.?.?.2", `^a_b_c_\w{10}\.2$`}, {"a.b.c.d.tar.gz", `^a_b_c_d_\w{10}\.tar\.gz$`}, {"abcd", `^abcd_\w{10}\.txt$`}, {"a b! c d . 456", `^a_b_c_d_\w{10}\.456$`}, // normalize spaces diff --git a/tools/filesystem/filesystem_test.go b/tools/filesystem/filesystem_test.go index 182f187c..c530e252 100644 --- a/tools/filesystem/filesystem_test.go +++ b/tools/filesystem/filesystem_test.go @@ -600,6 +600,7 @@ func TestFileSystemGetReuploadableFile(t *testing.T) { if err != nil { t.Fatal(err) } + defer r.Close() raw, err := io.ReadAll(r) if err != nil { @@ -677,12 +678,13 @@ func TestFileSystemCopy(t *testing.T) { if err := fsys.Copy(src, dst); err != nil { t.Fatalf("Failed to copy %q to %q: %v", src, dst, err) } + f, err := fsys.GetReader(dst) - //nolint - defer f.Close() if err != nil { t.Fatalf("Missing copied file %q: %v", dst, err) } + defer f.Close() + if f.Size() != 73 { t.Fatalf("Expected file size %d, got %d", 73, f.Size()) }