Explorar el Código

Added support for newlines and special chars in string settings

ManlyMarco hace 5 años
padre
commit
e01dd44786

+ 9 - 2
BepInEx/Configuration/TomlTypeConverter.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Globalization;
+using System.Text.RegularExpressions;
 
 namespace BepInEx.Configuration
 {
@@ -13,8 +14,14 @@ namespace BepInEx.Configuration
 		{
 			[typeof(string)] = new TypeConverter
 			{
-				ConvertToString = (obj, type) => (string)obj,
-				ConvertToObject = (str, type) => str,
+				ConvertToString = (obj, type) => Regex.Escape((string)obj),
+				ConvertToObject = (str, type) =>
+				{
+					// Check if the string is a file path with unescaped \ path separators (e.g. D:\test and not D:\\test)
+					if (Regex.IsMatch(str, @"^""?\w:\\(?!\\)(?!.+\\\\)"))
+						return str;
+					return Regex.Unescape(str);
+				},
 			},
 			[typeof(bool)] = new TypeConverter
 			{

+ 45 - 0
BepInExTests/Configuration/ConfigFileTests.cs

@@ -247,5 +247,50 @@ namespace BepInEx.Configuration.Tests
 			c.Reload();
 			Assert.AreEqual(shortcut, w.Value);
 		}
+		
+		[TestMethod]
+		public void StringEscapeChars()
+		{
+			const string testVal = "new line\n test \t\0";
+
+			var c = MakeConfig();
+			var w = c.Wrap<string>("Cat", "Key", testVal, new ConfigDescription("Test"));
+
+			Assert.AreEqual(testVal, w.Value);
+			Assert.IsFalse(w.ConfigEntry.GetSerializedValue().Any(x => x == '\n'));
+
+			w.ConfigEntry.SetSerializedValue(w.ConfigEntry.GetSerializedValue());
+			Assert.AreEqual(testVal, w.Value);
+
+			c.Save();
+			c.Reload();
+
+			Assert.AreEqual(testVal, w.Value);
+		}
+
+		[TestMethod]
+		public void UnescapedPathString()
+		{
+			var c = MakeConfig();
+
+			var unescaped = @"D:\test\p ath";
+			foreach (string testVal in new[]{ unescaped , @"D:\\test\\p ath" })
+			{
+				File.WriteAllText(c.ConfigFilePath, $"[Cat]\n# Test\nKey={testVal}\n");
+				c.Reload();
+
+				var w = c.Wrap<string>("Cat", "Key", "", new ConfigDescription("Test"));
+
+				Assert.AreEqual(unescaped, w.Value);
+
+				w.ConfigEntry.SetSerializedValue(w.ConfigEntry.GetSerializedValue());
+				Assert.AreEqual(unescaped, w.Value);
+
+				c.Save();
+				c.Reload();
+
+				Assert.AreEqual(unescaped, w.Value);
+			}
+		}
 	}
 }