Skip to content

Commit 39c4905

Browse files
authored
[mono] Fix assembly name parser to accommodate non-ASCII UTF8 strings (#103363)
Fixes #103276 Added an automated test that the testcase failed in the above issue. It now passes with this change. Ideally, Mono should share the same assembly name parsing logic as CoreCLR, which is `AssemblyNameParser.TryParse`.
1 parent d7ae8c6 commit 39c4905

File tree

8 files changed

+44
-7
lines changed

8 files changed

+44
-7
lines changed

src/libraries/System.Runtime/tests/System.Reflection.Tests/GetTypeTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,14 @@ public void TestTypeIdentifierAttribute()
300300
Assert.Equal(42, mi.Invoke(null, args));
301301
}
302302

303+
[Fact]
304+
public void TestAssemblyNameWithInternationalChar()
305+
{
306+
Type testObj = typeof(Hello工程123.Program);
307+
var t = Type.GetType(testObj.AssemblyQualifiedName);
308+
Assert.NotNull(t);
309+
}
310+
303311
[Fact]
304312
public void IgnoreLeadingDotForTypeNamesWithoutNamespace()
305313
{
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System;
2+
3+
namespace System.Reflection.Hello工程123
4+
{
5+
public class Program
6+
{
7+
}
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
4+
</PropertyGroup>
5+
<ItemGroup>
6+
<Compile Include="Hello工程123.cs" />
7+
</ItemGroup>
8+
</Project>

src/libraries/System.Runtime/tests/System.Reflection.Tests/System.Reflection.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
<ProjectReference Include="UnloadableAssembly\UnloadableAssembly.csproj" />
7878
<ProjectReference Include="TestExe\System.Reflection.TestExe.csproj" />
7979
<ProjectReference Include="TestAssembly\TestAssembly.csproj" />
80+
<ProjectReference Include="Hello工程123\Hello工程123.csproj" />
8081
</ItemGroup>
8182
<ItemGroup Condition="'$(TargetOS)' == 'browser'">
8283
<WasmFilesToIncludeFromPublishDir Include="$(AssemblyName).dll" />
@@ -87,5 +88,6 @@
8788

8889
<!-- Assemblies that should be excluded from the bundle -->
8990
<__ExcludeFromBundle Include="TestAssembly.dll" />
91+
<__ExcludeFromBundle Include="Hello工程123.dll" />
9092
</ItemGroup>
9193
</Project>

src/mono/mono/eglib/eglib-remap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@
219219
#define g_wtf8_to_utf16 monoeg_g_wtf8_to_utf16
220220
#define g_utf8_to_utf16_custom_alloc monoeg_g_utf8_to_utf16_custom_alloc
221221
#define g_utf8_to_utf16le_custom_alloc monoeg_g_utf8_to_utf16le_custom_alloc
222+
#define g_utf8_validate_part monoeg_g_utf8_validate_part
222223
#define g_utf8_validate monoeg_g_utf8_validate
223224
#define g_vasprintf monoeg_g_vasprintf
224225
#define g_assertion_disable_global monoeg_assertion_disable_global

src/mono/mono/eglib/glib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,7 @@ g_async_safe_printf (gchar const *format, ...)
10671067
*/
10681068
extern const guchar g_utf8_jump_table[256];
10691069

1070+
gboolean g_utf8_validate_part (const unsigned char *inptr, size_t len);
10701071
gboolean g_utf8_validate (const gchar *str, gssize max_len, const gchar **end);
10711072
glong g_utf8_strlen (const gchar *str, gssize max);
10721073

src/mono/mono/eglib/gutf8.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ const guchar g_utf8_jump_table[256] = {
3030
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
3131
};
3232

33-
static gboolean
34-
utf8_validate (const unsigned char *inptr, size_t len)
33+
gboolean
34+
g_utf8_validate_part (const unsigned char *inptr, size_t len)
3535
{
3636
const unsigned char *ptr = inptr + len;
3737
unsigned char c;
@@ -105,7 +105,7 @@ g_utf8_validate (const gchar *str, gssize max_len, const gchar **end)
105105
if (max_len < 0) {
106106
while (*inptr != 0) {
107107
length = g_utf8_jump_table[*inptr];
108-
if (!utf8_validate (inptr, length)) {
108+
if (!g_utf8_validate_part (inptr, length)) {
109109
valid = FALSE;
110110
break;
111111
}
@@ -124,7 +124,7 @@ g_utf8_validate (const gchar *str, gssize max_len, const gchar **end)
124124
length = g_utf8_jump_table[*inptr];
125125
min = MIN (length, GSSIZE_TO_UINT (max_len - n));
126126

127-
if (!utf8_validate (inptr, min)) {
127+
if (!g_utf8_validate_part (inptr, min)) {
128128
valid = FALSE;
129129
break;
130130
}

src/mono/mono/metadata/reflection.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,8 +1548,17 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p)
15481548
}
15491549
assembly->name = p;
15501550
s = p;
1551-
while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@' || g_ascii_isspace (*p)))
1552-
p++;
1551+
guchar *inptr = (guchar *) p;
1552+
while (*p && (*p != ',') && (*p != '\0')) {
1553+
if (quoted && (*p == '"'))
1554+
break;
1555+
guint length = g_utf8_jump_table[*inptr];
1556+
if (!g_utf8_validate_part (inptr, length)) {
1557+
return 0;
1558+
}
1559+
p += length;
1560+
inptr += length;
1561+
}
15531562
if (quoted) {
15541563
if (*p != '"')
15551564
return 1;
@@ -1648,7 +1657,7 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p)
16481657
found_sep = 1;
16491658
continue;
16501659
}
1651-
/* failed */
1660+
/* Done processing */
16521661
if (!found_sep)
16531662
return 1;
16541663
}

0 commit comments

Comments
 (0)