Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit 956967f

Browse files
committed
Truncate long title to not exceed fs length limits
1 parent f3731f1 commit 956967f

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

feed.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"strconv"
66
"strings"
77
"sync"
8+
"unicode/utf8"
89

910
"github.com/mmcdole/gofeed"
1011
log "github.com/sirupsen/logrus"
@@ -19,6 +20,28 @@ type Feed struct {
1920
var wg sync.WaitGroup
2021
var isAllUpdate bool
2122

23+
/*
24+
Based on the table in https://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits
25+
26+
the majority of filesystems have a limit of 255.
27+
28+
Some of them refer to "bytes" and others refer to "UTF-8 characters".
29+
Ideally we'd like to take as much as that as possible but we run the risk of
30+
truncating at a point which leaves us with an incomplete UTF8 code point
31+
representation. Instead, we need a UTF8-safe truncate - we define that function below.
32+
*/
33+
const maxFileNameLength = 255
34+
35+
func truncateString(s string, n int) string {
36+
if len(s) <= n {
37+
return s
38+
}
39+
for !utf8.ValidString(s[:n]) {
40+
n--
41+
}
42+
return s[:n]
43+
}
44+
2245
func DeleteFeedFiles(name string) {
2346
os.RemoveAll(Config.FeedDirectory + "/" + name)
2447
os.MkdirAll(Config.FeedDirectory+"/"+name, 0777)
@@ -37,7 +60,7 @@ func UpdateFeed(name string) {
3760
}
3861
DeleteFeedFiles(name)
3962
for _, item := range feed.Items {
40-
file, err := os.Create(Config.FeedDirectory + "/" + name + "/" + strings.ReplaceAll(item.Title, "/", ""))
63+
file, err := os.Create(Config.FeedDirectory + "/" + name + "/" + truncateString(strings.ReplaceAll(item.Title, "/", ""), maxFileNameLength))
4164
if err != nil {
4265
log.Error("Failed to create a file for article titled '" + item.Title + "'")
4366
continue

feed_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package main
2+
3+
import "testing"
4+
5+
func TestFileNameTruncation(t *testing.T) {
6+
names := []string{
7+
"我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我", // 255 x Chinese wo3 (我)
8+
"我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我", // 256 x Chinese wo3 (我)
9+
"我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我", // 32 x Chinese wo3 (我)
10+
"short"} // should not get truncated
11+
12+
for _, name := range names {
13+
shortened := truncateString(name, maxFileNameLength)
14+
if len(name) < maxFileNameLength {
15+
if name != shortened {
16+
t.Errorf("Filename should not be altered, but it was. Original was %s", name)
17+
}
18+
} else {
19+
if len(shortened) > maxFileNameLength {
20+
t.Errorf("Filename was too long - should have been truncated. Length was %d", len(name))
21+
}
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)