Browse Source

Make assembly resolution fully safe
Rebase of 68378b3

Bepis 4 years ago
parent
commit
a3e7b0edf6
2 changed files with 23 additions and 2 deletions
  1. 20 0
      BepInEx.Core/Utility.cs
  2. 3 2
      BepInEx.Preloader.Unity/DoorstopEntrypoint.cs

+ 20 - 0
BepInEx.Core/Utility.cs

@@ -308,6 +308,26 @@ namespace BepInEx
 
 			return builder.ToString();
 		}
+		
+		/// <summary>
+		/// Try to parse given string as an assembly name
+		/// </summary>
+		/// <param name="fullName">Fully qualified assembly name</param>
+		/// <param name="assemblyName">Resulting <see cref="AssemblyName"/> instance</param>
+		/// <returns><c>true</c>, if parsing was successful, otherwise <c>false</c></returns>
+		public static bool TryParseAssemblyName(string fullName, out AssemblyName assemblyName)
+		{
+			try
+			{
+				assemblyName = new AssemblyName(fullName);
+				return true;
+			}
+			catch (Exception)
+			{
+				assemblyName = null;
+				return false;
+			}
+		}
 
 		public static Platform CurrentPlatform { get; private set; } = CheckPlatform();
 

+ 3 - 2
BepInEx.Preloader.Unity/DoorstopEntrypoint.cs

@@ -31,12 +31,13 @@ namespace BepInEx.Preloader.Unity
 
 		private static Assembly LocalResolve(object sender, ResolveEventArgs args)
 		{
-			var assemblyName = new AssemblyName(args.Name);
+			if (!Utility.TryParseAssemblyName(args.Name, out var assemblyName))
+				return null;
 
 			// Use parse assembly name on managed side because native GetName() can fail on some locales
 			// if the game path has "exotic" characters
 			var foundAssembly = AppDomain.CurrentDomain.GetAssemblies()
-										 .FirstOrDefault(x => new AssemblyName(x.FullName).Name == assemblyName.Name);
+										 .FirstOrDefault(x => Utility.TryParseAssemblyName(x.FullName, out var name) && name.Name == assemblyName.Name);
 
 			if (foundAssembly != null)
 				return foundAssembly;