using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using Mono.Cecil;
using Mono.Cecil.Metadata;
using Mono.Cecil.PE;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
[TestFixture]
public class SecurityDeclarationTests : BaseTestFixture {
[Test]
public void XmlSecurityDeclaration ()
{
TestModule ("decsec-xml.dll", module => {
var type = module.GetType ("SubLibrary");
Assert.IsTrue (type.HasSecurityDeclarations);
Assert.AreEqual (1, type.SecurityDeclarations.Count);
var declaration = type.SecurityDeclarations [0];
Assert.AreEqual (SecurityAction.Deny, declaration.Action);
Assert.AreEqual (1, declaration.SecurityAttributes.Count);
var attribute = declaration.SecurityAttributes [0];
Assert.AreEqual ("System.Security.Permissions.PermissionSetAttribute", attribute.AttributeType.FullName);
Assert.AreEqual (1, attribute.Properties.Count);
var named_argument = attribute.Properties [0];
Assert.AreEqual ("XML", named_argument.Name);
var argument = named_argument.Argument;
Assert.AreEqual ("System.String", argument.Type.FullName);
const string permission_set = "\r\n\r\n\r\n";
Assert.AreEqual (permission_set, argument.Value);
});
}
[Test]
public void XmlNet_1_1SecurityDeclaration ()
{
TestModule ("decsec1-xml.dll", module => {
var type = module.GetType ("SubLibrary");
Assert.IsTrue (type.HasSecurityDeclarations);
Assert.AreEqual (1, type.SecurityDeclarations.Count);
var declaration = type.SecurityDeclarations [0];
Assert.AreEqual (SecurityAction.Deny, declaration.Action);
Assert.AreEqual (1, declaration.SecurityAttributes.Count);
var attribute = declaration.SecurityAttributes [0];
Assert.AreEqual ("System.Security.Permissions.PermissionSetAttribute", attribute.AttributeType.FullName);
Assert.AreEqual (1, attribute.Properties.Count);
var named_argument = attribute.Properties [0];
Assert.AreEqual ("XML", named_argument.Name);
var argument = named_argument.Argument;
Assert.AreEqual ("System.String", argument.Type.FullName);
const string permission_set = "\r\n\r\n\r\n";
Assert.AreEqual (permission_set, argument.Value);
});
}
#if !READ_ONLY
[Test]
public void DefineSecurityDeclarationByBlob ()
{
var file = Path.Combine(Path.GetTempPath(), "SecDecBlob.dll");
var module = ModuleDefinition.CreateModule ("SecDecBlob.dll", new ModuleParameters { Kind = ModuleKind.Dll, Runtime = TargetRuntime.Net_2_0 });
const string permission_set = "\r\n\r\n\r\n";
var declaration = new SecurityDeclaration (SecurityAction.Deny, Encoding.Unicode.GetBytes (permission_set));
module.Assembly.SecurityDeclarations.Add (declaration);
module.Write (file);
module = ModuleDefinition.ReadModule (file);
declaration = module.Assembly.SecurityDeclarations [0];
Assert.AreEqual (SecurityAction.Deny, declaration.Action);
Assert.AreEqual (1, declaration.SecurityAttributes.Count);
var attribute = declaration.SecurityAttributes [0];
Assert.AreEqual ("System.Security.Permissions.PermissionSetAttribute", attribute.AttributeType.FullName);
Assert.AreEqual (1, attribute.Properties.Count);
var named_argument = attribute.Properties [0];
Assert.AreEqual ("XML", named_argument.Name);
var argument = named_argument.Argument;
Assert.AreEqual ("System.String", argument.Type.FullName);
Assert.AreEqual (permission_set, argument.Value);
}
#endif
[Test]
public void SecurityDeclarationWithoutAttributes ()
{
TestModule ("empty-decsec-att.dll", module => {
var type = module.GetType ("TestSecurityAction.ModalUITypeEditor");
var method = type.GetMethod ("GetEditStyle");
Assert.IsNotNull (method);
Assert.AreEqual (1, method.SecurityDeclarations.Count);
var declaration = method.SecurityDeclarations [0];
Assert.AreEqual (SecurityAction.LinkDemand, declaration.Action);
Assert.AreEqual (1, declaration.SecurityAttributes.Count);
var attribute = declaration.SecurityAttributes [0];
Assert.AreEqual ("System.Security.Permissions.SecurityPermissionAttribute", attribute.AttributeType.FullName);
Assert.AreEqual (0, attribute.Fields.Count);
Assert.AreEqual (0, attribute.Properties.Count);
});
}
[Test]
public void AttributeSecurityDeclaration ()
{
TestModule ("decsec-att.dll", module => {
var type = module.GetType ("SubLibrary");
Assert.IsTrue (type.HasSecurityDeclarations);
Assert.AreEqual (1, type.SecurityDeclarations.Count);
var declaration = type.SecurityDeclarations [0];
Assert.AreEqual (SecurityAction.Deny, declaration.Action);
Assert.AreEqual (1, declaration.SecurityAttributes.Count);
var attribute = declaration.SecurityAttributes [0];
Assert.AreEqual ("System.Security.Permissions.SecurityPermissionAttribute", attribute.AttributeType.FullName);
Assert.AreEqual (1, attribute.Properties.Count);
var named_argument = attribute.Properties [0];
Assert.AreEqual ("UnmanagedCode", named_argument.Name);
var argument = named_argument.Argument;
Assert.AreEqual ("System.Boolean", argument.Type.FullName);
Assert.AreEqual (true, argument.Value);
});
}
static void AssertCustomAttributeArgument (string expected, CustomAttributeNamedArgument named_argument)
{
AssertCustomAttributeArgument (expected, named_argument.Argument);
}
static void AssertCustomAttributeArgument (string expected, CustomAttributeArgument argument)
{
var result = new StringBuilder ();
PrettyPrint (argument, result);
Assert.AreEqual (expected, result.ToString ());
}
static string PrettyPrint (CustomAttribute attribute)
{
var signature = new StringBuilder ();
signature.Append (".ctor (");
for (int i = 0; i < attribute.ConstructorArguments.Count; i++) {
if (i > 0)
signature.Append (", ");
PrettyPrint (attribute.ConstructorArguments [i], signature);
}
signature.Append (")");
return signature.ToString ();
}
static void PrettyPrint (CustomAttributeArgument argument, StringBuilder signature)
{
var value = argument.Value;
signature.Append ("(");
PrettyPrint (argument.Type, signature);
signature.Append (":");
PrettyPrintValue (argument.Value, signature);
signature.Append (")");
}
static void PrettyPrintValue (object value, StringBuilder signature)
{
if (value == null) {
signature.Append ("null");
return;
}
var arguments = value as CustomAttributeArgument [];
if (arguments != null) {
signature.Append ("{");
for (int i = 0; i < arguments.Length; i++) {
if (i > 0)
signature.Append (", ");
PrettyPrint (arguments [i], signature);
}
signature.Append ("}");
return;
}
switch (Type.GetTypeCode (value.GetType ())) {
case System.TypeCode.String:
signature.AppendFormat ("\"{0}\"", value);
break;
case System.TypeCode.Char:
signature.AppendFormat ("'{0}'", (char) value);
break;
default:
var formattable = value as IFormattable;
if (formattable != null) {
signature.Append (formattable.ToString (null, CultureInfo.InvariantCulture));
return;
}
if (value is CustomAttributeArgument) {
PrettyPrint ((CustomAttributeArgument) value, signature);
return;
}
break;
}
}
static void PrettyPrint (TypeReference type, StringBuilder signature)
{
if (type.IsArray) {
ArrayType array = (ArrayType) type;
signature.AppendFormat ("{0}[]", array.ElementType.etype.ToString ());
} else if (type.etype == ElementType.None) {
signature.Append (type.FullName);
} else
signature.Append (type.etype.ToString ());
}
static void AssertArgument (T value, CustomAttributeNamedArgument named_argument)
{
AssertArgument (value, named_argument.Argument);
}
static void AssertArgument (T value, CustomAttributeArgument argument)
{
AssertArgument (typeof (T).FullName, (object) value, argument);
}
static void AssertArgument (string type, object value, CustomAttributeArgument argument)
{
Assert.AreEqual (type, argument.Type.FullName);
Assert.AreEqual (value, argument.Value);
}
}
}