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); }); } [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); } [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); } } }