Fix 3D format detection when the tag is the last token of the path

Format3DParser drops the last character of the final path token: when
IndexOfAny finds no more delimiters, the slice is taken with
'index = path.Length - 1', so e.g. "hsbs" is compared as "hsb" and
never matches any rule.

File paths are unaffected because the extension is always the final
token, but directory based media have no extension. For DVD/BluRay
folder rips (BaseVideoResolver parses the folder path via
Set3DFormat), a trailing 3D tag such as
"Gravity (2013) 3d hsbs/BDMV" is silently ignored and Video3DFormat
is never set.

This is a regression from 42a2cc174 which replaced the string.Split
based FlagParser with span slicing; the Split implementation kept the
final token intact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
TowyTowy
2026-07-12 12:11:29 +02:00
parent 53aafcd38e
commit 5be844e1b7
2 changed files with 30 additions and 4 deletions
+9 -4
View File
@@ -52,13 +52,18 @@ namespace Emby.Naming.Video
while (path.Length > 0)
{
var index = path.IndexOfAny(delimiters);
ReadOnlySpan<char> currentSlice;
if (index == -1)
{
index = path.Length - 1;
// No delimiter left, the last token is the remainder of the path
currentSlice = path;
path = default;
}
else
{
currentSlice = path[..index];
path = path[(index + 1)..];
}
var currentSlice = path[..index];
path = path[(index + 1)..];
if (!foundPrefix)
{
@@ -19,6 +19,27 @@ namespace Jellyfin.Naming.Tests.Video
Test("Super movie 3d hsbs.mp4", true, "hsbs");
}
[Fact]
public void TestFormat3DAtEndOfPath()
{
// Directory based media (eg. DVD or BluRay folder rips) have no file extension,
// so the 3D tag can be the last token of the path.
Test("Super movie (2009) 3d hsbs", true, "hsbs");
Test("Super movie (2009).3d.sbs", true, "sbs");
Test("Super movie (2009) 3d htab", true, "htab");
Test("Super movie (2009).hsbs", true, "hsbs");
Test("Super movie (2009) 3d", false, null);
}
[Fact]
public void TestResolveDirectory3D()
{
var result = VideoResolver.ResolveDirectory("/movies/Oblivion (2013) 3d hsbs", _namingOptions);
Assert.True(result?.Is3D);
Assert.Equal("hsbs", result?.Format3D, true);
}
[Fact]
public void Test3DName()
{