diff options
author | Tomáš Rylek <trylek@microsoft.com> | 2019-05-14 09:40:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-14 09:40:46 -0700 |
commit | e3227026f99b149f6f02afef5896306b7cd38270 (patch) | |
tree | 33b732297da090bc1e3d8ae1e19dbeca62ff472f /src/tools | |
parent | 57539cf1e5adc484be1d2dbaa5c537d32e705cdf (diff) | |
download | coreclr-e3227026f99b149f6f02afef5896306b7cd38270.tar.gz coreclr-e3227026f99b149f6f02afef5896306b7cd38270.tar.bz2 coreclr-e3227026f99b149f6f02afef5896306b7cd38270.zip |
Further improvements for R2RDump robustness in the presence of bugs (#24429)
Based on JanV's suggestion I have added checks for token ranges
to MetadataNameFormatter to make it resilient towards invalid
tokens.
Thanks
Tomas
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/r2rdump/DisassemblingTypeProvider.cs | 4 | ||||
-rw-r--r-- | src/tools/r2rdump/R2RSignature.cs | 21 |
2 files changed, 23 insertions, 2 deletions
diff --git a/src/tools/r2rdump/DisassemblingTypeProvider.cs b/src/tools/r2rdump/DisassemblingTypeProvider.cs index 19621f16c0..c8008fc021 100644 --- a/src/tools/r2rdump/DisassemblingTypeProvider.cs +++ b/src/tools/r2rdump/DisassemblingTypeProvider.cs @@ -64,7 +64,7 @@ namespace R2RDump public virtual string GetGenericMethodParameter(DisassemblingGenericContext genericContext, int index) { - if (index >= genericContext.MethodParameters.Length) + if (genericContext.MethodParameters == null || index >= genericContext.MethodParameters.Length) { return "!!" + index.ToString(); } @@ -73,7 +73,7 @@ namespace R2RDump public virtual string GetGenericTypeParameter(DisassemblingGenericContext genericContext, int index) { - if (index >= genericContext.TypeParameters.Length) + if (genericContext.TypeParameters == null || index >= genericContext.TypeParameters.Length) { return "!" + index.ToString(); } diff --git a/src/tools/r2rdump/R2RSignature.cs b/src/tools/r2rdump/R2RSignature.cs index 15773f072a..63d6ddf3ea 100644 --- a/src/tools/r2rdump/R2RSignature.cs +++ b/src/tools/r2rdump/R2RSignature.cs @@ -90,11 +90,26 @@ namespace R2RDump } /// <summary> + /// Check that the metadata handle has valid range in the appropriate table context. + /// </summary> + /// <param name="handle">Metadata handle to validate</param> + private void ValidateHandle(EntityHandle handle, TableIndex tableIndex) + { + int rowid = MetadataTokens.GetRowNumber(handle); + int tableRowCount = _metadataReader.GetTableRowCount(tableIndex); + if (rowid <= 0 || rowid > tableRowCount) + { + throw new NotImplementedException($"Invalid handle {MetadataTokens.GetToken(handle):X8} in table {tableIndex.ToString()} ({tableRowCount} rows)"); + } + } + + /// <summary> /// Emit a method specification. /// </summary> /// <param name="methodSpecHandle">Method specification handle</param> private string EmitMethodSpecificationName(MethodSpecificationHandle methodSpecHandle, string owningTypeOverride, string signaturePrefix) { + ValidateHandle(methodSpecHandle, TableIndex.MethodSpec); MethodSpecification methodSpec = _metadataReader.GetMethodSpecification(methodSpecHandle); DisassemblingGenericContext genericContext = new DisassemblingGenericContext(Array.Empty<string>(), Array.Empty<string>()); return EmitHandleName(methodSpec.Method, namespaceQualified: true, owningTypeOverride: owningTypeOverride, signaturePrefix: signaturePrefix) @@ -107,6 +122,7 @@ namespace R2RDump /// <param name="memberRefHandle">Member reference handle</param> private string EmitMemberReferenceName(MemberReferenceHandle memberRefHandle, string owningTypeOverride, string signaturePrefix) { + ValidateHandle(memberRefHandle, TableIndex.MemberRef); MemberReference memberRef = _metadataReader.GetMemberReference(memberRefHandle); StringBuilder builder = new StringBuilder(); DisassemblingGenericContext genericContext = new DisassemblingGenericContext(Array.Empty<string>(), Array.Empty<string>()); @@ -144,6 +160,7 @@ namespace R2RDump /// <param name="methodSpecHandle">Method definition handle</param> private string EmitMethodDefinitionName(MethodDefinitionHandle methodDefinitionHandle, string owningTypeOverride, string signaturePrefix) { + ValidateHandle(methodDefinitionHandle, TableIndex.MethodDef); MethodDefinition methodDef = _metadataReader.GetMethodDefinition(methodDefinitionHandle); DisassemblingGenericContext genericContext = new DisassemblingGenericContext(Array.Empty<string>(), Array.Empty<string>()); MethodSignature<string> methodSig = methodDef.DecodeSignature<string, DisassemblingGenericContext>(this, genericContext); @@ -229,6 +246,7 @@ namespace R2RDump /// <param name="signaturePrefix">Optional type name signature prefix</param> private string EmitTypeReferenceName(TypeReferenceHandle typeRefHandle, bool namespaceQualified, string signaturePrefix) { + ValidateHandle(typeRefHandle, TableIndex.TypeRef); TypeReference typeRef = _metadataReader.GetTypeReference(typeRefHandle); string typeName = EmitString(typeRef.Name); string output = ""; @@ -257,6 +275,7 @@ namespace R2RDump /// <returns></returns> private string EmitTypeDefinitionName(TypeDefinitionHandle typeDefHandle, bool namespaceQualified, string signaturePrefix) { + ValidateHandle(typeDefHandle, TableIndex.TypeDef); TypeDefinition typeDef = _metadataReader.GetTypeDefinition(typeDefHandle); string typeName = signaturePrefix + EmitString(typeDef.Name); if (typeDef.IsNested) @@ -288,6 +307,7 @@ namespace R2RDump /// <param name="namespaceQualified">When set to true, include namespace information</param> private string EmitTypeSpecificationName(TypeSpecificationHandle typeSpecHandle, bool namespaceQualified, string signaturePrefix) { + ValidateHandle(typeSpecHandle, TableIndex.TypeSpec); TypeSpecification typeSpec = _metadataReader.GetTypeSpecification(typeSpecHandle); DisassemblingGenericContext genericContext = new DisassemblingGenericContext(Array.Empty<string>(), Array.Empty<string>()); return typeSpec.DecodeSignature<string, DisassemblingGenericContext>(this, genericContext); @@ -303,6 +323,7 @@ namespace R2RDump /// <returns>Textual representation of the field declaration</returns> private string EmitFieldDefinitionName(FieldDefinitionHandle fieldDefHandle, bool namespaceQualified, string owningTypeOverride, string signaturePrefix) { + ValidateHandle(fieldDefHandle, TableIndex.Field); FieldDefinition fieldDef = _metadataReader.GetFieldDefinition(fieldDefHandle); DisassemblingGenericContext genericContext = new DisassemblingGenericContext(Array.Empty<string>(), Array.Empty<string>()); StringBuilder output = new StringBuilder(); |