Skip to content

Scope of types for named values in attributes improperly set as assembly where attribute is defined #82

@KevinRansom

Description

@KevinRansom

This was originally opened at CodePlex by latkin

Original bug report
Runtime exception when using WSDL type provider: Could not load type 'System.Net.Security.ProtectionLevel' from assembly 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

Tooltip

{"Could not load type 'System.Net.Security.ProtectionLevel' from assembly 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.":"System.Net.Security.ProtectionLevel"} 

 Callstack 
 at System.Reflection.CustomAttribute._GetPropertyOrFieldData(RuntimeModule pModule, Byte** ppBlobStart, Byte* pBlobEnd, String& name, Boolean& bIsProperty, RuntimeType& type, Object& value) 
 at System.Reflection.CustomAttribute.GetPropertyOrFieldData(RuntimeModule module, IntPtr& blobStart, IntPtr blobEnd, String& name, Boolean& isProperty, RuntimeType& type, Object& value) 
 at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes, Boolean isDecoratedTargetSecurityTransparent) 
 at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, Boolean inherit) 
 at System.Reflection.RuntimeMethodInfo.GetCustomAttributes(Type attributeType, Boolean inherit) 
 at System.ServiceModel.Description.ServiceReflector.GetCustomAttributes(ICustomAttributeProvider attrProvider, Type attrType, Boolean inherit) 

Repro code:

#if INTERACTIVE
#r "System.Runtime.Serialization"
#r "System.ServiceModel"
#r "FSharp.Data.TypeProviders"
#endif

open System.Runtime.Serialization
open System
open System.Linq
open System.Collections.Generic
open System.Collections.Concurrent
open Microsoft.FSharp.Data.TypeProviders
open Microsoft.FSharp.Linq.NullableOperators
open System.ServiceModel

type TMS = WsdlService< ServiceUri = "http://[redacted]/TellusManagement/ExecutionService">

let Foo() =
    let endpointidentity = new DnsEndpointIdentity("localhost")
    let endpoint = new EndpointAddress( System.Uri("[redacted]/TellusManagement/ExecutionService/ExecutionService"), endpointidentity)
    let k2 = TMS.GetWSHttpBinding_IExecutionService1(endpoint)
    let _, _, _ = k2.GetInfoFromResourceAssignedTo("Quiver_ffe8bda3-2251-4a7a-9655-c45088caf368_Test_Machine")
    ()

Foo()

Comments
[Per Vladima] This is a bug in the implementation of type relocation, particularly - when moving custom attributes it uses assembly that contains attribute itself as a scope for types of all named values.

At glance ---> this <--- place looks incorrect (and has suspicious comment)
ilmorph.fs

     // We have a named value 
      let ty,sigptr = 
        // REVIEW: Post-M3, consider removing the restriction for scope - it's unnecessary
        // because you can reconstruct scope using the qualified name from the CA Blob
        if (0x50 = (int et) || 0x55 = (int et)) && Option.isSome scope then
            let qualified_tname,sigptr = sigptr_get_serstring bytes sigptr
            // we're already getting the qualified name from the binary blob
            // if we don't split out the unqualified name from the qualified name,
            // we'll write the qualified assembly reference string twice to the binary blob
***--->     let unqualified_tname = qualified_tname.Split([|','|]).[0]
            let scoref = Option.get scope                    
            let tref = mkILTyRef (scoref,unqualified_tname) <---***
            let tspec = mkILNonGenericTySpec tref
            ILType.Value(tspec),sigptr         

Fix: as suggested in comment reconstruct correct ILAssemblyRef using the information from qualified name

>comments
>dsyme wrote Jun 3, 2014 at 6:00 AM
>Yes, this analysis looks very likely to be correct. Great work, sublte bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions