Skip to content

Commit 02c4e05

Browse files
committed
release: fix cross-platform path normalization
1 parent c357ba0 commit 02c4e05

2 files changed

Lines changed: 18 additions & 6 deletions

File tree

AniLibertyStrmGenerator.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,7 +1226,8 @@ internal static string NormalizeImageUrlPreferJpg(string url)
12261226

12271227
try
12281228
{
1229-
if (Uri.TryCreate(url, UriKind.Absolute, out var uri))
1229+
if (Uri.TryCreate(url, UriKind.Absolute, out var uri) &&
1230+
(uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
12301231
{
12311232
var path = uri.AbsolutePath;
12321233
if (path.EndsWith(".webp", StringComparison.OrdinalIgnoreCase))
@@ -1242,10 +1243,16 @@ internal static string NormalizeImageUrlPreferJpg(string url)
12421243
// ignore
12431244
}
12441245

1245-
// fallback (in case a non-URI string is returned)
1246-
return url.EndsWith(".webp", StringComparison.OrdinalIgnoreCase)
1247-
? url[..^5] + ".jpg"
1248-
: url;
1246+
// Root-relative image paths are valid web URLs. On Unix, however,
1247+
// Uri.TryCreate classifies them as file:// URIs, so normalize their
1248+
// path component without changing the URL kind.
1249+
var suffixIndex = url.IndexOfAny(['?', '#']);
1250+
var pathOnly = suffixIndex >= 0 ? url[..suffixIndex] : url;
1251+
if (!pathOnly.EndsWith(".webp", StringComparison.OrdinalIgnoreCase))
1252+
return url;
1253+
1254+
var suffix = suffixIndex >= 0 ? url[suffixIndex..] : string.Empty;
1255+
return pathOnly[..^5] + ".jpg" + suffix;
12491256
}
12501257

12511258
internal static string GetSafeImageExtensionFromUrl(string url)
@@ -1597,7 +1604,10 @@ internal static string MakeSafe(string s)
15971604

15981605
if (ch == 'Ω' || ch == 'ω') continue;
15991606

1600-
sb.Append(Array.IndexOf(invalid, ch) >= 0 ? ' ' : ch);
1607+
// Use a portable superset so a catalog generated on Linux remains
1608+
// valid when mounted or copied to Windows.
1609+
var invalidEverywhere = ch < ' ' || ch is '<' or '>' or ':' or '"' or '/' or '\\' or '|' or '?' or '*';
1610+
sb.Append(invalidEverywhere || Array.IndexOf(invalid, ch) >= 0 ? ' ' : ch);
16011611
}
16021612

16031613
var tmp = RepeatedSeparatorRegex().Replace(sb.ToString(), " ").Trim();

AniLibertyStrmPlugin.Tests/AniLibertyStrmGeneratorHelperTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ public void ImageHelpers_PickNormalizeAndSanitizeExtensions()
245245
Assert.Equal("https://cdn.test/poster.jpg?x=1",
246246
AniLibertyStrmGenerator.NormalizeImageUrlPreferJpg("https://cdn.test/poster.webp?x=1"));
247247
Assert.Equal("/poster.jpg", AniLibertyStrmGenerator.NormalizeImageUrlPreferJpg("/poster.webp"));
248+
Assert.Equal("/poster.jpg?size=large#cover",
249+
AniLibertyStrmGenerator.NormalizeImageUrlPreferJpg("/poster.webp?size=large#cover"));
248250
Assert.Equal("/poster.png", AniLibertyStrmGenerator.NormalizeImageUrlPreferJpg("/poster.png"));
249251

250252
Assert.Equal(".jpg", AniLibertyStrmGenerator.GetSafeImageExtensionFromUrl(""));

0 commit comments

Comments
 (0)