Skip to content

Commit 496ee3a

Browse files
committed
fix bug about invalid utf8 in export cmd
1 parent 1f39059 commit 496ee3a

3 files changed

Lines changed: 32 additions & 4 deletions

File tree

internal/episode/obsidian.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,17 @@ var nonSafeFilenameRe = regexp.MustCompile(`[^\p{L}\p{N}\-_ ]+`)
101101

102102
// sanitizeFilename produces a filesystem-safe name from an arbitrary string.
103103
func sanitizeFilename(s string) string {
104+
// Strip any invalid UTF-8 sequences first so the regex and filesystem
105+
// are never handed malformed bytes.
106+
s = strings.ToValidUTF8(s, "")
104107
s = nonSafeFilenameRe.ReplaceAllString(s, "")
105108
s = strings.TrimSpace(s)
106109
s = strings.ReplaceAll(s, " ", "_")
107-
if len(s) > 80 {
108-
s = s[:80]
110+
// Truncate by rune count, not byte count, to avoid splitting multi-byte
111+
// characters (e.g. Chinese/Japanese) which would produce an illegal byte
112+
// sequence that macOS and other systems reject.
113+
if runes := []rune(s); len(runes) > 80 {
114+
s = string(runes[:80])
109115
}
110116
if s == "" {
111117
s = "episode"

internal/episode/utils.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ import (
1010

1111
// ParseSeq extracts the integer episode seq from a podwise episode URL.
1212
// Expected format: https://podwise.ai/dashboard/episodes/<seq>
13+
// Also accepts https://app.podwise.ai/dashboard/episodes/<seq> and beta.podwise.ai.
1314
func ParseSeq(input string) (int, error) {
1415
const hint = "(expected https://podwise.ai/dashboard/episodes/<id>)"
1516

1617
u, err := url.Parse(input)
17-
if err != nil || u.Scheme != "https" || (u.Host != "podwise.ai" && u.Host != "beta.podwise.ai") {
18+
if err != nil || u.Scheme != "https" || !isPodwiseHost(u.Host) {
1819
return 0, fmt.Errorf("%q is not a valid podwise episode URL %s", input, hint)
1920
}
2021

@@ -68,6 +69,16 @@ func IsXiaoyuzhouURL(rawURL string) bool {
6869
return u.Hostname() == "www.xiaoyuzhoufm.com" && strings.HasPrefix(u.Path, "/episode/")
6970
}
7071

72+
// isPodwiseHost reports whether host is a recognised Podwise web host.
73+
// Accepted: podwise.ai, app.podwise.ai, beta.podwise.ai.
74+
func isPodwiseHost(host string) bool {
75+
switch host {
76+
case "podwise.ai", "app.podwise.ai", "beta.podwise.ai":
77+
return true
78+
}
79+
return false
80+
}
81+
7182
// trimTime removes a leading "00:" hour prefix from a time string only when
7283
// the remainder is still a valid mm:ss[-based] string (contains at least one
7384
// more colon). Examples:

internal/podcast/utils.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,24 @@ import (
77
"strings"
88
)
99

10+
// isPodwiseHost reports whether host is a recognised Podwise web host.
11+
// Accepted: podwise.ai, app.podwise.ai, beta.podwise.ai.
12+
func isPodwiseHost(host string) bool {
13+
switch host {
14+
case "podwise.ai", "app.podwise.ai", "beta.podwise.ai":
15+
return true
16+
}
17+
return false
18+
}
19+
1020
// ParseSeq extracts the integer podcast seq from a podwise podcast URL.
1121
// Expected format: https://podwise.ai/dashboard/podcasts/<seq>
22+
// Also accepts https://app.podwise.ai/dashboard/podcasts/<seq> and beta.podwise.ai.
1223
func ParseSeq(input string) (int, error) {
1324
const hint = "(expected https://podwise.ai/dashboard/podcasts/<id>)"
1425

1526
u, err := url.Parse(input)
16-
if err != nil || u.Scheme != "https" || (u.Host != "podwise.ai" && u.Host != "beta.podwise.ai") {
27+
if err != nil || u.Scheme != "https" || !isPodwiseHost(u.Host) {
1728
return 0, fmt.Errorf("%q is not a valid podwise podcast URL %s", input, hint)
1829
}
1930

0 commit comments

Comments
 (0)