public IList<IAttribute> Resolve(IAssembly currentAssembly) { // TODO: make this a per-assembly cache // CacheManager cache = currentAssembly.Compilation.CacheManager; // IList<IAttribute> result = (IList<IAttribute>)cache.GetShared(this); // if (result != null) // return result; ITypeResolveContext context = new SimpleTypeResolveContext(currentAssembly); BlobReader reader = new BlobReader(blob, currentAssembly); if (reader.ReadByte() != '.') { // should not use UnresolvedSecurityDeclaration for XML secdecls throw new InvalidOperationException(); } ResolveResult securityActionRR = securityAction.Resolve(context); uint attributeCount = reader.ReadCompressedUInt32(); IAttribute[] attributes = new IAttribute[attributeCount]; try { ReadSecurityBlob(reader, attributes, context, securityActionRR); } catch (NotSupportedException) { // ignore invalid blobs //Debug.WriteLine(ex.ToString()); } for (int i = 0; i < attributes.Length; i++) { if (attributes[i] == null) attributes[i] = new CecilResolvedAttribute(context, SpecialType.UnknownType); } return attributes; // return (IList<IAttribute>)cache.GetOrAddShared(this, attributes); }
public UnresolvedSecurityDeclarationBlob(int securityAction, byte[] blob) { BlobReader reader = new BlobReader(blob, null); this.securityAction = new SimpleConstantValue(securityActionTypeReference, securityAction); this.blob = blob; if (reader.ReadByte() == '.') { // binary attribute uint attributeCount = reader.ReadCompressedUInt32(); for (uint i = 0; i < attributeCount; i++) { unresolvedAttributes.Add(new UnresolvedSecurityAttribute(this, (int)i)); } } else { // for backward compatibility with .NET 1.0: XML-encoded attribute var attr = new DefaultUnresolvedAttribute(permissionSetAttributeTypeReference); attr.ConstructorParameterTypes.Add(securityActionTypeReference); attr.PositionalArguments.Add(this.securityAction); string xml = System.Text.Encoding.Unicode.GetString(blob); attr.AddNamedPropertyArgument("XML", new SimpleConstantValue(KnownTypeReference.String, xml)); unresolvedAttributes.Add(attr); } }
void DecodeBlob(List<ResolveResult> positionalArguments, List<KeyValuePair<IMember, ResolveResult>> namedArguments) { if (blob == null) return; BlobReader reader = new BlobReader(blob, context.CurrentAssembly); if (reader.ReadUInt16() != 0x0001) { //Debug.WriteLine("Unknown blob prolog"); return; } foreach (var ctorParameter in ctorParameterTypes.Resolve(context)) { ResolveResult arg; bool isError; try { arg = reader.ReadFixedArg (ctorParameter); positionalArguments.Add(arg); isError = arg.IsError; } catch (Exception) { //Debug.WriteLine("Crash during blob decoding: " + ex); isError = true; } if (isError) { // After a decoding error, we must stop decoding the blob because // we might have read too few bytes due to the error. // Just fill up the remaining arguments with ErrorResolveResult: while (positionalArguments.Count < ctorParameterTypes.Count) positionalArguments.Add(ErrorResolveResult.UnknownError); return; } } try { ushort numNamed = reader.ReadUInt16(); for (int i = 0; i < numNamed; i++) { var namedArg = reader.ReadNamedArg(attributeType); if (namedArg.Key != null) namedArguments.Add(namedArg); } } catch (Exception) { //Debug.WriteLine("Crash during blob decoding: " + ex); } }
void ReadSecurityBlob(BlobReader reader, IAttribute[] attributes, ITypeResolveContext context, ResolveResult securityActionRR) { for (int i = 0; i < attributes.Length; i++) { string attributeTypeName = reader.ReadSerString(); ITypeReference attributeTypeRef = ReflectionHelper.ParseReflectionName(attributeTypeName); IType attributeType = attributeTypeRef.Resolve(context); reader.ReadCompressedUInt32(); // ?? // The specification seems to be incorrect here, so I'm using the logic from Cecil instead. uint numNamed = reader.ReadCompressedUInt32(); var namedArgs = new List<KeyValuePair<IMember, ResolveResult>>((int)numNamed); for (uint j = 0; j < numNamed; j++) { var namedArg = reader.ReadNamedArg(attributeType); if (namedArg.Key != null) namedArgs.Add(namedArg); } attributes[i] = new DefaultAttribute( attributeType, positionalArguments: new ResolveResult[] { securityActionRR }, namedArguments: namedArgs); } }
void DecodeBlob(ICollection<ResolveResult> newPositionalArguments, ICollection<KeyValuePair<IMember, ResolveResult>> newNamedArguments) { if (blob == null) return; var reader = new BlobReader(blob, context.CurrentAssembly); if (reader.ReadUInt16() != 0x0001) { Debug.WriteLine("Unknown blob prolog"); return; } foreach (var ctorParameter in ctorParameterTypes.Resolve(context)) { ResolveResult arg = reader.ReadFixedArg(ctorParameter); newPositionalArguments.Add(arg); if (arg.IsError) { // After a decoding error, we must stop decoding the blob because // we might have read too few bytes due to the error. // Just fill up the remaining arguments with ErrorResolveResult: while (newPositionalArguments.Count < ctorParameterTypes.Count) newPositionalArguments.Add(ErrorResolveResult.UnknownError); return; } } ushort numNamed = reader.ReadUInt16(); for (int i = 0; i < numNamed; i++) { var namedArg = reader.ReadNamedArg(attributeType); if (namedArg.Key != null) newNamedArguments.Add(namedArg); } }
decimal? TryDecodeDecimalConstantAttribute(CustomAttributeData attribute) { if (attribute.ConstructorArguments.Count != 5) return null; var reader = new BlobReader(attribute.__GetBlob(), null); if (reader.ReadUInt16() != 0x0001) { Debug.WriteLine("Unknown blob prolog"); return null; } // DecimalConstantAttribute has the arguments (byte scale, byte sign, uint hi, uint mid, uint low) or (byte scale, byte sign, int hi, int mid, int low) // Both of these invoke the Decimal constructor (int lo, int mid, int hi, bool isNegative, byte scale) with explicit argument conversions if required. var ctorArgs = new object[attribute.ConstructorArguments.Count]; for (int i = 0; i < ctorArgs.Length; i++) { switch (attribute.ConstructorArguments[i].ArgumentType.FullName) { case "System.Byte": ctorArgs[i] = reader.ReadByte(); break; case "System.Int32": ctorArgs[i] = reader.ReadInt32(); break; case "System.UInt32": ctorArgs[i] = unchecked((int)reader.ReadUInt32()); break; default: return null; } } if (!ctorArgs.Select(a => a.GetType()).SequenceEqual(new[] { typeof(byte), typeof(byte), typeof(int), typeof(int), typeof(int) })) return null; return new decimal((int)ctorArgs[4], (int)ctorArgs[3], (int)ctorArgs[2], (byte)ctorArgs[1] != 0, (byte)ctorArgs[0]); }
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other) { return(other is UnresolvedAttributeBlob o && attributeType == o.attributeType && ctorParameterTypes == o.ctorParameterTypes && BlobReader.BlobEquals(blob, o.blob)); }
int ISupportsInterning.GetHashCodeForInterning() { return(attributeType.GetHashCode() ^ ctorParameterTypes.GetHashCode() ^ BlobReader.GetBlobHashCode(blob)); }