Selaa lähdekoodia

Enforce stricter validation for plugin info

Bepis 5 vuotta sitten
vanhempi
commit
d89d42856a
2 muutettua tiedostoa jossa 65 lisäystä ja 40 poistoa
  1. 56 39
      BepInEx/Bootstrap/Chainloader.cs
  2. 9 1
      BepInEx/Contract/Attributes.cs

+ 56 - 39
BepInEx/Bootstrap/Chainloader.cs

@@ -7,6 +7,7 @@ using System.IO;
 using System.Linq;
 using System.Reflection;
 using System.Text;
+using System.Text.RegularExpressions;
 using UnityEngine;
 using UnityInjector.ConsoleUtil;
 using Logger = BepInEx.Logging.Logger;
@@ -77,6 +78,8 @@ namespace BepInEx.Bootstrap
 			_initialized = true;
 		}
 
+		private static Regex allowedGuidRegex { get; } = new Regex(@"^[a-zA-Z0-9\._]+$");
+
 		/// <summary>
 		/// The entrypoint for the BepInEx plugin system.
 		/// </summary>
@@ -109,60 +112,74 @@ namespace BepInEx.Bootstrap
 
 
 				string currentProcess = Process.GetCurrentProcess().ProcessName.ToLower();
-
+				
 				var globalPluginTypes = TypeLoader.LoadTypes<BaseUnityPlugin>(Paths.PluginPath).ToList();
 
-				var selectedPluginTypes = globalPluginTypes
-										  .Where(plugin =>
-										  {
-											  //Ensure metadata exists
-											  var metadata = MetadataHelper.GetMetadata(plugin);
+				Dictionary<Type, BepInPlugin> selectedPluginTypes = new Dictionary<Type, BepInPlugin>(globalPluginTypes.Count);
 
-											  if (metadata == null)
-											  {
-												  Logger.LogWarning($"Skipping over type [{plugin.Name}] as no metadata attribute is specified");
-												  return false;
-											  }
+				foreach (var pluginType in globalPluginTypes)
+				{
+					//Ensure metadata exists
+					var metadata = MetadataHelper.GetMetadata(pluginType);
 
-											  //Perform a filter for currently running process
-											  var filters = MetadataHelper.GetAttributes<BepInProcess>(plugin);
+					if (metadata == null)
+					{
+						Logger.LogWarning($"Skipping type [{pluginType.FullName}] as no metadata attribute is specified");
+						continue;
+					}
 
-											  if (filters.Length == 0) //no filters means it loads everywhere
-												  return true;
+					if (string.IsNullOrEmpty(metadata.GUID) || !allowedGuidRegex.IsMatch(metadata.GUID))
+					{
+						Logger.LogWarning($"Skipping type [{pluginType.FullName}] because its GUID [{metadata.GUID}] is of an illegal format.");
+						continue;
+					}
 
-											  var result = filters.Any(x => x.ProcessName.ToLower().Replace(".exe", "") == currentProcess);
+					if (selectedPluginTypes.Any(x => x.Value.GUID.Equals(metadata.GUID, StringComparison.OrdinalIgnoreCase)))
+					{
+						Logger.LogWarning($"Skipping type [{pluginType.FullName}] because its GUID [{metadata.GUID}] is already used by another plugin.");
+						continue;
+					}
 
-											  if (!result)
-												  Logger.LogInfo($"Skipping over plugin [{metadata.GUID}] due to process filter");
+					if (metadata.Version == null)
+					{
+						Logger.LogWarning($"Skipping type [{pluginType.FullName}] because its version is invalid.");
+						continue;
+					}
 
-											  return result;
-										  })
-										  .ToList();
+					if (metadata.Name == null)
+					{
+						Logger.LogWarning($"Skipping type [{pluginType.FullName}] because its name is null.");
+						continue;
+					}
+
+					//Perform a filter for currently running process
+					var filters = MetadataHelper.GetAttributes<BepInProcess>(pluginType);
+
+					if (filters.Length != 0)
+					{
+						var result = filters.Any(x => x.ProcessName.ToLower().Replace(".exe", "") == currentProcess);
+
+						if (!result)
+						{
+							Logger.LogInfo($"Skipping over plugin [{metadata.GUID}] due to process filter");
+							continue;
+						}
+					}
+
+					selectedPluginTypes.Add(pluginType, metadata);
+				}
 
 				Logger.LogInfo($"{selectedPluginTypes.Count} / {globalPluginTypes.Count} plugins to load");
 
 				var dependencyDict = new Dictionary<string, IEnumerable<string>>();
 				var pluginsByGUID = new Dictionary<string, Type>();
 
-				foreach (Type t in selectedPluginTypes)
+				foreach (var kv in selectedPluginTypes)
 				{
-					var dependencies = MetadataHelper.GetDependencies(t, selectedPluginTypes);
-					var metadata = MetadataHelper.GetMetadata(t);
-
-					if (metadata.GUID == null)
-					{
-						Logger.LogWarning($"Skipping [{metadata.Name}] because it does not have a valid GUID.");
-						continue;
-					}
-
-					if (dependencyDict.ContainsKey(metadata.GUID))
-					{
-						Logger.LogWarning($"Skipping [{metadata.Name}] because its GUID ({metadata.GUID}) is already used by another plugin.");
-						continue;
-					}
+					var dependencies = MetadataHelper.GetDependencies(kv.Key, selectedPluginTypes.Keys);
 
-					dependencyDict[metadata.GUID] = dependencies.Select(d => d.DependencyGUID);
-					pluginsByGUID[metadata.GUID] = t;
+					dependencyDict[kv.Value.GUID] = dependencies.Select(d => d.DependencyGUID);
+					pluginsByGUID[kv.Value.GUID] = kv.Key;
 				}
 
 				var emptyDependencies = new string[0];
@@ -181,7 +198,7 @@ namespace BepInEx.Bootstrap
 						continue;
 
 					var metadata = MetadataHelper.GetMetadata(pluginType);
-					var dependencies = MetadataHelper.GetDependencies(pluginType, selectedPluginTypes);
+					var dependencies = MetadataHelper.GetDependencies(pluginType, selectedPluginTypes.Keys);
 					var dependsOnInvalidPlugin = false;
 					var missingDependencies = new List<string>();
 					foreach (var dependency in dependencies)

+ 9 - 1
BepInEx/Contract/Attributes.cs

@@ -36,7 +36,15 @@ namespace BepInEx
 		{
 			this.GUID = GUID;
 			this.Name = Name;
-			this.Version = new Version(Version);
+
+			try
+			{
+				this.Version = new Version(Version);
+			}
+			catch
+			{
+				this.Version = null;
+			}
 		}
 	}