aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2017-11-01 15:45:10 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2017-11-01 15:45:10 -0400
commit5fa007d04eff4a280a3f549de869339cccdb0d52 (patch)
treeaa98643b2eed2ae018f5e508b2146b66449cf864
parentccda4bd62928466badcd0787eaedc79dc318a80b (diff)
add error handling to work around skia crashes
-rw-r--r--Emby.Drawing.Skia/SkiaEncoder.cs62
-rw-r--r--Emby.Drawing.Skia/StripCollageBuilder.cs4
-rw-r--r--MediaBrowser.Server.Mono/ImageEncoderHelper.cs6
-rw-r--r--MediaBrowser.Server.Mono/Program.cs2
-rw-r--r--MediaBrowser.ServerApplication/ImageEncoderHelper.cs6
-rw-r--r--MediaBrowser.ServerApplication/MainStartup.cs17
6 files changed, 79 insertions, 18 deletions
diff --git a/Emby.Drawing.Skia/SkiaEncoder.cs b/Emby.Drawing.Skia/SkiaEncoder.cs
index 7469d167e..a89e1f2db 100644
--- a/Emby.Drawing.Skia/SkiaEncoder.cs
+++ b/Emby.Drawing.Skia/SkiaEncoder.cs
@@ -10,22 +10,27 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
+using MediaBrowser.Controller.Extensions;
+using System.Globalization;
+using MediaBrowser.Model.Globalization;
namespace Emby.Drawing.Skia
{
public class SkiaEncoder : IImageEncoder
{
private readonly ILogger _logger;
- private readonly IApplicationPaths _appPaths;
+ private static IApplicationPaths _appPaths;
private readonly Func<IHttpClient> _httpClientFactory;
private readonly IFileSystem _fileSystem;
+ private static ILocalizationManager _localizationManager;
- public SkiaEncoder(ILogger logger, IApplicationPaths appPaths, Func<IHttpClient> httpClientFactory, IFileSystem fileSystem)
+ public SkiaEncoder(ILogger logger, IApplicationPaths appPaths, Func<IHttpClient> httpClientFactory, IFileSystem fileSystem, ILocalizationManager localizationManager)
{
_logger = logger;
_appPaths = appPaths;
_httpClientFactory = httpClientFactory;
_fileSystem = fileSystem;
+ _localizationManager = localizationManager;
LogVersion();
}
@@ -190,14 +195,53 @@ namespace Emby.Drawing.Skia
}
}
+ private static bool HasDiacritics(string text)
+ {
+ return !String.Equals(text, text.RemoveDiacritics(), StringComparison.Ordinal);
+ }
+
+ private static bool RequiresSpecialCharacterHack(string path)
+ {
+ if (_localizationManager.HasUnicodeCategory(path, UnicodeCategory.OtherLetter))
+ {
+ return true;
+ }
+
+ if (HasDiacritics(path))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static string NormalizePath(string path, IFileSystem fileSystem)
+ {
+ if (!RequiresSpecialCharacterHack(path))
+ {
+ return path;
+ }
+
+ var tempPath = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + Path.GetExtension(path) ?? string.Empty);
+
+ fileSystem.CopyFile(path, tempPath, true);
+
+ return tempPath;
+ }
+
private static string[] TransparentImageTypes = new string[] { ".png", ".gif", ".webp" };
- internal static SKBitmap Decode(string path, bool forceCleanBitmap, out SKCodecOrigin origin)
+ internal static SKBitmap Decode(string path, bool forceCleanBitmap, IFileSystem fileSystem, out SKCodecOrigin origin)
{
+ if (!fileSystem.FileExists(path))
+ {
+ throw new FileNotFoundException("File not found", path);
+ }
+
var requiresTransparencyHack = TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty);
if (requiresTransparencyHack || forceCleanBitmap)
{
- using (var stream = new SKFileStream(path))
+ using (var stream = new SKFileStream(NormalizePath(path, fileSystem)))
{
using (var codec = SKCodec.Create(stream))
{
@@ -227,11 +271,11 @@ namespace Emby.Drawing.Skia
}
}
- var resultBitmap = SKBitmap.Decode(path);
+ var resultBitmap = SKBitmap.Decode(NormalizePath(path, fileSystem));
if (resultBitmap == null)
{
- return Decode(path, true, out origin);
+ return Decode(path, true, fileSystem, out origin);
}
// If we have to resize these they often end up distorted
@@ -239,7 +283,7 @@ namespace Emby.Drawing.Skia
{
using (resultBitmap)
{
- return Decode(path, true, out origin);
+ return Decode(path, true, fileSystem, out origin);
}
}
@@ -251,13 +295,13 @@ namespace Emby.Drawing.Skia
{
if (cropWhitespace)
{
- using (var bitmap = Decode(path, forceAnalyzeBitmap, out origin))
+ using (var bitmap = Decode(path, forceAnalyzeBitmap, _fileSystem, out origin))
{
return CropWhiteSpace(bitmap);
}
}
- return Decode(path, forceAnalyzeBitmap, out origin);
+ return Decode(path, forceAnalyzeBitmap, _fileSystem, out origin);
}
private SKBitmap GetBitmap(string path, bool cropWhitespace, bool autoOrient)
diff --git a/Emby.Drawing.Skia/StripCollageBuilder.cs b/Emby.Drawing.Skia/StripCollageBuilder.cs
index 624245ee7..d562bb4be 100644
--- a/Emby.Drawing.Skia/StripCollageBuilder.cs
+++ b/Emby.Drawing.Skia/StripCollageBuilder.cs
@@ -83,7 +83,7 @@ namespace Emby.Drawing.Skia
for (int i = 0; i < 4; i++)
{
SKCodecOrigin origin;
- using (var currentBitmap = SkiaEncoder.Decode(paths[imageIndex], false, out origin))
+ using (var currentBitmap = SkiaEncoder.Decode(paths[imageIndex], false, _fileSystem, out origin))
{
// resize to the same aspect as the original
int iWidth = (int)Math.Abs(iHeight * currentBitmap.Width / currentBitmap.Height);
@@ -165,7 +165,7 @@ namespace Emby.Drawing.Skia
for (var y = 0; y < 2; y++)
{
SKCodecOrigin origin;
- using (var currentBitmap = SkiaEncoder.Decode(paths[imageIndex], false, out origin))
+ using (var currentBitmap = SkiaEncoder.Decode(paths[imageIndex], false, _fileSystem, out origin))
{
using (var resizedBitmap = new SKBitmap(cellWidth, cellHeight, currentBitmap.ColorType, currentBitmap.AlphaType))
{
diff --git a/MediaBrowser.Server.Mono/ImageEncoderHelper.cs b/MediaBrowser.Server.Mono/ImageEncoderHelper.cs
index 5112c64ed..4f8451c0d 100644
--- a/MediaBrowser.Server.Mono/ImageEncoderHelper.cs
+++ b/MediaBrowser.Server.Mono/ImageEncoderHelper.cs
@@ -9,6 +9,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using Emby.Drawing.Skia;
using MediaBrowser.Model.System;
+using MediaBrowser.Model.Globalization;
namespace MediaBrowser.Server.Startup.Common
{
@@ -20,13 +21,14 @@ namespace MediaBrowser.Server.Startup.Common
StartupOptions startupOptions,
Func<IHttpClient> httpClient,
IApplicationPaths appPaths,
- IEnvironmentInfo environment)
+ IEnvironmentInfo environment,
+ ILocalizationManager localizationManager)
{
if (!startupOptions.ContainsOption("-enablegdi"))
{
try
{
- return new SkiaEncoder(logManager.GetLogger("Skia"), appPaths, httpClient, fileSystem);
+ return new SkiaEncoder(logManager.GetLogger("Skia"), appPaths, httpClient, fileSystem, localizationManager);
}
catch (Exception ex)
{
diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs
index 3267a77b9..7a3a968ad 100644
--- a/MediaBrowser.Server.Mono/Program.cs
+++ b/MediaBrowser.Server.Mono/Program.cs
@@ -127,7 +127,7 @@ namespace MediaBrowser.Server.Mono
Task.WaitAll(task);
- appHost.ImageProcessor.ImageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => appHost.HttpClient, appPaths, environmentInfo);
+ appHost.ImageProcessor.ImageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => appHost.HttpClient, appPaths, environmentInfo, appHost.LocalizationManager);
Console.WriteLine("Running startup tasks");
diff --git a/MediaBrowser.ServerApplication/ImageEncoderHelper.cs b/MediaBrowser.ServerApplication/ImageEncoderHelper.cs
index c86e85785..7c95a25de 100644
--- a/MediaBrowser.ServerApplication/ImageEncoderHelper.cs
+++ b/MediaBrowser.ServerApplication/ImageEncoderHelper.cs
@@ -7,6 +7,7 @@ using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Globalization;
namespace MediaBrowser.Server.Startup.Common
{
@@ -17,11 +18,12 @@ namespace MediaBrowser.Server.Startup.Common
IFileSystem fileSystem,
StartupOptions startupOptions,
Func<IHttpClient> httpClient,
- IApplicationPaths appPaths)
+ IApplicationPaths appPaths,
+ ILocalizationManager localizationManager)
{
try
{
- return new SkiaEncoder(logManager.GetLogger("Skia"), appPaths, httpClient, fileSystem);
+ return new SkiaEncoder(logManager.GetLogger("Skia"), appPaths, httpClient, fileSystem, localizationManager);
}
catch
{
diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs
index 70b03aa44..91a949921 100644
--- a/MediaBrowser.ServerApplication/MainStartup.cs
+++ b/MediaBrowser.ServerApplication/MainStartup.cs
@@ -304,6 +304,19 @@ namespace MediaBrowser.ServerApplication
}
}
+ private static string UpdatePackageFileName
+ {
+ get
+ {
+ if (Environment.Is64BitOperatingSystem)
+ {
+ return "embyserver-win-x64-{version}.zip";
+ }
+
+ return "embyserver-win-x86-{version}.zip";
+ }
+ }
+
/// <summary>
/// Runs the application.
/// </summary>
@@ -324,7 +337,7 @@ namespace MediaBrowser.ServerApplication
options,
fileSystem,
new PowerManagement(),
- "emby.windows.zip",
+ UpdatePackageFileName,
environmentInfo,
new NullImageEncoder(),
new SystemEvents(logManager.GetLogger("SystemEvents")),
@@ -355,7 +368,7 @@ namespace MediaBrowser.ServerApplication
}
// set image encoder here
- appHost.ImageProcessor.ImageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => appHost.HttpClient, appPaths);
+ appHost.ImageProcessor.ImageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => appHost.HttpClient, appPaths, appHost.LocalizationManager);
task = task.ContinueWith(new Action<Task>(a => appHost.RunStartupTasks()), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent);