// dnlib: See LICENSE.txt for more info
using System;
using System.Collections.Generic;
using dnlib.IO;
namespace dnlib.DotNet {
///
/// Reads DeclSecurity blobs
///
public struct DeclSecurityReader {
DataReader reader;
readonly ModuleDef module;
readonly GenericParamContext gpContext;
///
/// Reads a DeclSecurity blob
///
/// Module that will own the returned list
/// #Blob offset of DeclSecurity signature
/// A list of s
public static IList Read(ModuleDefMD module, uint sig) => Read(module, module.BlobStream.CreateReader(sig), new GenericParamContext());
///
/// Reads a DeclSecurity blob
///
/// Module that will own the returned list
/// #Blob offset of DeclSecurity signature
/// Generic parameter context
/// A list of s
public static IList Read(ModuleDefMD module, uint sig, GenericParamContext gpContext) => Read(module, module.BlobStream.CreateReader(sig), gpContext);
///
/// Reads a DeclSecurity blob
///
/// Module that will own the returned list
/// DeclSecurity blob
/// A list of s
public static IList Read(ModuleDef module, byte[] blob) => Read(module, ByteArrayDataReaderFactory.CreateReader(blob), new GenericParamContext());
///
/// Reads a DeclSecurity blob
///
/// Module that will own the returned list
/// DeclSecurity blob
/// Generic parameter context///
/// A list of s
public static IList Read(ModuleDef module, byte[] blob, GenericParamContext gpContext) => Read(module, ByteArrayDataReaderFactory.CreateReader(blob), gpContext);
///
/// Reads a DeclSecurity blob
///
/// Module that will own the returned list
/// DeclSecurity stream that will be owned by us
/// A list of s
public static IList Read(ModuleDef module, DataReader signature) => Read(module, signature, new GenericParamContext());
///
/// Reads a DeclSecurity blob
///
/// Module that will own the returned list
/// DeclSecurity stream that will be owned by us
/// Generic parameter context
/// A list of s
public static IList Read(ModuleDef module, DataReader signature, GenericParamContext gpContext) {
var reader = new DeclSecurityReader(module, signature, gpContext);
return reader.Read();
}
DeclSecurityReader(ModuleDef module, DataReader reader, GenericParamContext gpContext) {
this.reader = reader;
this.module = module;
this.gpContext = gpContext;
}
IList Read() {
try {
if (reader.Position >= reader.Length)
return new List();
if (reader.ReadByte() == '.')
return ReadBinaryFormat();
reader.Position--;
return ReadXmlFormat();
}
catch {
return new List();
}
}
///
/// Reads the new (.NET Framework 2.0+) DeclSecurity blob format
///
///
IList ReadBinaryFormat() {
int numAttrs = (int)reader.ReadCompressedUInt32();
var list = new List(numAttrs);
for (int i = 0; i < numAttrs; i++) {
var name = ReadUTF8String();
// Use CA search rules. Some tools don't write the fully qualified name.
var attrRef = TypeNameParser.ParseReflection(module, UTF8String.ToSystemStringOrEmpty(name), new CAAssemblyRefFinder(module), gpContext);
/*int blobLength = (int)*/reader.ReadCompressedUInt32();
int numNamedArgs = (int)reader.ReadCompressedUInt32();
var namedArgs = CustomAttributeReader.ReadNamedArguments(module, ref reader, numNamedArgs, gpContext);
if (namedArgs is null)
throw new ApplicationException("Could not read named arguments");
list.Add(new SecurityAttribute(attrRef, namedArgs));
}
return list;
}
///
/// Reads the old (.NET Framework 1.x) DeclSecurity blob format
///
///
IList ReadXmlFormat() {
var xml = reader.ReadUtf16String((int)reader.Length / 2);
var sa = SecurityAttribute.CreateFromXml(module, xml);
return new List { sa };
}
UTF8String ReadUTF8String() {
uint len = reader.ReadCompressedUInt32();
return len == 0 ? UTF8String.Empty : new UTF8String(reader.ReadBytes((int)len));
}
}
}