mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-04-24 22:17:25 -04:00
Fix #7100 by catching the exception on opening invalid UDF images
When an invalid UDF image is opened by the UdfReader, it may throw and exception. This change is to catch and log the exception.
This commit is contained in:
parent
6a8a6a1325
commit
554d1b2ca8
9 changed files with 52 additions and 30 deletions
|
@ -46,6 +46,7 @@ using MediaBrowser.Model.Library;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
||||||
using EpisodeInfo = Emby.Naming.TV.EpisodeInfo;
|
using EpisodeInfo = Emby.Naming.TV.EpisodeInfo;
|
||||||
|
@ -99,7 +100,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
/// Initializes a new instance of the <see cref="LibraryManager" /> class.
|
/// Initializes a new instance of the <see cref="LibraryManager" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="appHost">The application host.</param>
|
/// <param name="appHost">The application host.</param>
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="loggerFactory">The logger factory.</param>
|
||||||
/// <param name="taskManager">The task manager.</param>
|
/// <param name="taskManager">The task manager.</param>
|
||||||
/// <param name="userManager">The user manager.</param>
|
/// <param name="userManager">The user manager.</param>
|
||||||
/// <param name="configurationManager">The configuration manager.</param>
|
/// <param name="configurationManager">The configuration manager.</param>
|
||||||
|
@ -115,7 +116,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
/// <param name="namingOptions">The naming options.</param>
|
/// <param name="namingOptions">The naming options.</param>
|
||||||
public LibraryManager(
|
public LibraryManager(
|
||||||
IServerApplicationHost appHost,
|
IServerApplicationHost appHost,
|
||||||
ILogger<LibraryManager> logger,
|
ILoggerFactory loggerFactory,
|
||||||
ITaskManager taskManager,
|
ITaskManager taskManager,
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
IServerConfigurationManager configurationManager,
|
IServerConfigurationManager configurationManager,
|
||||||
|
@ -131,7 +132,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
NamingOptions namingOptions)
|
NamingOptions namingOptions)
|
||||||
{
|
{
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
_logger = logger;
|
_logger = loggerFactory.CreateLogger<LibraryManager>();
|
||||||
_taskManager = taskManager;
|
_taskManager = taskManager;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_configurationManager = configurationManager;
|
_configurationManager = configurationManager;
|
||||||
|
@ -146,7 +147,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
_memoryCache = memoryCache;
|
_memoryCache = memoryCache;
|
||||||
_namingOptions = namingOptions;
|
_namingOptions = namingOptions;
|
||||||
|
|
||||||
_extraResolver = new ExtraResolver(namingOptions);
|
_extraResolver = new ExtraResolver(loggerFactory.CreateLogger<ExtraResolver>(), namingOptions);
|
||||||
|
|
||||||
_configurationManager.ConfigurationUpdated += ConfigurationUpdated;
|
_configurationManager.ConfigurationUpdated += ConfigurationUpdated;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers
|
namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
{
|
{
|
||||||
|
@ -22,8 +23,11 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
public abstract class BaseVideoResolver<T> : MediaBrowser.Controller.Resolvers.ItemResolver<T>
|
public abstract class BaseVideoResolver<T> : MediaBrowser.Controller.Resolvers.ItemResolver<T>
|
||||||
where T : Video, new()
|
where T : Video, new()
|
||||||
{
|
{
|
||||||
protected BaseVideoResolver(NamingOptions namingOptions)
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
protected BaseVideoResolver(ILogger logger, NamingOptions namingOptions)
|
||||||
{
|
{
|
||||||
|
_logger = logger;
|
||||||
NamingOptions = namingOptions;
|
NamingOptions = namingOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,19 +160,26 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// use disc-utils, both DVDs and BDs use UDF filesystem
|
try
|
||||||
using (var videoFileStream = File.Open(video.Path, FileMode.Open, FileAccess.Read))
|
|
||||||
using (UdfReader udfReader = new UdfReader(videoFileStream))
|
|
||||||
{
|
{
|
||||||
if (udfReader.DirectoryExists("VIDEO_TS"))
|
// use disc-utils, both DVDs and BDs use UDF filesystem
|
||||||
|
using (var videoFileStream = File.Open(video.Path, FileMode.Open, FileAccess.Read))
|
||||||
|
using (UdfReader udfReader = new UdfReader(videoFileStream))
|
||||||
{
|
{
|
||||||
video.IsoType = IsoType.Dvd;
|
if (udfReader.DirectoryExists("VIDEO_TS"))
|
||||||
}
|
{
|
||||||
else if (udfReader.DirectoryExists("BDMV"))
|
video.IsoType = IsoType.Dvd;
|
||||||
{
|
}
|
||||||
video.IsoType = IsoType.BluRay;
|
else if (udfReader.DirectoryExists("BDMV"))
|
||||||
|
{
|
||||||
|
video.IsoType = IsoType.BluRay;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error opening UDF/ISO image: {Value}", video.Path ?? video.Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ using Emby.Naming.Video;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Resolvers;
|
using MediaBrowser.Controller.Resolvers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using static Emby.Naming.Video.ExtraRuleResolver;
|
using static Emby.Naming.Video.ExtraRuleResolver;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers
|
namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
|
@ -22,12 +23,13 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ExtraResolver"/> class.
|
/// Initializes a new instance of the <see cref="ExtraResolver"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
/// <param name="namingOptions">An instance of <see cref="NamingOptions"/>.</param>
|
/// <param name="namingOptions">An instance of <see cref="NamingOptions"/>.</param>
|
||||||
public ExtraResolver(NamingOptions namingOptions)
|
public ExtraResolver(ILogger<ExtraResolver> logger, NamingOptions namingOptions)
|
||||||
{
|
{
|
||||||
_namingOptions = namingOptions;
|
_namingOptions = namingOptions;
|
||||||
_trailerResolvers = new IItemResolver[] { new GenericVideoResolver<Trailer>(namingOptions) };
|
_trailerResolvers = new IItemResolver[] { new GenericVideoResolver<Trailer>(logger, namingOptions) };
|
||||||
_videoResolvers = new IItemResolver[] { new GenericVideoResolver<Video>(namingOptions) };
|
_videoResolvers = new IItemResolver[] { new GenericVideoResolver<Video>(logger, namingOptions) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using Emby.Naming.Common;
|
using Emby.Naming.Common;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers
|
namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
{
|
{
|
||||||
|
@ -15,9 +16,10 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="GenericVideoResolver{T}"/> class.
|
/// Initializes a new instance of the <see cref="GenericVideoResolver{T}"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
/// <param name="namingOptions">The naming options.</param>
|
/// <param name="namingOptions">The naming options.</param>
|
||||||
public GenericVideoResolver(NamingOptions namingOptions)
|
public GenericVideoResolver(ILogger logger, NamingOptions namingOptions)
|
||||||
: base(namingOptions)
|
: base(logger, namingOptions)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Controller.Resolvers;
|
using MediaBrowser.Controller.Resolvers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
{
|
{
|
||||||
|
@ -40,9 +41,10 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||||
/// Initializes a new instance of the <see cref="MovieResolver"/> class.
|
/// Initializes a new instance of the <see cref="MovieResolver"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="imageProcessor">The image processor.</param>
|
/// <param name="imageProcessor">The image processor.</param>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
/// <param name="namingOptions">The naming options.</param>
|
/// <param name="namingOptions">The naming options.</param>
|
||||||
public MovieResolver(IImageProcessor imageProcessor, NamingOptions namingOptions)
|
public MovieResolver(IImageProcessor imageProcessor, ILogger<MovieResolver> logger, NamingOptions namingOptions)
|
||||||
: base(namingOptions)
|
: base(logger, namingOptions)
|
||||||
{
|
{
|
||||||
_imageProcessor = imageProcessor;
|
_imageProcessor = imageProcessor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ using Emby.Naming.Common;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Library.Resolvers.TV
|
namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||||
{
|
{
|
||||||
|
@ -17,9 +18,10 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="EpisodeResolver"/> class.
|
/// Initializes a new instance of the <see cref="EpisodeResolver"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
/// <param name="namingOptions">The naming options.</param>
|
/// <param name="namingOptions">The naming options.</param>
|
||||||
public EpisodeResolver(NamingOptions namingOptions)
|
public EpisodeResolver(ILogger<EpisodeResolver> logger, NamingOptions namingOptions)
|
||||||
: base(namingOptions)
|
: base(logger, namingOptions)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using Emby.Naming.Common;
|
using Emby.Naming.Common;
|
||||||
using Emby.Server.Implementations.Library.Resolvers.TV;
|
using Emby.Server.Implementations.Library.Resolvers.TV;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
@ -7,6 +7,7 @@ using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ namespace Jellyfin.Server.Implementations.Tests.Library
|
||||||
{
|
{
|
||||||
var parent = new Folder { Name = "extras" };
|
var parent = new Folder { Name = "extras" };
|
||||||
|
|
||||||
var episodeResolver = new EpisodeResolver(_namingOptions);
|
var episodeResolver = new EpisodeResolver(Mock.Of<ILogger<EpisodeResolver>>(), _namingOptions);
|
||||||
var itemResolveArgs = new ItemResolveArgs(
|
var itemResolveArgs = new ItemResolveArgs(
|
||||||
Mock.Of<IServerApplicationPaths>(),
|
Mock.Of<IServerApplicationPaths>(),
|
||||||
Mock.Of<IDirectoryService>())
|
Mock.Of<IDirectoryService>())
|
||||||
|
@ -44,7 +45,7 @@ namespace Jellyfin.Server.Implementations.Tests.Library
|
||||||
|
|
||||||
// Have to create a mock because of moq proxies not being castable to a concrete implementation
|
// Have to create a mock because of moq proxies not being castable to a concrete implementation
|
||||||
// https://github.com/jellyfin/jellyfin/blob/ab0cff8556403e123642dc9717ba778329554634/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs#L48
|
// https://github.com/jellyfin/jellyfin/blob/ab0cff8556403e123642dc9717ba778329554634/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs#L48
|
||||||
var episodeResolver = new EpisodeResolverMock(_namingOptions);
|
var episodeResolver = new EpisodeResolverMock(Mock.Of<ILogger<EpisodeResolver>>(), _namingOptions);
|
||||||
var itemResolveArgs = new ItemResolveArgs(
|
var itemResolveArgs = new ItemResolveArgs(
|
||||||
Mock.Of<IServerApplicationPaths>(),
|
Mock.Of<IServerApplicationPaths>(),
|
||||||
Mock.Of<IDirectoryService>())
|
Mock.Of<IDirectoryService>())
|
||||||
|
@ -61,7 +62,7 @@ namespace Jellyfin.Server.Implementations.Tests.Library
|
||||||
|
|
||||||
private class EpisodeResolverMock : EpisodeResolver
|
private class EpisodeResolverMock : EpisodeResolver
|
||||||
{
|
{
|
||||||
public EpisodeResolverMock(NamingOptions namingOptions) : base(namingOptions)
|
public EpisodeResolverMock(ILogger<EpisodeResolver> logger, NamingOptions namingOptions) : base(logger, namingOptions)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
|
@ -5,6 +5,7 @@ using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ public class MovieResolverTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Resolve_GivenLocalAlternateVersion_ResolvesToVideo()
|
public void Resolve_GivenLocalAlternateVersion_ResolvesToVideo()
|
||||||
{
|
{
|
||||||
var movieResolver = new MovieResolver(Mock.Of<IImageProcessor>(), _namingOptions);
|
var movieResolver = new MovieResolver(Mock.Of<IImageProcessor>(), Mock.Of<ILogger<MovieResolver>>(), _namingOptions);
|
||||||
var itemResolveArgs = new ItemResolveArgs(
|
var itemResolveArgs = new ItemResolveArgs(
|
||||||
Mock.Of<IServerApplicationPaths>(),
|
Mock.Of<IServerApplicationPaths>(),
|
||||||
Mock.Of<IDirectoryService>())
|
Mock.Of<IDirectoryService>())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue