summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Reflection/AssemblyName.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Reflection/AssemblyName.cs')
-rw-r--r--src/mscorlib/src/System/Reflection/AssemblyName.cs274
1 files changed, 222 insertions, 52 deletions
diff --git a/src/mscorlib/src/System/Reflection/AssemblyName.cs b/src/mscorlib/src/System/Reflection/AssemblyName.cs
index 051f3b5f0e..48eab33ee5 100644
--- a/src/mscorlib/src/System/Reflection/AssemblyName.cs
+++ b/src/mscorlib/src/System/Reflection/AssemblyName.cs
@@ -24,6 +24,7 @@ namespace System.Reflection {
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
+ using System.Text;
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
@@ -103,19 +104,12 @@ namespace System.Reflection {
public String CodeBase
{
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
get { return _CodeBase; }
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
set { _CodeBase = value; }
}
public String EscapedCodeBase
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (_CodeBase == null)
@@ -189,16 +183,15 @@ namespace System.Reflection {
* if the file contains an assembly manifest. This method causes
* the file to be opened and closed.
*/
- [System.Security.SecuritySafeCritical] // auto-generated
static public AssemblyName GetAssemblyName(String assemblyFile)
{
if(assemblyFile == null)
- throw new ArgumentNullException("assemblyFile");
+ throw new ArgumentNullException(nameof(assemblyFile));
Contract.EndContractBlock();
// Assembly.GetNameInternal() will not demand path discovery
// permission, so do that first.
- String fullPath = Path.GetFullPathInternal(assemblyFile);
+ string fullPath = Path.GetFullPath(assemblyFile);
new FileIOPermission( FileIOPermissionAccess.PathDiscovery, fullPath ).Demand();
return nGetFileInformation(fullPath);
}
@@ -230,7 +223,6 @@ namespace System.Reflection {
// The compressed version of the public key formed from a truncated hash.
// Will throw a SecurityException if _PublicKey is invalid
- [System.Security.SecuritySafeCritical] // auto-generated
public byte[] GetPublicKeyToken()
{
if (_PublicKeyToken == null)
@@ -279,7 +271,6 @@ namespace System.Reflection {
public String FullName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return nToString();
}
@@ -295,11 +286,10 @@ namespace System.Reflection {
return s;
}
- [System.Security.SecurityCritical] // auto-generated_required
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
//Allocate the serialization info and serialize our static data.
@@ -360,11 +350,10 @@ namespace System.Reflection {
m_siInfo = info;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public AssemblyName(String assemblyName)
{
if (assemblyName == null)
- throw new ArgumentNullException("assemblyName");
+ throw new ArgumentNullException(nameof(assemblyName));
Contract.EndContractBlock();
if ((assemblyName.Length == 0) ||
(assemblyName[0] == '\0'))
@@ -374,7 +363,6 @@ namespace System.Reflection {
nInit();
}
- [System.Security.SecuritySafeCritical] // auto-generated
static public bool ReferenceMatchesDefinition(AssemblyName reference,
AssemblyName definition)
{
@@ -389,7 +377,6 @@ namespace System.Reflection {
/// "parse" tells us to parse the simple name of the assembly as if it was the full name
/// almost never the right thing to do, but needed for compat
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern bool ReferenceMatchesDefinitionInternal(AssemblyName reference,
AssemblyName definition,
@@ -397,11 +384,9 @@ namespace System.Reflection {
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void nInit(out RuntimeAssembly assembly, bool forIntrospection, bool raiseResolveEvent);
- [System.Security.SecurityCritical] // auto-generated
internal void nInit()
{
RuntimeAssembly dummy = null;
@@ -486,54 +471,239 @@ namespace System.Reflection {
_StrongNameKeyPair = keyPair;
}
-#if !FEATURE_CORECLR
- void _AssemblyName.GetTypeInfoCount(out uint pcTInfo)
+ // This call opens and closes the file, but does not add the
+ // assembly to the domain.
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ static internal extern AssemblyName nGetFileInformation(String s);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern String nToString();
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern byte[] nGetPublicKeyToken();
+
+ static internal String EscapeCodeBase(String codebase)
{
- throw new NotImplementedException();
+ if (codebase == null)
+ return string.Empty;
+
+ int position = 0;
+ char[] dest = EscapeString(codebase, 0, codebase.Length, null, ref position, true, c_DummyChar, c_DummyChar, c_DummyChar);
+ if (dest == null)
+ return codebase;
+
+ return new string(dest, 0, position);
}
- void _AssemblyName.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
+ // This implementation of EscapeString has been copied from System.Private.Uri from corefx repo
+ // - forceX characters are always escaped if found
+ // - rsvd character will remain unescaped
+ //
+ // start - starting offset from input
+ // end - the exclusive ending offset in input
+ // destPos - starting offset in dest for output, on return this will be an exclusive "end" in the output.
+ //
+ // In case "dest" has lack of space it will be reallocated by preserving the _whole_ content up to current destPos
+ //
+ // Returns null if nothing has to be escaped AND passed dest was null, otherwise the resulting array with the updated destPos
+ //
+ internal unsafe static char[] EscapeString(string input, int start, int end, char[] dest, ref int destPos,
+ bool isUriString, char force1, char force2, char rsvd)
{
- throw new NotImplementedException();
+ int i = start;
+ int prevInputPos = start;
+ byte* bytes = stackalloc byte[c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar]; // 40*4=160
+
+ fixed (char* pStr = input)
+ {
+ for (; i < end; ++i)
+ {
+ char ch = pStr[i];
+
+ // a Unicode ?
+ if (ch > '\x7F')
+ {
+ short maxSize = (short)Math.Min(end - i, (int)c_MaxUnicodeCharsReallocate - 1);
+
+ short count = 1;
+ for (; count < maxSize && pStr[i + count] > '\x7f'; ++count)
+ ;
+
+ // Is the last a high surrogate?
+ if (pStr[i + count - 1] >= 0xD800 && pStr[i + count - 1] <= 0xDBFF)
+ {
+ // Should be a rare case where the app tries to feed an invalid Unicode surrogates pair
+ if (count == 1 || count == end - i)
+ throw new FormatException(Environment.GetResourceString("Arg_FormatException"));
+ // need to grab one more char as a Surrogate except when it's a bogus input
+ ++count;
+ }
+
+ dest = EnsureDestinationSize(pStr, dest, i,
+ (short)(count * c_MaxUTF_8BytesPerUnicodeChar * c_EncodedCharsPerByte),
+ c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar * c_EncodedCharsPerByte,
+ ref destPos, prevInputPos);
+
+ short numberOfBytes = (short)Encoding.UTF8.GetBytes(pStr + i, count, bytes,
+ c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar);
+
+ // This is the only exception that built in UriParser can throw after a Uri ctor.
+ // Should not happen unless the app tries to feed an invalid Unicode String
+ if (numberOfBytes == 0)
+ throw new FormatException(Environment.GetResourceString("Arg_FormatException"));
+
+ i += (count - 1);
+
+ for (count = 0; count < numberOfBytes; ++count)
+ EscapeAsciiChar((char)bytes[count], dest, ref destPos);
+
+ prevInputPos = i + 1;
+ }
+ else if (ch == '%' && rsvd == '%')
+ {
+ // Means we don't reEncode '%' but check for the possible escaped sequence
+ dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte,
+ c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+ if (i + 2 < end && EscapedAscii(pStr[i + 1], pStr[i + 2]) != c_DummyChar)
+ {
+ // leave it escaped
+ dest[destPos++] = '%';
+ dest[destPos++] = pStr[i + 1];
+ dest[destPos++] = pStr[i + 2];
+ i += 2;
+ }
+ else
+ {
+ EscapeAsciiChar('%', dest, ref destPos);
+ }
+ prevInputPos = i + 1;
+ }
+ else if (ch == force1 || ch == force2)
+ {
+ dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte,
+ c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+ EscapeAsciiChar(ch, dest, ref destPos);
+ prevInputPos = i + 1;
+ }
+ else if (ch != rsvd && (isUriString ? !IsReservedUnreservedOrHash(ch) : !IsUnreserved(ch)))
+ {
+ dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte,
+ c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+ EscapeAsciiChar(ch, dest, ref destPos);
+ prevInputPos = i + 1;
+ }
+ }
+
+ if (prevInputPos != i)
+ {
+ // need to fill up the dest array ?
+ if (prevInputPos != start || dest != null)
+ dest = EnsureDestinationSize(pStr, dest, i, 0, 0, ref destPos, prevInputPos);
+ }
+ }
+
+ return dest;
}
- void _AssemblyName.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
+ //
+ // ensure destination array has enough space and contains all the needed input stuff
+ //
+ private unsafe static char[] EnsureDestinationSize(char* pStr, char[] dest, int currentInputPos,
+ short charsToAdd, short minReallocateChars, ref int destPos, int prevInputPos)
{
- throw new NotImplementedException();
- }
+ if ((object)dest == null || dest.Length < destPos + (currentInputPos - prevInputPos) + charsToAdd)
+ {
+ // allocating or reallocating array by ensuring enough space based on maxCharsToAdd.
+ char[] newresult = new char[destPos + (currentInputPos - prevInputPos) + minReallocateChars];
+
+ if ((object)dest != null && destPos != 0)
+ Buffer.BlockCopy(dest, 0, newresult, 0, destPos << 1);
+ dest = newresult;
+ }
- void _AssemblyName.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
+ // ensuring we copied everything form the input string left before last escaping
+ while (prevInputPos != currentInputPos)
+ dest[destPos++] = pStr[prevInputPos++];
+ return dest;
+ }
+
+ internal static void EscapeAsciiChar(char ch, char[] to, ref int pos)
{
- throw new NotImplementedException();
+ to[pos++] = '%';
+ to[pos++] = s_hexUpperChars[(ch & 0xf0) >> 4];
+ to[pos++] = s_hexUpperChars[ch & 0xf];
}
-#endif
-#if FEATURE_APTCA
- internal string GetNameWithPublicKey()
+ internal static char EscapedAscii(char digit, char next)
{
- byte[] key = GetPublicKey();
+ if (!(((digit >= '0') && (digit <= '9'))
+ || ((digit >= 'A') && (digit <= 'F'))
+ || ((digit >= 'a') && (digit <= 'f'))))
+ {
+ return c_DummyChar;
+ }
+
+ int res = (digit <= '9')
+ ? ((int)digit - (int)'0')
+ : (((digit <= 'F')
+ ? ((int)digit - (int)'A')
+ : ((int)digit - (int)'a'))
+ + 10);
+
+ if (!(((next >= '0') && (next <= '9'))
+ || ((next >= 'A') && (next <= 'F'))
+ || ((next >= 'a') && (next <= 'f'))))
+ {
+ return c_DummyChar;
+ }
+
+ return (char)((res << 4) + ((next <= '9')
+ ? ((int)next - (int)'0')
+ : (((next <= 'F')
+ ? ((int)next - (int)'A')
+ : ((int)next - (int)'a'))
+ + 10)));
+ }
- // The following string should not be localized because it is used in security decisions.
- return Name + ", PublicKey=" + System.Security.Util.Hex.EncodeHexString(key);
+ private static unsafe bool IsReservedUnreservedOrHash(char c)
+ {
+ if (IsUnreserved(c))
+ {
+ return true;
+ }
+ return (RFC3986ReservedMarks.IndexOf(c) >= 0);
}
-#endif
- // This call opens and closes the file, but does not add the
- // assembly to the domain.
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static internal extern AssemblyName nGetFileInformation(String s);
+ internal static unsafe bool IsUnreserved(char c)
+ {
+ if (IsAsciiLetterOrDigit(c))
+ {
+ return true;
+ }
+ return (RFC3986UnreservedMarks.IndexOf(c) >= 0);
+ }
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern String nToString();
+ //Only consider ASCII characters
+ internal static bool IsAsciiLetter(char character)
+ {
+ return (character >= 'a' && character <= 'z') ||
+ (character >= 'A' && character <= 'Z');
+ }
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern byte[] nGetPublicKeyToken();
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static internal extern String EscapeCodeBase(String codeBase);
+ internal static bool IsAsciiLetterOrDigit(char character)
+ {
+ return IsAsciiLetter(character) || (character >= '0' && character <= '9');
+ }
+
+ private static readonly char[] s_hexUpperChars = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ internal const char c_DummyChar = (char)0xFFFF; //An Invalid Unicode character used as a dummy char passed into the parameter
+ private const short c_MaxAsciiCharsReallocate = 40;
+ private const short c_MaxUnicodeCharsReallocate = 40;
+ private const short c_MaxUTF_8BytesPerUnicodeChar = 4;
+ private const short c_EncodedCharsPerByte = 3;
+ private const string RFC3986ReservedMarks = @":/?#[]@!$&'()*+,;=";
+ private const string RFC3986UnreservedMarks = @"-._~";
}
}