From fcbfc652044358ae4273c8be2bd065142608bff8 Mon Sep 17 00:00:00 2001 From: Katy Coe Date: Mon, 14 Sep 2020 05:02:47 +0200 Subject: [PATCH] C#: Sanitize type names (#70) --- Il2CppInspector.Common/Reflection/Extensions.cs | 4 ++-- Il2CppInspector.Common/Reflection/TypeInfo.cs | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Il2CppInspector.Common/Reflection/Extensions.cs b/Il2CppInspector.Common/Reflection/Extensions.cs index b48e27e..fbd309b 100644 --- a/Il2CppInspector.Common/Reflection/Extensions.cs +++ b/Il2CppInspector.Common/Reflection/Extensions.cs @@ -88,11 +88,11 @@ namespace Il2CppInspector.Reflection return s.ToString(); } - public static string ToCIdentifier(this string str) { + public static string ToCIdentifier(this string str, bool allowScopeQualifiers = false) { // replace * with Ptr str = str.Replace("*", "Ptr"); // replace illegal characters - str = Regex.Replace(str, "[^a-zA-Z0-9_]", "_"); + str = Regex.Replace(str, allowScopeQualifiers? @"[^a-zA-Z0-9_\.:]" : "[^a-zA-Z0-9_]", "_"); // ensure identifier starts with a letter or _ (and is non-empty) if (!Regex.IsMatch(str, "^[a-zA-Z_]")) str = "_" + str; diff --git a/Il2CppInspector.Common/Reflection/TypeInfo.cs b/Il2CppInspector.Common/Reflection/TypeInfo.cs index bde9e4b..b98219a 100644 --- a/Il2CppInspector.Common/Reflection/TypeInfo.cs +++ b/Il2CppInspector.Common/Reflection/TypeInfo.cs @@ -297,8 +297,8 @@ namespace Il2CppInspector.Reflection return name; } - // Get rid of generic backticks - public string CSharpBaseName => unmangleName(base.Name); + // Get rid of generic backticks and invalid characters + public string CSharpBaseName => unmangleName(base.Name).ToCIdentifier(); // C# colloquial name of the type (if available) public override string CSharpName { @@ -315,8 +315,7 @@ namespace Il2CppInspector.Reflection } else { var s = Namespace + "." + base.Name; var i = Il2CppConstants.FullNameTypeString.IndexOf(s); - var n = (i != -1 ? Il2CppConstants.CSharpTypeString[i] : base.Name); - n = unmangleName(n); + var n = (i != -1 ? Il2CppConstants.CSharpTypeString[i] : CSharpBaseName); var ga = GetGenericArguments(); if (ga.Any()) n += "<" + string.Join(", ", ga.Select(x => x.CSharpName)) + ">"; @@ -339,7 +338,7 @@ namespace Il2CppInspector.Reflection n += "*"; return n; } else { - var n = unmangleName(base.Name); + var n = CSharpBaseName; var ga = IsNested ? GetGenericArguments().Where(p => DeclaringType.GetGenericArguments().All(dp => dp.Name != p.Name)) : GetGenericArguments(); if (ga.Any()) n += "<" + string.Join(", ", ga.Select(x => (!x.IsGenericTypeParameter ? x.Namespace + "." : "") + x.GetCSharpTypeDeclarationName(includeVariance: true))) + ">"; @@ -580,7 +579,7 @@ namespace Il2CppInspector.Reflection // Built-in keyword type names do not require a scope var i = Il2CppConstants.FullNameTypeString.IndexOf(s); var n = i != -1 ? Il2CppConstants.CSharpTypeString[i] : getScopedFullName(usingScope); - n = unmangleName(n); + n = unmangleName(n).ToCIdentifier(allowScopeQualifiers: true); // Generic type parameters and type arguments // Inheriting from a base class or implementing an interface use the type's declaring scope, not the type's scope itself