Jb Evain wrote:
I'll have to add support for that. As a very sad workaround, you can
go back to Cecil 0.6.x as found in Mono 2.8.
That won't work, as I'm working on a mono.merge implementation using
cecil 0.9 :-)
I'll see what I can do in implementing this myself, maybe I can provide
a patch...
I didn't find the exact format of this in the ECMA-335, only them mentioning calling "ToXML()" on the CustomAttribute... However, since .NET 1.x seems to be the only place where the XML format is used, I have implemented the ToXml()/FromXml() functions myself and included them in AssemblyReader.cs/AssemblyWriter.cs.

The current implementation is somewhat incomplete in that it
a) doesn't allow to write permissionsets for .NET 1.1 assemblies and
b) writes blob-style permissionsets including XML strings when modifying .NET 1.1 assemblies (which I'm not sure .NET 2.0 and above can handle)

Any chance of this going in to the main sources? I'll attach my code below. The downside is it adds a dependency to System.Xml.dll.

Thanks for the help on this (pointing me in the right direction), I really thought there was something wrong with our merge process :-)

Simon
--
AssemblyReader.cs:
SecurityAttribute ParseXmlSecurityDeclaration(string xmlString)
{
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xmlString);
    XmlNode permissionSet = xmlDoc.SelectSingleNode("/PermissionSet");
    if (permissionSet == null)
        return null;
XmlNode permissionSetClass = permissionSet.SelectSingleNode("@class"); // check version?
    if (permissionSetClass == null)
        return null;
    if (permissionSetClass.Value != "System.Security.PermissionSet")
        return null;
    XmlNode iPermission = permissionSet.SelectSingleNode("IPermission");
    if (iPermission == null)
        return null;
XmlNode iPermissionClass = iPermission.SelectSingleNode("@class"); // check version?
    if (iPermissionClass == null)
        return null;

// Create Namespace & Name from FullName, AssemblyName can be ignored since we look it up. Collection<string> classNamespace = new Collection<string>(iPermissionClass.Value.Split(',')[0].Split('.'));
    string className = classNamespace[classNamespace.Count - 1];
    classNamespace.RemoveAt(classNamespace.Count - 1);
SecurityAttribute attribute = new SecurityAttribute(module.TypeSystem.LookupType(string.Join(".", classNamespace.ToArray()), className));
    attribute.properties = new Collection<CustomAttributeNamedArgument>(1);
    foreach (XmlAttribute xmlAttr in iPermission.Attributes)
    {
        if ((xmlAttr.Name != "class") && (xmlAttr.Name != "version"))
        {
            attribute.properties.Add(new CustomAttributeNamedArgument(
                xmlAttr.Name,
                new CustomAttributeArgument(
                    module.TypeSystem.String,
                    xmlAttr.Value)));
        }
    }
    return attribute;
}

void ReadXmlSecurityDeclaration(uint signature, SecurityDeclaration declaration)
{
    var blob = ReadBlob(signature);

    string xmlString = Encoding.Unicode.GetString(blob, 0, blob.Length);
    var attributes = new Collection<SecurityAttribute>(1);

    var attribute = ParseXmlSecurityDeclaration(xmlString);
    attributes.Add (attribute);

    declaration.security_attributes = attributes;
}

AssemblyWriter.cs:
SignatureWriter GetXmlSecurityDeclarationSignature(SecurityDeclaration declaration)
{
    SecurityAttribute sa = declaration.SecurityAttributes[0];
    TypeReference attrType = sa.AttributeType;
    AssemblyNameReference attrAsm = (AssemblyNameReference)attrType.Scope;
    string className = attrType.FullName + ", " + attrAsm.FullName;

    XmlDocument xmlDoc = new XmlDocument();

    XmlElement permissionSet = xmlDoc.CreateElement("PermissionSet");
    permissionSet.SetAttribute("class", "System.Security.PermissionSet");
    permissionSet.SetAttribute("version", "1");

    XmlElement iPermission = xmlDoc.CreateElement("IPermission");
    iPermission.SetAttribute("class", className);
    iPermission.SetAttribute("version", "1");
    foreach (var arg in sa.Properties)
    {
        iPermission.SetAttribute(arg.Name, arg.Argument.Value.ToString());
    }

    permissionSet.AppendChild(iPermission);
    xmlDoc.AppendChild(permissionSet);

    string xmlDocString = xmlDoc.InnerXml;
    byte[] bytes = Encoding.Unicode.GetBytes(xmlDocString);

    var signature = CreateSignatureWriter();
    signature.WriteBytes(bytes);
    return signature;
}

SignatureWriter GetSecurityDeclarationSignature(SecurityDeclaration declaration)
{
    var signature = CreateSignatureWriter();
    if (!declaration.resolved)
    {
        signature.WriteBytes(declaration.GetBlob());
        return signature;
    }
    if (module.Runtime <= TargetRuntime.Net_1_1)
    {
        return GetXmlSecurityDeclarationSignature(declaration);
    }
    //... old non-1.1 code as before
}

--
--
mono-cecil

Reply via email to