diff --git a/Il2CppInspector.Common/Outputs/CppDeclarations.cs b/Il2CppInspector.Common/Outputs/CppDeclarations.cs index c7a55a5..0171ff8 100644 --- a/Il2CppInspector.Common/Outputs/CppDeclarations.cs +++ b/Il2CppInspector.Common/Outputs/CppDeclarations.cs @@ -142,7 +142,7 @@ namespace Il2CppInspector.Outputs // Generate structure fields for each field of a given type private void GenerateFieldList(StringBuilder csrc, Namespace ns, TypeInfo ti) { - var namer = ns.MakeNamer((field) => sanitizeIdentifier(field.Name)); + var namer = ns.MakeNamer((field) => field.Name.ToCIdentifier()); foreach (var field in ti.DeclaredFields) { if (field.IsLiteral || field.IsStatic) continue; @@ -156,7 +156,7 @@ namespace Il2CppInspector.Outputs if (ti.IsEnum) { // Enums should be represented using enum syntax // They otherwise behave like value types - var namer = GlobalsNamespace.MakeNamer((field) => sanitizeIdentifier($"{name}_{field.Name}")); + var namer = GlobalsNamespace.MakeNamer((field) => $"{name}_{field.Name}".ToCIdentifier()); csrc.Append($"enum {name} : {AsCType(ti.GetEnumUnderlyingType())} {{\n"); foreach (var field in ti.DeclaredFields) { if (field.Name != "value__") @@ -386,7 +386,7 @@ namespace Il2CppInspector.Outputs vtable = ti.GetVTable(); } var name = TypeNamer.GetName(ti); - var namer = CreateNamespace().MakeNamer((i) => sanitizeIdentifier(vtable[i]?.Name ?? "__unknown")); + var namer = CreateNamespace().MakeNamer((i) => vtable[i]?.Name?.ToCIdentifier() ?? "__unknown"); // Il2Cpp switched to `VirtualInvokeData *vtable` in Unity 5.3.6. // Previous versions used `MethodInfo **vtable`. @@ -411,7 +411,7 @@ namespace Il2CppInspector.Outputs GenerateVTableStruct(csrc, ti); csrc.Append($"struct {name}__StaticFields {{\n"); - var namer = CreateNamespace().MakeNamer((field) => sanitizeIdentifier(field.Name)); + var namer = CreateNamespace().MakeNamer((field) => field.Name.ToCIdentifier()); foreach (var field in ti.DeclaredFields) { if (field.IsLiteral || !field.IsStatic) continue; @@ -489,7 +489,7 @@ namespace Il2CppInspector.Outputs var paramNs = CreateNamespace(); paramNs.ReserveName("method"); - var paramNamer = paramNs.MakeNamer((pi) => pi.Name == "" ? "arg" : sanitizeIdentifier(pi.Name)); + var paramNamer = paramNs.MakeNamer((pi) => pi.Name == "" ? "arg" : pi.Name.ToCIdentifier()); var paramList = new List(); // Figure out the "this" param @@ -551,7 +551,7 @@ namespace Il2CppInspector.Outputs TypeNamer = TypeNamespace.MakeNamer((ti) => { if (ti.IsArray) return TypeNamer.GetName(ti.ElementType) + "__Array"; - var name = sanitizeIdentifier(ti.Name); + var name = ti.Name.ToCIdentifier(); if (name.StartsWith("Il2Cpp")) name = "_" + name; name = Regex.Replace(name, "__+", "_"); @@ -563,7 +563,7 @@ namespace Il2CppInspector.Outputs }); GlobalsNamespace = CreateNamespace(); - MethodNamer = TypeNamespace.MakeNamer((method) => $"{TypeNamer.GetName(method.DeclaringType)}_{sanitizeIdentifier(method.Name)}"); + MethodNamer = TypeNamespace.MakeNamer((method) => $"{TypeNamer.GetName(method.DeclaringType)}_{method.Name.ToCIdentifier()}"); } // Reserve C/C++ keywords and built-in names @@ -580,8 +580,6 @@ namespace Il2CppInspector.Outputs return ns; } - private static string sanitizeIdentifier(string id) => Regex.Replace(id, "[^a-zA-Z0-9_]", "_"); - /// /// Namespace for all types and typedefs /// diff --git a/Il2CppInspector.Common/Outputs/IDAPythonScript.cs b/Il2CppInspector.Common/Outputs/IDAPythonScript.cs index 0ca123e..da7cb29 100644 --- a/Il2CppInspector.Common/Outputs/IDAPythonScript.cs +++ b/Il2CppInspector.Common/Outputs/IDAPythonScript.cs @@ -10,7 +10,6 @@ using System.IO; using System.Text; using Il2CppInspector.Reflection; using Il2CppInspector.Outputs.UnityHeaders; -using System.Text.RegularExpressions; namespace Il2CppInspector.Outputs { @@ -118,13 +117,9 @@ typedef __int64 int64_t; } } - private static string sanitizeIdentifier(string str) { - return Regex.Replace(str, "[^a-zA-Z0-9_]", "_"); - } - private static string stringToIdentifier(string str) { str = str.Substring(0, Math.Min(32, str.Length)); - return sanitizeIdentifier(str); + return str.ToCIdentifier(); } private void writeUsages() { diff --git a/Il2CppInspector.Common/Reflection/Extensions.cs b/Il2CppInspector.Common/Reflection/Extensions.cs index cccfb3c..b23bbe8 100644 --- a/Il2CppInspector.Common/Reflection/Extensions.cs +++ b/Il2CppInspector.Common/Reflection/Extensions.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; namespace Il2CppInspector.Reflection { @@ -83,6 +84,15 @@ namespace Il2CppInspector.Reflection return s.ToString(); } + public static string ToCIdentifier(this string str) { + // replace illegal characters + str = Regex.Replace(str, "[^a-zA-Z0-9_]", "_"); + // ensure identifier starts with a letter or _ (and is non-empty) + if (!Regex.IsMatch(str, "^[a-zA-Z_]")) + str = "_" + str; + return str; + } + // Output a value in C#-friendly syntax public static string ToCSharpValue(this object value, TypeInfo type, Scope usingScope = null) { if (value is bool)