diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 2cb10765ff..93d527a4d1 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -1135,15 +1135,25 @@ namespace Emby.Server.Implementations.Data Path = RestorePath(path.ToString()) }; - if (long.TryParse(dateModified, NumberStyles.Any, CultureInfo.InvariantCulture, out var ticks)) + if (long.TryParse(dateModified, NumberStyles.Any, CultureInfo.InvariantCulture, out var ticks) + && ticks >= DateTime.MinValue.Ticks + && ticks <= DateTime.MaxValue.Ticks) { image.DateModified = new DateTime(ticks, DateTimeKind.Utc); } + else + { + return null; + } if (Enum.TryParse(imageType.ToString(), true, out ImageType type)) { image.Type = type; } + else + { + return null; + } // Optional parameters: width*height*blurhash if (nextSegment + 1 < value.Length - 1) diff --git a/Emby.Server.Implementations/Properties/AssemblyInfo.cs b/Emby.Server.Implementations/Properties/AssemblyInfo.cs index cb7972173e..41c396ac1d 100644 --- a/Emby.Server.Implementations/Properties/AssemblyInfo.cs +++ b/Emby.Server.Implementations/Properties/AssemblyInfo.cs @@ -16,6 +16,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyCulture("")] [assembly: NeutralResourcesLanguage("en")] [assembly: InternalsVisibleTo("Jellyfin.Server.Implementations.Tests")] +[assembly: InternalsVisibleTo("Emby.Server.Implementations.Fuzz")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from diff --git a/fuzz/Emby.Server.Implementations.Fuzz/Emby.Server.Implementations.Fuzz.csproj b/fuzz/Emby.Server.Implementations.Fuzz/Emby.Server.Implementations.Fuzz.csproj index 791cb140db..6abdb77342 100644 --- a/fuzz/Emby.Server.Implementations.Fuzz/Emby.Server.Implementations.Fuzz.csproj +++ b/fuzz/Emby.Server.Implementations.Fuzz/Emby.Server.Implementations.Fuzz.csproj @@ -12,6 +12,13 @@ + + + + + + + diff --git a/fuzz/Emby.Server.Implementations.Fuzz/Program.cs b/fuzz/Emby.Server.Implementations.Fuzz/Program.cs index a4a6f5f54d..03b2964948 100644 --- a/fuzz/Emby.Server.Implementations.Fuzz/Program.cs +++ b/fuzz/Emby.Server.Implementations.Fuzz/Program.cs @@ -1,5 +1,12 @@ using System; +using AutoFixture; +using AutoFixture.AutoMoq; +using Emby.Server.Implementations.Data; using Emby.Server.Implementations.Library; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Entities; +using Moq; using SharpFuzz; namespace Emby.Server.Implementations.Fuzz @@ -11,6 +18,7 @@ namespace Emby.Server.Implementations.Fuzz switch (args[0]) { case "PathExtensions.TryReplaceSubPath": Run(PathExtensions_TryReplaceSubPath); return; + case "SqliteItemRepository.ItemImageInfoFromValueString": Run(SqliteItemRepository_ItemImageInfoFromValueString); return; default: throw new ArgumentException($"Unknown fuzzing function: {args[0]}"); } } @@ -28,5 +36,27 @@ namespace Emby.Server.Implementations.Fuzz _ = PathExtensions.TryReplaceSubPath(parts[0], parts[1], parts[2], out _); } + + private static void SqliteItemRepository_ItemImageInfoFromValueString(string data) + { + var sqliteItemRepository = MockSqliteItemRepository(); + sqliteItemRepository.ItemImageInfoFromValueString(data); + } + + private static SqliteItemRepository MockSqliteItemRepository() + { + const string VirtualMetaDataPath = "%MetadataPath%"; + const string MetaDataPath = "/meta/data/path"; + + var appHost = new Mock(); + appHost.Setup(x => x.ExpandVirtualPath(It.IsAny())) + .Returns((string x) => x.Replace(VirtualMetaDataPath, MetaDataPath, StringComparison.Ordinal)); + appHost.Setup(x => x.ReverseVirtualPath(It.IsAny())) + .Returns((string x) => x.Replace(MetaDataPath, VirtualMetaDataPath, StringComparison.Ordinal)); + + IFixture fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true }); + fixture.Inject(appHost); + return fixture.Create(); + } } } diff --git a/fuzz/Emby.Server.Implementations.Fuzz/Testcases/SqliteItemRepository.ItemImageInfoFromValueString/test1.txt b/fuzz/Emby.Server.Implementations.Fuzz/Testcases/SqliteItemRepository.ItemImageInfoFromValueString/test1.txt new file mode 100644 index 0000000000..1b0115882f --- /dev/null +++ b/fuzz/Emby.Server.Implementations.Fuzz/Testcases/SqliteItemRepository.ItemImageInfoFromValueString/test1.txt @@ -0,0 +1 @@ +/mnt/series/Family Guy/Season 1/Family Guy - S01E01-thumb.jpg*637452096478512963*Primary*1920*1080*WjQbtJtSO8nhNZ%L_Io#R/oaS6o}-;adXAoIn7j[%hW9s:WGw[nN diff --git a/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs index f312933fbf..a6e1dfe8f6 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs @@ -109,6 +109,9 @@ namespace Jellyfin.Server.Implementations.Tests.Data [InlineData("")] [InlineData("*")] [InlineData("https://image.tmdb.org/t/p/original/zhB5CHEgqqh4wnEqDNJLfWXJlcL.jpg*0")] + [InlineData("/mnt/series/Family Guy/Season 1/Family Guy - S01E01-thumb.jpg*6374520964785129080*WjQbtJtSO8nhNZ%L_Io#R/oaS