From ddb24549d481dece372914da1102e34fc3beddd1 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 22 Jan 2015 21:34:10 -0800 Subject: [PATCH] Fixed: Extra checks in place to prevent config file corruption --- .../ConfigFileProviderTest.cs | 2 - .../Configuration/ConfigFileProvider.cs | 46 +++++++++++++------ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/NzbDrone.Common.Test/ConfigFileProviderTest.cs b/src/NzbDrone.Common.Test/ConfigFileProviderTest.cs index b15b81310..43bfc00f9 100644 --- a/src/NzbDrone.Common.Test/ConfigFileProviderTest.cs +++ b/src/NzbDrone.Common.Test/ConfigFileProviderTest.cs @@ -29,10 +29,8 @@ public void GetValue_Success() const string key = "Port"; const string value = "8989"; - var result = Subject.GetValue(key, value); - result.Should().Be(value); } diff --git a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs index 6120ef7a7..9f368b232 100644 --- a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs +++ b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs @@ -6,6 +6,7 @@ using System.Xml; using System.Xml.Linq; using NzbDrone.Common.Cache; +using NzbDrone.Common.Disk; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration.Events; @@ -48,15 +49,22 @@ public class ConfigFileProvider : IConfigFileProvider public const string CONFIG_ELEMENT_NAME = "Config"; private readonly IEventAggregator _eventAggregator; + private readonly IDiskProvider _diskProvider; private readonly ICached _cache; private readonly string _configFile; private static readonly Regex HiddenCharacterRegex = new Regex("[^a-z0-9]", RegexOptions.Compiled | RegexOptions.IgnoreCase); - public ConfigFileProvider(IAppFolderInfo appFolderInfo, ICacheManager cacheManager, IEventAggregator eventAggregator) + private static readonly object Mutex = new object(); + + public ConfigFileProvider(IAppFolderInfo appFolderInfo, + ICacheManager cacheManager, + IEventAggregator eventAggregator, + IDiskProvider diskProvider) { _cache = cacheManager.GetCache(GetType()); _eventAggregator = eventAggregator; + _diskProvider = diskProvider; _configFile = appFolderInfo.GetConfigPath(); } @@ -247,8 +255,6 @@ public string GetValue(string key, object defaultValue, bool persist = true) { return _cache.Get(key, () => { - EnsureDefaultConfigFile(); - var xDoc = LoadConfigFile(); var config = xDoc.Descendants(CONFIG_ELEMENT_NAME).Single(); @@ -274,8 +280,6 @@ public string GetValue(string key, object defaultValue, bool persist = true) public void SetValue(string key, object value) { - EnsureDefaultConfigFile(); - var valueString = value.ToString().Trim(); var xDoc = LoadConfigFile(); var config = xDoc.Descendants(CONFIG_ELEMENT_NAME).Single(); @@ -296,7 +300,7 @@ public void SetValue(string key, object value) _cache.Set(key, valueString); - xDoc.Save(_configFile); + SaveConfigFile(xDoc); } public void SetValue(string key, Enum value) @@ -308,18 +312,12 @@ private void EnsureDefaultConfigFile() { if (!File.Exists(_configFile)) { - var xDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes")); - xDoc.Add(new XElement(CONFIG_ELEMENT_NAME)); - xDoc.Save(_configFile); - SaveConfigDictionary(GetConfigDictionary()); } } private void DeleteOldValues() { - EnsureDefaultConfigFile(); - var xDoc = LoadConfigFile(); var config = xDoc.Descendants(CONFIG_ELEMENT_NAME).Single(); @@ -336,14 +334,25 @@ private void DeleteOldValues() } } - xDoc.Save(_configFile); + SaveConfigFile(xDoc); } private XDocument LoadConfigFile() { try { - return XDocument.Load(_configFile); + lock (Mutex) + { + if (_diskProvider.FileExists(_configFile)) + { + return XDocument.Load(_configFile); + } + + var xDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes")); + xDoc.Add(new XElement(CONFIG_ELEMENT_NAME)); + + return xDoc; + } } catch (XmlException ex) @@ -352,6 +361,14 @@ private XDocument LoadConfigFile() } } + private void SaveConfigFile(XDocument xDoc) + { + lock (Mutex) + { + _diskProvider.WriteAllText(_configFile, xDoc.ToString()); + } + } + private string GenerateApiKey() { return Guid.NewGuid().ToString().Replace("-", ""); @@ -359,6 +376,7 @@ private string GenerateApiKey() public void HandleAsync(ApplicationStartedEvent message) { + EnsureDefaultConfigFile(); DeleteOldValues(); }