зеркало из https://github.com/mono/ikvm-fork.git
Added support for adding "new-style" declarative security (i.e. .NET 2.0 compatible).
This commit is contained in:
Родитель
5e56f47c94
Коммит
3ea4d4aa8f
|
@ -52,6 +52,7 @@ namespace IKVM.Reflection.Emit
|
|||
private List<ResourceFile> resourceFiles = new List<ResourceFile>();
|
||||
private List<ModuleBuilder> modules = new List<ModuleBuilder>();
|
||||
private List<CustomAttributeBuilder> customAttributes = new List<CustomAttributeBuilder>();
|
||||
private List<CustomAttributeBuilder> declarativeSecurity = new List<CustomAttributeBuilder>();
|
||||
|
||||
private struct ResourceFile
|
||||
{
|
||||
|
@ -128,6 +129,11 @@ namespace IKVM.Reflection.Emit
|
|||
}
|
||||
}
|
||||
|
||||
public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
|
||||
{
|
||||
declarativeSecurity.Add(customBuilder);
|
||||
}
|
||||
|
||||
public void SetEntryPoint(MethodBuilder mb)
|
||||
{
|
||||
SetEntryPoint(mb, PEFileKinds.ConsoleApplication);
|
||||
|
@ -221,6 +227,8 @@ namespace IKVM.Reflection.Emit
|
|||
manifestModule.SetAssemblyCustomAttribute(cab);
|
||||
}
|
||||
|
||||
manifestModule.AddDeclarativeSecurity(0x20000001, declarativeSecurity);
|
||||
|
||||
foreach (ResourceFile resfile in resourceFiles)
|
||||
{
|
||||
int fileToken = AddFile(manifestModule, resfile.FileName, 1 /*ContainsNoMetaData*/);
|
||||
|
|
|
@ -56,6 +56,11 @@ namespace IKVM.Reflection.Emit
|
|||
methodBuilder.SetCustomAttribute(customBuilder);
|
||||
}
|
||||
|
||||
public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
|
||||
{
|
||||
methodBuilder.__AddDeclarativeSecurity(customBuilder);
|
||||
}
|
||||
|
||||
public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
|
||||
{
|
||||
methodBuilder.AddDeclarativeSecurity(securityAction, permissionSet);
|
||||
|
|
|
@ -121,6 +121,37 @@ namespace IKVM.Reflection.Emit
|
|||
return str.ToArray();
|
||||
}
|
||||
|
||||
internal void WriteNamedArgForDeclSecurity(ByteBuffer bb)
|
||||
{
|
||||
// NumNamed
|
||||
int named = 0;
|
||||
if (cab.namedFields != null)
|
||||
{
|
||||
named += cab.namedFields.Length;
|
||||
}
|
||||
if (cab.namedProperties != null)
|
||||
{
|
||||
named += cab.namedProperties.Length;
|
||||
}
|
||||
WritePackedLen(named);
|
||||
if (cab.namedFields != null)
|
||||
{
|
||||
for (int i = 0; i < cab.namedFields.Length; i++)
|
||||
{
|
||||
WriteNamedArg(0x53, cab.namedFields[i].FieldType, cab.namedFields[i].Name, cab.fieldValues[i]);
|
||||
}
|
||||
}
|
||||
if (cab.namedProperties != null)
|
||||
{
|
||||
for (int i = 0; i < cab.namedProperties.Length; i++)
|
||||
{
|
||||
WriteNamedArg(0x54, cab.namedProperties[i].PropertyType, cab.namedProperties[i].Name, cab.propertyValues[i]);
|
||||
}
|
||||
}
|
||||
str.Position = 0;
|
||||
bb.Write(str);
|
||||
}
|
||||
|
||||
private void WriteNamedArg(byte fieldOrProperty, Type type, string name, object value)
|
||||
{
|
||||
str.WriteByte(fieldOrProperty);
|
||||
|
@ -459,6 +490,11 @@ namespace IKVM.Reflection.Emit
|
|||
return constructorArgs[pos];
|
||||
}
|
||||
|
||||
internal int ConstructorArgumentCount
|
||||
{
|
||||
get { return constructorArgs == null ? 0 : constructorArgs.Length; }
|
||||
}
|
||||
|
||||
internal object GetFieldValue(string name)
|
||||
{
|
||||
if (namedFields != null)
|
||||
|
@ -473,5 +509,11 @@ namespace IKVM.Reflection.Emit
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal void WriteNamedArgumentsForDeclSecurity(ModuleBuilder moduleBuilder, ByteBuffer bb)
|
||||
{
|
||||
BlobWriter bw = new BlobWriter(moduleBuilder, this);
|
||||
bw.WriteNamedArgForDeclSecurity(bb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace IKVM.Reflection.Emit
|
|||
private readonly CallingConventions callingConvention;
|
||||
private List<ParameterBuilder> parameters;
|
||||
private GenericTypeParameterBuilder[] gtpb;
|
||||
private List<CustomAttributeBuilder> declarativeSecurity;
|
||||
|
||||
internal MethodBuilder(TypeBuilder typeBuilder, string name, MethodAttributes attributes, CallingConventions callingConvention)
|
||||
{
|
||||
|
@ -282,6 +283,16 @@ namespace IKVM.Reflection.Emit
|
|||
}
|
||||
}
|
||||
|
||||
public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
|
||||
{
|
||||
attributes |= MethodAttributes.HasSecurity;
|
||||
if (declarativeSecurity == null)
|
||||
{
|
||||
declarativeSecurity = new List<CustomAttributeBuilder>();
|
||||
}
|
||||
declarativeSecurity.Add(customBuilder);
|
||||
}
|
||||
|
||||
public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
|
||||
{
|
||||
this.ModuleBuilder.AddDeclaritiveSecurity(pseudoToken, securityAction, permissionSet);
|
||||
|
@ -508,6 +519,11 @@ namespace IKVM.Reflection.Emit
|
|||
{
|
||||
rva = -1;
|
||||
}
|
||||
|
||||
if (declarativeSecurity != null)
|
||||
{
|
||||
this.ModuleBuilder.AddDeclarativeSecurity(pseudoToken, declarativeSecurity);
|
||||
}
|
||||
}
|
||||
|
||||
internal ModuleBuilder ModuleBuilder
|
||||
|
|
|
@ -332,6 +332,56 @@ namespace IKVM.Reflection.Emit
|
|||
this.Tables.DeclSecurity.AddRecord(rec);
|
||||
}
|
||||
|
||||
internal void AddDeclarativeSecurity(int token, List<CustomAttributeBuilder> declarativeSecurity)
|
||||
{
|
||||
Dictionary<int, List<CustomAttributeBuilder>> ordered = new Dictionary<int, List<CustomAttributeBuilder>>();
|
||||
foreach (CustomAttributeBuilder cab in declarativeSecurity)
|
||||
{
|
||||
int action;
|
||||
// check for HostProtectionAttribute without SecurityAction
|
||||
if (cab.ConstructorArgumentCount == 0)
|
||||
{
|
||||
action = (int)System.Security.Permissions.SecurityAction.LinkDemand;
|
||||
}
|
||||
else
|
||||
{
|
||||
action = (int)cab.GetConstructorArgument(0);
|
||||
}
|
||||
List<CustomAttributeBuilder> list;
|
||||
if (!ordered.TryGetValue(action, out list))
|
||||
{
|
||||
list = new List<CustomAttributeBuilder>();
|
||||
ordered.Add(action, list);
|
||||
}
|
||||
list.Add(cab);
|
||||
}
|
||||
foreach (KeyValuePair<int, List<CustomAttributeBuilder>> kv in ordered)
|
||||
{
|
||||
TableHeap.DeclSecurityTable.Record rec = new TableHeap.DeclSecurityTable.Record();
|
||||
rec.Action = (short)kv.Key;
|
||||
rec.Parent = token;
|
||||
rec.PermissionSet = WriteDeclSecurityBlob(kv.Value);
|
||||
this.Tables.DeclSecurity.AddRecord(rec);
|
||||
}
|
||||
}
|
||||
|
||||
private int WriteDeclSecurityBlob(List<CustomAttributeBuilder> list)
|
||||
{
|
||||
ByteBuffer namedArgs = new ByteBuffer(100);
|
||||
ByteBuffer bb = new ByteBuffer(list.Count * 100);
|
||||
bb.Write((byte)'.');
|
||||
bb.WriteCompressedInt(list.Count);
|
||||
foreach (CustomAttributeBuilder cab in list)
|
||||
{
|
||||
bb.Write(cab.Constructor.DeclaringType.AssemblyQualifiedName);
|
||||
namedArgs.Clear();
|
||||
cab.WriteNamedArgumentsForDeclSecurity(this, namedArgs);
|
||||
bb.WriteCompressedInt(namedArgs.Length);
|
||||
bb.Write(namedArgs);
|
||||
}
|
||||
return this.Blobs.Add(bb);
|
||||
}
|
||||
|
||||
public void DefineManifestResource(string name, Stream stream, ResourceAttributes attribute)
|
||||
{
|
||||
TableHeap.ManifestResourceTable.Record rec = new TableHeap.ManifestResourceTable.Record();
|
||||
|
|
|
@ -184,6 +184,7 @@ namespace IKVM.Reflection.Emit
|
|||
private TypeAttributes attribs;
|
||||
private TypeFlags typeFlags;
|
||||
private GenericTypeParameterBuilder[] gtpb;
|
||||
private List<CustomAttributeBuilder> declarativeSecurity;
|
||||
|
||||
[Flags]
|
||||
private enum TypeFlags
|
||||
|
@ -453,6 +454,16 @@ namespace IKVM.Reflection.Emit
|
|||
}
|
||||
}
|
||||
|
||||
public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
|
||||
{
|
||||
attribs |= TypeAttributes.HasSecurity;
|
||||
if (declarativeSecurity == null)
|
||||
{
|
||||
declarativeSecurity = new List<CustomAttributeBuilder>();
|
||||
}
|
||||
declarativeSecurity.Add(customBuilder);
|
||||
}
|
||||
|
||||
public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
|
||||
{
|
||||
this.ModuleBuilder.AddDeclaritiveSecurity(token, securityAction, permissionSet);
|
||||
|
@ -515,6 +526,10 @@ namespace IKVM.Reflection.Emit
|
|||
}
|
||||
events = null;
|
||||
}
|
||||
if (declarativeSecurity != null)
|
||||
{
|
||||
this.ModuleBuilder.AddDeclarativeSecurity(token, declarativeSecurity);
|
||||
}
|
||||
return new BakedType(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -160,6 +160,20 @@ namespace IKVM.Reflection.Emit.Writer
|
|||
Write(BitConverter.DoubleToInt64Bits(value));
|
||||
}
|
||||
|
||||
internal void Write(string str)
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
Write((byte)0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] buf = Encoding.UTF8.GetBytes(str);
|
||||
WriteCompressedInt(buf.Length);
|
||||
Write(buf);
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteCompressedInt(int value)
|
||||
{
|
||||
if (value <= 0x7F)
|
||||
|
|
Загрузка…
Ссылка в новой задаче