Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 7bb7921

Browse files
jkotasatsushikan
authored andcommitted
Merge pull request dotnet/corert#3601 from dotnet/nmirror
Merge nmirror to master Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
1 parent 79ee21a commit 7bb7921

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed

src/mscorlib/shared/System.Private.CoreLib.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@
201201
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyKeyNameAttribute.cs" />
202202
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyMetadataAttribute.cs" />
203203
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyNameFlags.cs" />
204+
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyNameFormatter.cs" />
204205
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyProductAttribute.cs" />
205206
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblySignatureKeyAttribute.cs" />
206207
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyTitleAttribute.cs" />
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.IO;
6+
using System.Text;
7+
using System.Globalization;
8+
using System.Collections.Generic;
9+
10+
namespace System.Reflection
11+
{
12+
internal static class AssemblyNameFormatter
13+
{
14+
public static string ComputeDisplayName(string name, Version version, string cultureName, byte[] pkt, AssemblyNameFlags flags, AssemblyContentType contentType)
15+
{
16+
const int PUBLIC_KEY_TOKEN_LEN = 8;
17+
18+
if (name == string.Empty)
19+
throw new FileLoadException();
20+
21+
StringBuilder sb = new StringBuilder();
22+
if (name != null)
23+
{
24+
sb.AppendQuoted(name);
25+
}
26+
27+
if (version != null)
28+
{
29+
Version canonicalizedVersion = version.CanonicalizeVersion();
30+
if (canonicalizedVersion.Major != ushort.MaxValue)
31+
{
32+
sb.Append(", Version=");
33+
sb.Append(canonicalizedVersion.Major);
34+
35+
if (canonicalizedVersion.Minor != ushort.MaxValue)
36+
{
37+
sb.Append('.');
38+
sb.Append(canonicalizedVersion.Minor);
39+
40+
if (canonicalizedVersion.Build != ushort.MaxValue)
41+
{
42+
sb.Append('.');
43+
sb.Append(canonicalizedVersion.Build);
44+
45+
if (canonicalizedVersion.Revision != ushort.MaxValue)
46+
{
47+
sb.Append('.');
48+
sb.Append(canonicalizedVersion.Revision);
49+
}
50+
}
51+
}
52+
}
53+
}
54+
55+
if (cultureName != null)
56+
{
57+
if (cultureName == string.Empty)
58+
cultureName = "neutral";
59+
sb.Append(", Culture=");
60+
sb.AppendQuoted(cultureName);
61+
}
62+
63+
if (pkt != null)
64+
{
65+
if (pkt.Length > PUBLIC_KEY_TOKEN_LEN)
66+
throw new ArgumentException();
67+
68+
sb.Append(", PublicKeyToken=");
69+
if (pkt.Length == 0)
70+
sb.Append("null");
71+
else
72+
{
73+
foreach (byte b in pkt)
74+
{
75+
sb.Append(b.ToString("x2", CultureInfo.InvariantCulture));
76+
}
77+
}
78+
}
79+
80+
if (0 != (flags & AssemblyNameFlags.Retargetable))
81+
sb.Append(", Retargetable=Yes");
82+
83+
if (contentType == AssemblyContentType.WindowsRuntime)
84+
sb.Append(", ContentType=WindowsRuntime");
85+
86+
// NOTE: By design (desktop compat) AssemblyName.FullName and ToString() do not include ProcessorArchitecture.
87+
88+
return sb.ToString();
89+
}
90+
91+
private static void AppendQuoted(this StringBuilder sb, string s)
92+
{
93+
bool needsQuoting = false;
94+
const char quoteChar = '\"';
95+
96+
//@todo: App-compat: You can use double or single quotes to quote a name, and Fusion (or rather the IdentityAuthority) picks one
97+
// by some algorithm. Rather than guess at it, I'll just use double-quote consistently.
98+
if (s != s.Trim() || s.Contains("\"") || s.Contains("\'"))
99+
needsQuoting = true;
100+
101+
if (needsQuoting)
102+
sb.Append(quoteChar);
103+
104+
for (int i = 0; i < s.Length; i++)
105+
{
106+
bool addedEscape = false;
107+
foreach (KeyValuePair<char, string> kv in EscapeSequences)
108+
{
109+
string escapeReplacement = kv.Value;
110+
if (!(s[i] == escapeReplacement[0]))
111+
continue;
112+
if ((s.Length - i) < escapeReplacement.Length)
113+
continue;
114+
string prefix = s.Substring(i, escapeReplacement.Length);
115+
if (prefix == escapeReplacement)
116+
{
117+
sb.Append('\\');
118+
sb.Append(kv.Key);
119+
addedEscape = true;
120+
}
121+
}
122+
123+
if (!addedEscape)
124+
sb.Append(s[i]);
125+
}
126+
127+
if (needsQuoting)
128+
sb.Append(quoteChar);
129+
}
130+
131+
private static Version CanonicalizeVersion(this Version version)
132+
{
133+
ushort major = (ushort)version.Major;
134+
ushort minor = (ushort)version.Minor;
135+
ushort build = (ushort)version.Build;
136+
ushort revision = (ushort)version.Revision;
137+
138+
if (major == version.Major && minor == version.Minor && build == version.Build && revision == version.Revision)
139+
return version;
140+
141+
return new Version(major, minor, build, revision);
142+
}
143+
144+
public static KeyValuePair<char, string>[] EscapeSequences =
145+
{
146+
new KeyValuePair<char, string>('\\', "\\"),
147+
new KeyValuePair<char, string>(',', ","),
148+
new KeyValuePair<char, string>('=', "="),
149+
new KeyValuePair<char, string>('\'', "'"),
150+
new KeyValuePair<char, string>('\"', "\""),
151+
new KeyValuePair<char, string>('n', Environment.NewLine),
152+
new KeyValuePair<char, string>('t', "\t"),
153+
};
154+
}
155+
}
156+

0 commit comments

Comments
 (0)