diff --git a/ICSharpCode.ILSpyX/Metadata/PdbDumper.cs b/ICSharpCode.ILSpyX/Metadata/PdbDumper.cs index e0a94a8b40..9a7b675fb4 100644 --- a/ICSharpCode.ILSpyX/Metadata/PdbDumper.cs +++ b/ICSharpCode.ILSpyX/Metadata/PdbDumper.cs @@ -20,6 +20,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Reflection.PortableExecutable; using System.Linq; using System.Text; using System.Text.Json; @@ -116,6 +117,13 @@ internal static ReaderParameters CreateReaderParameters(string? pdbFileName) static ModuleDefinition ReadModuleWithSymbols(string assemblyFileName, string? pdbFileName) { + using (var stream = File.OpenRead(assemblyFileName)) + using (var reader = new PEReader(stream)) + { + if (reader.ReadDebugDirectory().Any(e => e.Type == DebugDirectoryEntryType.EmbeddedPortablePdb + && DebugInfoUtils.IsEmbeddedPortablePdbTooLarge(reader, e))) + throw new NoDebugSymbolsException($"Embedded Portable PDB is too large for '{assemblyFileName}'."); + } var parameters = CreateReaderParameters(pdbFileName); ModuleDefinition module; try @@ -137,6 +145,14 @@ static ModuleDefinition ReadModuleWithSymbols(string assemblyFileName, string? p static ModuleDefinition ReadModuleWithSymbols(Stream assemblyStream, string assemblyName, string? pdbFileName) { + long position = assemblyStream.Position; + using (var reader = new PEReader(assemblyStream, PEStreamOptions.LeaveOpen)) + { + if (reader.ReadDebugDirectory().Any(e => e.Type == DebugDirectoryEntryType.EmbeddedPortablePdb + && DebugInfoUtils.IsEmbeddedPortablePdbTooLarge(reader, e))) + throw new NoDebugSymbolsException($"Embedded Portable PDB is too large for '{assemblyName}'."); + } + assemblyStream.Position = position; var parameters = new ReaderParameters { ReadSymbols = true, InMemory = true }; ApplyExplicitSymbolFile(parameters, pdbFileName); ModuleDefinition module; diff --git a/ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs b/ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs index 5605a941b8..a125343dbf 100644 --- a/ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs +++ b/ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Buffers.Binary; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection.Metadata; @@ -32,6 +33,23 @@ namespace ICSharpCode.ILSpyX.PdbProvider { public static class DebugInfoUtils { + internal const int MaxEmbeddedPortablePdbSize = 128 * 1024 * 1024; + + public static bool IsEmbeddedPortablePdbTooLarge(PEReader reader, DebugDirectoryEntry entry) + { + if (entry.DataSize < 8) + return false; + try + { + int offset = reader.IsLoadedImage ? entry.DataRelativeVirtualAddress : entry.DataPointer; + var data = reader.GetEntireImage().GetContent(offset, 8); + return BinaryPrimitives.ReadUInt32LittleEndian(data.AsSpan().Slice(4, 4)) > MaxEmbeddedPortablePdbSize; + } + catch (ArgumentOutOfRangeException) + { + return false; + } + } public static IDebugInfoProvider? LoadSymbols(PEFile module) { try @@ -131,6 +149,9 @@ static bool TryOpenPortablePdb(PEFile module, { if (entry.IsPortableCodeView) { + if (entry.Type == DebugDirectoryEntryType.EmbeddedPortablePdb + && IsEmbeddedPortablePdbTooLarge(reader, entry)) + return false; return reader.TryOpenAssociatedPortablePdb(module.FileName, OpenStream, out provider, out pdbFileName); } diff --git a/ILSpy/Metadata/DebugDirectoryTreeNode.cs b/ILSpy/Metadata/DebugDirectoryTreeNode.cs index 3e802b3303..396b511794 100644 --- a/ILSpy/Metadata/DebugDirectoryTreeNode.cs +++ b/ILSpy/Metadata/DebugDirectoryTreeNode.cs @@ -22,6 +22,7 @@ using System.Reflection.PortableExecutable; using ICSharpCode.Decompiler.Metadata; +using ICSharpCode.ILSpyX.PdbProvider; using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.ViewModels; @@ -104,6 +105,8 @@ protected override void LoadChildren() case DebugDirectoryEntryType.EmbeddedPortablePdb: try { + if (DebugInfoUtils.IsEmbeddedPortablePdbTooLarge(module.Reader, entry)) + break; var provider = module.Reader.ReadEmbeddedPortablePdbDebugDirectoryData(entry); var pdbMetadata = new MetadataFile( MetadataFile.MetadataFileKind.ProgramDebugDatabase,