diff --git a/src/Jackett.Common/Services/ConfigurationService.cs b/src/Jackett.Common/Services/ConfigurationService.cs index 615d4a673..ccb3068e1 100644 --- a/src/Jackett.Common/Services/ConfigurationService.cs +++ b/src/Jackett.Common/Services/ConfigurationService.cs @@ -69,7 +69,9 @@ namespace Jackett.Common.Services { try { - processService.StartProcessAndLog(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath, "--MigrateSettings", true); + // Use EscapedCodeBase to avoid Uri reserved characters from causing bugs + // https://stackoverflow.com/questions/896572 + processService.StartProcessAndLog(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath, "--MigrateSettings", true); } catch { @@ -164,7 +166,9 @@ namespace Jackett.Common.Services } } - public string ApplicationFolder() => Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath); + // Use EscapedCodeBase to avoid Uri reserved characters from causing bugs + // https://stackoverflow.com/questions/896572 + public string ApplicationFolder() => Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath); public string GetContentFolder() { @@ -232,7 +236,7 @@ namespace Jackett.Common.Services } else { - //We don't load these out of the config files as it could get confusing to users who accidently save. + //We don't load these out of the config files as it could get confusing to users who accidently save. //In future we could flatten the serverconfig, and use command line parameters to override any configuration. config.RuntimeSettings = runtimeSettings; } diff --git a/src/Jackett.Common/Services/WindowsServiceConfigService.cs b/src/Jackett.Common/Services/WindowsServiceConfigService.cs index 93443b924..40bf44578 100644 --- a/src/Jackett.Common/Services/WindowsServiceConfigService.cs +++ b/src/Jackett.Common/Services/WindowsServiceConfigService.cs @@ -51,7 +51,9 @@ namespace Jackett.Common.Services } else { - var applicationFolder = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath); + // Use EscapedCodeBase to avoid Uri reserved characters from causing bugs + // https://stackoverflow.com/questions/896572 + var applicationFolder = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath); var exePath = Path.Combine(applicationFolder, SERVICEEXE); if (!File.Exists(exePath) && Debugger.IsAttached) diff --git a/src/Jackett.Server/Services/ServiceConfigService.cs b/src/Jackett.Server/Services/ServiceConfigService.cs index 102c7dfc9..235946b53 100644 --- a/src/Jackett.Server/Services/ServiceConfigService.cs +++ b/src/Jackett.Server/Services/ServiceConfigService.cs @@ -47,7 +47,9 @@ namespace Jackett.Server.Services } else { - var applicationFolder = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath); + // Use EscapedCodeBase to avoid Uri reserved characters from causing bugs + // https://stackoverflow.com/questions/896572 + var applicationFolder = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath); var exePath = Path.Combine(applicationFolder, SERVICEEXE); if (!File.Exists(exePath) && Debugger.IsAttached) diff --git a/src/Jackett.Service/Service.cs b/src/Jackett.Service/Service.cs index f42aa1445..3e716ec2c 100644 --- a/src/Jackett.Service/Service.cs +++ b/src/Jackett.Service/Service.cs @@ -51,7 +51,9 @@ namespace Jackett.Service private void StartConsoleApplication() { - var applicationFolder = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath); + // Use EscapedCodeBase to avoid Uri reserved characters from causing bugs + // https://stackoverflow.com/questions/896572 + var applicationFolder = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath); var exePath = Path.Combine(applicationFolder, "JackettConsole.exe"); diff --git a/src/Jackett.Test/Definitions/DefinitionsParserTests.cs b/src/Jackett.Test/Definitions/DefinitionsParserTests.cs new file mode 100644 index 000000000..cdd9d25cc --- /dev/null +++ b/src/Jackett.Test/Definitions/DefinitionsParserTests.cs @@ -0,0 +1,38 @@ +using System; +using System.IO; +using System.Reflection; +using Jackett.Common.Models; +using NUnit.Framework; +using YamlDotNet.Serialization; +using YamlDotNet.Serialization.NamingConventions; +using Assert = NUnit.Framework.Assert; + +namespace Jackett.Test.Definitions +{ + [TestFixture] + public class DefinitionsParserTests + { + [Test] + public void LoadAndParseAllCardigannDefinitions() + { + // Use EscapedCodeBase to avoid Uri reserved characters from causing bugs + // https://stackoverflow.com/questions/896572 + var applicationFolder = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath); + var definitionsFolder = Path.GetFullPath(Path.Combine(applicationFolder, "Definitions")); + var deserializer = new DeserializerBuilder() + .WithNamingConvention(CamelCaseNamingConvention.Instance) + .Build(); + var files = new DirectoryInfo(definitionsFolder).GetFiles("*.yml"); + foreach (var file in files) + try + { + var definitionString = File.ReadAllText(file.FullName); + deserializer.Deserialize(definitionString); + } + catch (Exception ex) + { + Assert.Fail($"Error while parsing Cardigann definition {file.Name}\n{ex}"); + } + } + } +}