diff options
author | Jb Evain <jbevain@gmail.com> | 2012-12-03 22:23:45 +0400 |
---|---|---|
committer | Jb Evain <jbevain@gmail.com> | 2012-12-03 22:23:45 +0400 |
commit | d9976f58f40fe9973a015198e1cc7d3773c4b640 (patch) | |
tree | 7ea9e57e120c42e74e4e07e18a7cfd52141c93ef | |
parent | 9bfe76be006fbf8cd2dc4df20b00764e8faecfc7 (diff) |
Properly read unsorted GenericParam, DeclSecl and CustomAttr tables
-rw-r--r-- | Mono.Cecil/AssemblyReader.cs | 117 | ||||
-rw-r--r-- | Mono.Cecil/MetadataSystem.cs | 18 | ||||
-rw-r--r-- | Mono.Cecil/TypeParser.cs | 8 | ||||
-rw-r--r-- | Mono/Empty.cs | 14 |
4 files changed, 106 insertions, 51 deletions
diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs index 89d300f..eb7bdb8 100644 --- a/Mono.Cecil/AssemblyReader.cs +++ b/Mono.Cecil/AssemblyReader.cs @@ -1787,25 +1787,35 @@ namespace Mono.Cecil { { InitializeGenericParameters (); - Range range; - if (!metadata.TryGetGenericParameterRange (provider, out range)) + Range [] ranges; + if (!metadata.TryGetGenericParameterRanges (provider, out ranges)) return false; - return range.Length > 0; + return RangesSize (ranges) > 0; } public Collection<GenericParameter> ReadGenericParameters (IGenericParameterProvider provider) { InitializeGenericParameters (); - Range range; - if (!metadata.TryGetGenericParameterRange (provider, out range) - || !MoveTo (Table.GenericParam, range.Start)) + Range [] ranges; + if (!metadata.TryGetGenericParameterRanges (provider, out ranges)) return new GenericParameterCollection (provider); metadata.RemoveGenericParameterRange (provider); - var generic_parameters = new GenericParameterCollection (provider, (int) range.Length); + var generic_parameters = new GenericParameterCollection (provider, RangesSize (ranges)); + + for (int i = 0; i < ranges.Length; i++) + ReadGenericParametersRange (ranges [i], provider, generic_parameters); + + return generic_parameters; + } + + void ReadGenericParametersRange (Range range, IGenericParameterProvider provider, GenericParameterCollection generic_parameters) + { + if (!MoveTo (Table.GenericParam, range.Start)) + return; for (uint i = 0; i < range.Length; i++) { ReadUInt16 (); // index @@ -1819,8 +1829,6 @@ namespace Mono.Cecil { generic_parameters.Add (parameter); } - - return generic_parameters; } void InitializeGenericParameters () @@ -1837,10 +1845,10 @@ namespace Mono.Cecil { }); } - Dictionary<MetadataToken, Range> InitializeRanges (Table table, Func<MetadataToken> get_next) + Dictionary<MetadataToken, Range []> InitializeRanges (Table table, Func<MetadataToken> get_next) { int length = MoveTo (table); - var ranges = new Dictionary<MetadataToken, Range> (length); + var ranges = new Dictionary<MetadataToken, Range []> (length); if (length == 0) return ranges; @@ -1855,20 +1863,34 @@ namespace Mono.Cecil { owner = next; range.Length++; } else if (next != owner) { - if (owner.RID != 0) - ranges.Add (owner, range); + AddRange (ranges, owner, range); range = new Range (i, 1); owner = next; } else range.Length++; } - if (owner != MetadataToken.Zero && !ranges.ContainsKey (owner)) - ranges.Add (owner, range); + AddRange (ranges, owner, range); return ranges; } + static void AddRange (Dictionary<MetadataToken, Range []> ranges, MetadataToken owner, Range range) + { + if (owner.RID == 0) + return; + + Range [] slots; + if (!ranges.TryGetValue (owner, out slots)) { + ranges.Add (owner, new [] { range }); + return; + } + + slots = slots.Resize (slots.Length + 1); + slots [slots.Length - 1] = range; + ranges [owner] = slots; + } + public bool HasGenericConstraints (GenericParameter generic_parameter) { InitializeGenericConstraints (); @@ -2332,23 +2354,35 @@ namespace Mono.Cecil { { InitializeCustomAttributes (); - Range range; - if (!metadata.TryGetCustomAttributeRange (owner, out range)) + Range [] ranges; + if (!metadata.TryGetCustomAttributeRanges (owner, out ranges)) return false; - return range.Length > 0; + return RangesSize (ranges) > 0; } public Collection<CustomAttribute> ReadCustomAttributes (ICustomAttributeProvider owner) { InitializeCustomAttributes (); - Range range; - if (!metadata.TryGetCustomAttributeRange (owner, out range) - || !MoveTo (Table.CustomAttribute, range.Start)) + Range [] ranges; + if (!metadata.TryGetCustomAttributeRanges (owner, out ranges)) return new Collection<CustomAttribute> (); - var custom_attributes = new Collection<CustomAttribute> ((int) range.Length); + var custom_attributes = new Collection<CustomAttribute> (RangesSize (ranges)); + + for (int i = 0; i < ranges.Length; i++) + ReadCustomAttributeRange (ranges [i], custom_attributes); + + metadata.RemoveCustomAttributeRange (owner); + + return custom_attributes; + } + + void ReadCustomAttributeRange (Range range, Collection<CustomAttribute> custom_attributes) + { + if (!MoveTo (Table.CustomAttribute, range.Start)) + return; for (int i = 0; i < range.Length; i++) { ReadMetadataToken (CodedIndex.HasCustomAttribute); @@ -2360,10 +2394,15 @@ namespace Mono.Cecil { custom_attributes.Add (new CustomAttribute (signature, constructor)); } + } - metadata.RemoveCustomAttributeRange (owner); + static int RangesSize (Range [] ranges) + { + uint size = 0; + for (int i = 0; i < ranges.Length; i++) + size += ranges [i].Length; - return custom_attributes; + return (int) size; } public byte [] ReadCustomAttributeBlob (uint signature) @@ -2455,23 +2494,35 @@ namespace Mono.Cecil { { InitializeSecurityDeclarations (); - Range range; - if (!metadata.TryGetSecurityDeclarationRange (owner, out range)) + Range [] ranges; + if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges)) return false; - return range.Length > 0; + return RangesSize (ranges) > 0; } public Collection<SecurityDeclaration> ReadSecurityDeclarations (ISecurityDeclarationProvider owner) { InitializeSecurityDeclarations (); - Range range; - if (!metadata.TryGetSecurityDeclarationRange (owner, out range) - || !MoveTo (Table.DeclSecurity, range.Start)) + Range [] ranges; + if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges)) return new Collection<SecurityDeclaration> (); - var security_declarations = new Collection<SecurityDeclaration> ((int) range.Length); + var security_declarations = new Collection<SecurityDeclaration> (RangesSize (ranges)); + + for (int i = 0; i < ranges.Length; i++) + ReadSecurityDeclarationRange (ranges [i], security_declarations); + + metadata.RemoveSecurityDeclarationRange (owner); + + return security_declarations; + } + + void ReadSecurityDeclarationRange (Range range, Collection<SecurityDeclaration> security_declarations) + { + if (!MoveTo (Table.DeclSecurity, range.Start)) + return; for (int i = 0; i < range.Length; i++) { var action = (SecurityAction) ReadUInt16 (); @@ -2480,10 +2531,6 @@ namespace Mono.Cecil { security_declarations.Add (new SecurityDeclaration (action, signature, module)); } - - metadata.RemoveSecurityDeclarationRange (owner); - - return security_declarations; } public byte [] ReadSecurityDeclarationBlob (uint signature) diff --git a/Mono.Cecil/MetadataSystem.cs b/Mono.Cecil/MetadataSystem.cs index 72b04f2..3ae2015 100644 --- a/Mono.Cecil/MetadataSystem.cs +++ b/Mono.Cecil/MetadataSystem.cs @@ -65,13 +65,13 @@ namespace Mono.Cecil { internal Dictionary<MetadataToken, uint> FieldMarshals; internal Dictionary<MetadataToken, Row<ElementType, uint>> Constants; internal Dictionary<uint, MetadataToken []> Overrides; - internal Dictionary<MetadataToken, Range> CustomAttributes; - internal Dictionary<MetadataToken, Range> SecurityDeclarations; + internal Dictionary<MetadataToken, Range []> CustomAttributes; + internal Dictionary<MetadataToken, Range []> SecurityDeclarations; internal Dictionary<uint, Range> Events; internal Dictionary<uint, Range> Properties; internal Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> Semantics; internal Dictionary<uint, Row<PInvokeAttributes, uint, uint>> PInvokes; - internal Dictionary<MetadataToken, Range> GenericParameters; + internal Dictionary<MetadataToken, Range []> GenericParameters; internal Dictionary<uint, MetadataToken []> GenericConstraints; static Dictionary<string, Row<ElementType, bool>> primitive_value_types; @@ -302,9 +302,9 @@ namespace Mono.Cecil { Events.Remove (type.token.RID); } - public bool TryGetGenericParameterRange (IGenericParameterProvider owner, out Range range) + public bool TryGetGenericParameterRanges (IGenericParameterProvider owner, out Range [] ranges) { - return GenericParameters.TryGetValue (owner.MetadataToken, out range); + return GenericParameters.TryGetValue (owner.MetadataToken, out ranges); } public void RemoveGenericParameterRange (IGenericParameterProvider owner) @@ -312,9 +312,9 @@ namespace Mono.Cecil { GenericParameters.Remove (owner.MetadataToken); } - public bool TryGetCustomAttributeRange (ICustomAttributeProvider owner, out Range range) + public bool TryGetCustomAttributeRanges (ICustomAttributeProvider owner, out Range [] ranges) { - return CustomAttributes.TryGetValue (owner.MetadataToken, out range); + return CustomAttributes.TryGetValue (owner.MetadataToken, out ranges); } public void RemoveCustomAttributeRange (ICustomAttributeProvider owner) @@ -322,9 +322,9 @@ namespace Mono.Cecil { CustomAttributes.Remove (owner.MetadataToken); } - public bool TryGetSecurityDeclarationRange (ISecurityDeclarationProvider owner, out Range range) + public bool TryGetSecurityDeclarationRanges (ISecurityDeclarationProvider owner, out Range [] ranges) { - return SecurityDeclarations.TryGetValue (owner.MetadataToken, out range); + return SecurityDeclarations.TryGetValue (owner.MetadataToken, out ranges); } public void RemoveSecurityDeclarationRange (ISecurityDeclarationProvider owner) diff --git a/Mono.Cecil/TypeParser.cs b/Mono.Cecil/TypeParser.cs index 3e633ea..90e04a6 100644 --- a/Mono.Cecil/TypeParser.cs +++ b/Mono.Cecil/TypeParser.cs @@ -173,13 +173,7 @@ namespace Mono.Cecil { return; } -#if !CF - Array.Resize (ref array, array.Length + 1); -#else - var copy = new T [array.Length + 1]; - Array.Copy (array, copy, array.Length); - array = copy; -#endif + array = array.Resize (array.Length + 1); array [array.Length - 1] = item; } diff --git a/Mono/Empty.cs b/Mono/Empty.cs index d043a35..820bc34 100644 --- a/Mono/Empty.cs +++ b/Mono/Empty.cs @@ -26,6 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; using Mono.Collections.Generic; namespace Mono { @@ -49,5 +50,18 @@ namespace Mono.Cecil { { return self == null || self.size == 0; } + + public static T [] Resize<T> (this T [] self, int length) + { +#if !CF + Array.Resize (ref self, length); +#else + var copy = new T [length]; + Array.Copy (self, copy, self.Length); + array = copy; +#endif + + return self; + } } } |