Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/cecil.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJb Evain <jb@evain.net>2021-06-24 04:55:44 +0300
committerGitHub <noreply@github.com>2021-06-24 04:55:44 +0300
commit0dd5556af12ab8fd053f9072a1f8e80d7a9608a7 (patch)
tree216bb4af5e9791393dc393c96d189f3aefd90a49 /symbols
parenta72c1b1e11762d940f95ffb662dbdf7f0de92a28 (diff)
Fix NRE when writing native pdb with type name exceeding PDB_MAX_PATH (#769)
* Add test with long type name * Fix definition and usage of IMetadataImport methods to handle long names
Diffstat (limited to 'symbols')
-rw-r--r--symbols/pdb/Mono.Cecil.Pdb.csproj1
-rw-r--r--symbols/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs109
-rw-r--r--symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs11
-rw-r--r--symbols/pdb/Test/Resources/assemblies/longtypename.dllbin0 -> 4096 bytes
-rw-r--r--symbols/pdb/Test/Resources/assemblies/longtypename.pdbbin0 -> 11776 bytes
5 files changed, 72 insertions, 49 deletions
diff --git a/symbols/pdb/Mono.Cecil.Pdb.csproj b/symbols/pdb/Mono.Cecil.Pdb.csproj
index 265159d..8e7d08c 100644
--- a/symbols/pdb/Mono.Cecil.Pdb.csproj
+++ b/symbols/pdb/Mono.Cecil.Pdb.csproj
@@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net40</TargetFrameworks>
<NoWarn>0649</NoWarn>
+ <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Cecil.csproj">
diff --git a/symbols/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs b/symbols/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs
index 297df0c..0bc32dc 100644
--- a/symbols/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs
+++ b/symbols/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs
@@ -5,8 +5,10 @@ using System.Text;
namespace Mono.Cecil.Pdb {
+ // WARNING: most methods should be reworked into PreserveSig methods
+
[ComImport, InterfaceType (ComInterfaceType.InterfaceIsIUnknown), Guid ("BA3FEE4C-ECB9-4e41-83B7-183FA41CD859")]
- interface IMetaDataEmit {
+ unsafe interface IMetaDataEmit {
void SetModuleProps (string szName);
void Save (string szFile, uint dwSaveFlags);
void SaveToStream (IntPtr pIStream, uint dwSaveFlags);
@@ -63,7 +65,7 @@ namespace Mono.Cecil.Pdb {
}
[ComImport, InterfaceType (ComInterfaceType.InterfaceIsIUnknown), Guid ("7DAC8207-D3AE-4c75-9B67-92801A497D44")]
- interface IMetaDataImport {
+ unsafe interface IMetaDataImport {
[PreserveSig]
void CloseEnum (uint hEnum);
uint CountEnum (uint hEnum);
@@ -74,7 +76,9 @@ namespace Mono.Cecil.Pdb {
uint FindTypeDefByName (string szTypeDef, uint tkEnclosingClass);
Guid GetScopeProps (StringBuilder szName, uint cchName, out uint pchName);
uint GetModuleFromScope ();
- uint GetTypeDefProps (uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags);
+
+ [PreserveSig]
+ uint GetTypeDefProps (uint td, char* szTypeDef, uint cchTypeDef, uint* pchTypeDef, uint* pdwTypeDefFlags, uint* ptkExtends);
uint GetInterfaceImplProps (uint iiImpl, out uint pClass);
uint GetTypeRefProps (uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName);
uint ResolveTypeRef (uint tr, [In] ref Guid riid, [MarshalAs (UnmanagedType.Interface)] out object ppIScope);
@@ -94,7 +98,9 @@ namespace Mono.Cecil.Pdb {
uint FindMethod (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob);
uint FindField (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob);
uint FindMemberRef (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob);
- uint GetMethodProps (uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA);
+
+ [PreserveSig]
+ uint GetMethodProps (uint mb, uint* pClass, char* szMethod, uint cchMethod, uint* pchMethod, uint* pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, uint* pulCodeRVA, uint* pdwImplFlags);
uint GetMemberRefProps (uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr /* byte* */ ppvSigBlob);
uint EnumProperties (ref uint phEnum, uint td, IntPtr /* uint* */ rProperties, uint cMax);
uint EnumEvents (ref uint phEnum, uint td, IntPtr /* uint* */ rEvents, uint cMax);
@@ -136,18 +142,22 @@ namespace Mono.Cecil.Pdb {
[PreserveSig]
[return: MarshalAs (UnmanagedType.Bool)]
bool IsValidToken (uint tk);
- uint GetNestedClassProps (uint tdNestedClass);
+ [PreserveSig]
+ uint GetNestedClassProps (uint tdNestedClass, uint* ptdEnclosingClass);
uint GetNativeCallConvFromSig (IntPtr /* void* */ pvSig, uint cbSig);
int IsGlobal (uint pd);
}
- class ModuleMetadata : IMetaDataEmit, IMetaDataImport {
+ unsafe class ModuleMetadata : IMetaDataEmit, IMetaDataImport {
readonly ModuleDefinition module;
Dictionary<uint, TypeDefinition> types;
Dictionary<uint, MethodDefinition> methods;
+ const uint S_OK = 0x00000000;
+ const uint E_FAIL = 0x80004005;
+
public ModuleMetadata (ModuleDefinition module)
{
this.module = module;
@@ -476,40 +486,22 @@ namespace Mono.Cecil.Pdb {
throw new NotImplementedException ();
}
- public uint GetTypeDefProps (uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags)
+ public uint GetTypeDefProps (uint td, char* szTypeDef, uint cchTypeDef, uint* pchTypeDef, uint* pdwTypeDefFlags, uint* ptkExtends)
{
TypeDefinition type;
- if (!TryGetType (td, out type)) {
- Marshal.WriteInt16 (szTypeDef, 0);
- pchTypeDef = 1;
- return 0;
- }
-
- WriteString (type.IsNested ? type.Name : type.FullName, szTypeDef, cchTypeDef, out pchTypeDef);
- WriteIntPtr (pdwTypeDefFlags, (uint) type.Attributes);
- return type.BaseType != null ? type.BaseType.MetadataToken.ToUInt32 () : 0;
- }
-
- static void WriteIntPtr (IntPtr ptr, uint value)
- {
- if (ptr == IntPtr.Zero)
- return;
+ if (!TryGetType (td, out type))
+ return E_FAIL;
- Marshal.WriteInt32 (ptr, (int) value);
- }
+ var name = type.IsNested ? type.Name : type.FullName;
- static void WriteString (string str, IntPtr buffer, uint bufferSize, out uint chars)
- {
- var length = str.Length + 1 >= bufferSize ? bufferSize - 1 : (uint) str.Length;
- chars = length + 1;
- var offset = 0;
+ WriteNameBuffer (name, szTypeDef, cchTypeDef, pchTypeDef);
- for (int i = 0; i < length; i++) {
- Marshal.WriteInt16 (buffer, offset, str [i]);
- offset += 2;
- }
+ if (pdwTypeDefFlags != null)
+ *pdwTypeDefFlags = (uint) type.Attributes;
+ if (ptkExtends != null)
+ *ptkExtends = type.BaseType != null ? type.BaseType.MetadataToken.ToUInt32 () : 0;
- Marshal.WriteInt16 (buffer, offset, 0);
+ return S_OK;
}
public uint GetInterfaceImplProps (uint iiImpl, out uint pClass)
@@ -597,22 +589,38 @@ namespace Mono.Cecil.Pdb {
throw new NotImplementedException ();
}
- public uint GetMethodProps (uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA)
+ public uint GetMethodProps (uint mb, uint* pClass, char* szMethod, uint cchMethod, uint* pchMethod, uint* pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, uint* pulCodeRVA, uint* pdwImplFlags)
{
MethodDefinition method;
- if (!TryGetMethod (mb, out method)) {
- Marshal.WriteInt16 (szMethod, 0);
- pchMethod = 1;
- pClass = 0;
- return 0;
- }
+ if (!TryGetMethod (mb, out method))
+ return E_FAIL;
+
+ if (pClass != null)
+ *pClass = method.DeclaringType.MetadataToken.ToUInt32 ();
+
+ WriteNameBuffer (method.Name, szMethod, cchMethod, pchMethod);
- pClass = method.DeclaringType.MetadataToken.ToUInt32 ();
- WriteString (method.Name, szMethod, cchMethod, out pchMethod);
- WriteIntPtr (pdwAttr, (uint) method.Attributes);
- WriteIntPtr (pulCodeRVA, (uint) method.RVA);
+ if (pdwAttr != null)
+ *pdwAttr = (uint) method.Attributes;
+ if (pulCodeRVA != null)
+ *pulCodeRVA = (uint) method.RVA;
+ if (pdwImplFlags != null)
+ *pdwImplFlags = (uint) method.ImplAttributes;
- return (uint) method.ImplAttributes;
+ return S_OK;
+ }
+
+ static void WriteNameBuffer(string name, char* buffer, uint bufferLength, uint* actualLength)
+ {
+ var length = Math.Min (name.Length, bufferLength - 1);
+ if (actualLength != null)
+ *actualLength = (uint) length;
+
+ if (buffer != null && bufferLength > 0) {
+ for (int i = 0; i < length; i++)
+ buffer [i] = name [i];
+ buffer [length + 1] = '\0';
+ }
}
public uint GetMemberRefProps (uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob)
@@ -770,13 +778,16 @@ namespace Mono.Cecil.Pdb {
throw new NotImplementedException ();
}
- public uint GetNestedClassProps (uint tdNestedClass)
+ public uint GetNestedClassProps (uint tdNestedClass, uint* ptdEnclosingClass)
{
TypeDefinition type;
if (!TryGetType (tdNestedClass, out type))
- return 0;
+ return E_FAIL;
+
+ if (ptdEnclosingClass != null)
+ *ptdEnclosingClass = type.IsNested ? type.DeclaringType.MetadataToken.ToUInt32 () : 0;
- return type.IsNested ? type.DeclaringType.MetadataToken.ToUInt32 () : 0;
+ return S_OK;
}
public uint GetNativeCallConvFromSig (IntPtr pvSig, uint cbSig)
diff --git a/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs b/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs
index 797f680..6f2d2fa 100644
--- a/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs
+++ b/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs
@@ -465,5 +465,16 @@ namespace Mono.Cecil.Tests {
Assert.AreEqual ("temp", method.DebugInformation.Scope.Variables [0].Name);
}
+
+ [Test]
+ public void TypeNameExceedingMaxPdbPath ()
+ {
+ if (!Platform.HasNativePdbSupport)
+ Assert.Ignore ();
+
+ TestModule ("longtypename.dll", module => {
+ Assert.IsTrue (module.HasSymbols);
+ }, symbolReaderProvider: typeof (NativePdbReaderProvider), symbolWriterProvider: typeof (NativePdbWriterProvider));
+ }
}
}
diff --git a/symbols/pdb/Test/Resources/assemblies/longtypename.dll b/symbols/pdb/Test/Resources/assemblies/longtypename.dll
new file mode 100644
index 0000000..803757f
--- /dev/null
+++ b/symbols/pdb/Test/Resources/assemblies/longtypename.dll
Binary files differ
diff --git a/symbols/pdb/Test/Resources/assemblies/longtypename.pdb b/symbols/pdb/Test/Resources/assemblies/longtypename.pdb
new file mode 100644
index 0000000..0c5ca89
--- /dev/null
+++ b/symbols/pdb/Test/Resources/assemblies/longtypename.pdb
Binary files differ