• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SamboyCoding / Cpp2IL / 12312179808

13 Dec 2024 08:28AM UTC coverage: 27.996% (-0.1%) from 28.128%
12312179808

Pull #395

github

web-flow
Merge 48093bf01 into d297c56a8
Pull Request #395: String Public Key

1266 of 6293 branches covered (20.12%)

Branch coverage included in aggregate %.

4 of 40 new or added lines in 2 files covered. (10.0%)

2 existing lines in 1 file now uncovered.

3385 of 10320 relevant lines covered (32.8%)

124339.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

17.43
/LibCpp2IL/Metadata/Il2CppAssemblyNameDefinition.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Diagnostics.CodeAnalysis;
4
using System.Linq;
5

6
namespace LibCpp2IL.Metadata;
7

8
public class Il2CppAssemblyNameDefinition : ReadableClass
9
{
10
    public int nameIndex;
11
    public int cultureIndex;
12

13
    [Version(Max = 24.1f)] [Version(Min = 24.2f, Max = 24.3f)] //Not present in 24.15
14
    public int hashValueIndex;
15

16
    public int publicKeyIndex;
17
    public uint hash_alg;
18
    public int hash_len;
19
    public uint flags;
20
    public int major;
21
    public int minor;
22
    public int build;
23
    public int revision;
24
    public ulong publicKeyToken;
25

26
    public string Name => LibCpp2IlMain.TheMetadata!.GetStringFromIndex(nameIndex);
1,272✔
27
    public string Culture => LibCpp2IlMain.TheMetadata!.GetStringFromIndex(cultureIndex);
×
28

29
    public byte[]? PublicKey
30
    {
31
        get
32
        {
NEW
33
            if (IsAtLeast(24.4f) || Is(24.15f))
×
34
            {
35
                // 2018.4.34 until 2019 (24.15)
36
                // 2019.4.15 until 2020 (24.4)
37
                // 2020.1.11 until 2020.2.0 (24.4)
38
                // 2020.2.0b7 and later (27+)
NEW
39
                var result = LibCpp2IlMain.TheMetadata!.GetByteArrayFromIndex(publicKeyIndex);
×
NEW
40
                return result.Length == 0 ? null : result;
×
41
            }
42
            else
43
            {
NEW
44
                var str = LibCpp2IlMain.TheMetadata!.GetStringFromIndex(publicKeyIndex);
×
45

NEW
46
                if (str is "NULL")
×
NEW
47
                    return null; // No public key
×
48

49
                // mscorlib example:
50
                // "\x0\x0\x0\x0\x0\x0\x0\x0\x4\x0\x0\x0\x0\x0\x0\x0"
51
                // The string above is verbatim, so the backslashes are not escape characters and the quotes are part of the string.
NEW
52
                if (str.Length > 2 && str[0] is '"' && str[^1] is '"' && TryParseByteArray(str.AsSpan()[1..^1], out var result))
×
NEW
53
                    return result;
×
54

NEW
55
                return null; // Parsing failed
×
56
            }
57

NEW
58
            static bool IsHexDigit(char c) => c is (>= '0' and <= '9') or (>= 'A' and <= 'F') or (>= 'a' and <= 'f');
×
59

60
            static bool TryParseByte(ReadOnlySpan<char> characters, out byte result)
61
            {
62
#if NET6_0_OR_GREATER
NEW
63
                return byte.TryParse(characters, System.Globalization.NumberStyles.HexNumber, null, out result);
×
64
#else
65
                return byte.TryParse(characters.ToString(), System.Globalization.NumberStyles.HexNumber, null, out result);
66
#endif
67
            }
68

69
            static bool TryParseByteArray(ReadOnlySpan<char> characters, [NotNullWhen(true)] out byte[]? result)
70
            {
NEW
71
                var bytes = new List<byte>();
×
72

NEW
73
                var i = 0;
×
NEW
74
                while (i < characters.Length)
×
75
                {
76
                    // Each byte is represented by 3 or 4 characters.
77
                    // The first one is backslash.
78
                    // The second one is 'x'.
79
                    // The third and fourth (if present) ones are the hexadecimal representation of the byte.
NEW
80
                    if (i > characters.Length - 3 || characters[i] is not '\\' || characters[i + 1] is not 'x')
×
81
                    {
NEW
82
                        result = null;
×
NEW
83
                        return false;
×
84
                    }
85

NEW
86
                    i += 2;
×
87

NEW
88
                    if (!IsHexDigit(characters[i]))
×
89
                    {
NEW
90
                        result = null;
×
NEW
91
                        return false;
×
92
                    }
93

94
                    ReadOnlySpan<char> hexCharacters;
NEW
95
                    if (i + 1 < characters.Length && characters[i + 1] is not '\\')
×
96
                    {
NEW
97
                        if (!IsHexDigit(characters[i + 1]))
×
98
                        {
NEW
99
                            result = null;
×
NEW
100
                            return false;
×
101
                        }
NEW
102
                        hexCharacters = characters.Slice(i, 2);
×
NEW
103
                        i += 2;
×
104
                    }
105
                    else
106
                    {
NEW
107
                        hexCharacters = characters.Slice(i, 1);
×
NEW
108
                        i += 1;
×
109
                    }
110

NEW
111
                    if (!TryParseByte(hexCharacters, out var b))
×
112
                    {
NEW
113
                        result = null;
×
NEW
114
                        return false;
×
115
                    }
116

NEW
117
                    bytes.Add(b);
×
118
                }
119

NEW
120
                result = bytes.ToArray();
×
NEW
121
                return true;
×
122
            }
123
        }
124
    }
125

126
    /// <summary>
127
    /// This returns the public key token as a byte array, or null if the token is 0.
128
    /// </summary>
129
    /// <remarks>
130
    /// Returning null is necessary to match the behavior of AsmResolver.
131
    /// </remarks>
132
    public byte[]? PublicKeyToken
133
    {
134
        get
135
        {
UNCOV
136
            return publicKeyToken == default ? null : BitConverter.GetBytes(publicKeyToken);
×
137
        }
138
    }
139

140
    public string HashValue => LibCpp2IlMain.MetadataVersion > 24.3f ? "NULL" : LibCpp2IlMain.TheMetadata!.GetStringFromIndex(hashValueIndex);
×
141

142
    public override string ToString()
143
    {
144
        var pkt = string.Join("-", BitConverter.GetBytes(publicKeyToken).Select(b => b.ToString("X2")));
×
UNCOV
145
        return $"{Name}, Version={major}.{minor}.{build}.{revision}, PublicKeyToken={pkt}";
×
146
    }
147

148
    public override void Read(ClassReadingBinaryReader reader)
149
    {
150
        nameIndex = reader.ReadInt32();
1,061✔
151
        cultureIndex = reader.ReadInt32();
1,061✔
152
        if (IsAtMost(24.3f) && IsNot(24.15f))
1,061✔
153
            hashValueIndex = reader.ReadInt32();
193✔
154
        publicKeyIndex = reader.ReadInt32();
1,061✔
155
        hash_alg = reader.ReadUInt32();
1,061✔
156
        hash_len = reader.ReadInt32();
1,061✔
157
        flags = reader.ReadUInt32();
1,061✔
158
        major = reader.ReadInt32();
1,061✔
159
        minor = reader.ReadInt32();
1,061✔
160
        build = reader.ReadInt32();
1,061✔
161
        revision = reader.ReadInt32();
1,061✔
162
        publicKeyToken = reader.ReadUInt64();
1,061✔
163
    }
1,061✔
164
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc