Skip to content

Commit 7bbe430

Browse files
committed
Fix Windows PE test failures
1 parent 691073b commit 7bbe430

4 files changed

Lines changed: 56 additions & 9 deletions

File tree

‎src/LibObjectFile.Tests/PE/PEReaderTests.cs‎

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.Collections.Generic;
77
using System.Diagnostics;
8+
using System.Globalization;
89
using System.IO;
910
using System.Runtime.InteropServices;
1011
using System.Threading.Tasks;
@@ -162,6 +163,45 @@ public void TestCreatePE()
162163
Assert.AreEqual(156, process.ExitCode);
163164
}
164165
}
166+
167+
[TestMethod]
168+
public void TestReadShortDosStub()
169+
{
170+
var pe = new PEFile
171+
{
172+
// Some Windows binaries use a stub shorter than e_cparhdr * 16.
173+
DosStub = new byte[56]
174+
};
175+
using var stream = new MemoryStream();
176+
pe.Write(stream);
177+
178+
stream.Position = 0;
179+
var readPE = PEFile.Read(stream);
180+
181+
Assert.AreEqual(56, readPE.DosStub.Length);
182+
}
183+
184+
[TestMethod]
185+
public void TestPrinterUsesStableDateFormat()
186+
{
187+
var sourceFile = Path.Combine(AppContext.BaseDirectory, "PE", "NativeLibraryWin64.dll");
188+
using var stream = File.OpenRead(sourceFile);
189+
var peImage = PEFile.Read(stream);
190+
var writer = new StringWriter();
191+
var previousCulture = CultureInfo.CurrentCulture;
192+
193+
try
194+
{
195+
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("fr-FR");
196+
peImage.Print(writer);
197+
}
198+
finally
199+
{
200+
CultureInfo.CurrentCulture = previousCulture;
201+
}
202+
203+
StringAssert.Contains(writer.ToString(), "TimeStamp = 02/07/2106 06:28:15");
204+
}
165205

166206
[TestMethod]
167207
[DynamicData(nameof(GetWindowsExeAndDlls))]
@@ -285,4 +325,4 @@ public async Task TestTinyExe97Bytes()
285325

286326
await Verifier.Verify(afterReadText);
287327
}
288-
}
328+
}

‎src/LibObjectFile/PE/DataDirectory/PEResourceDirectoryEntry.cs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System;
88
using System.Collections.Generic;
99
using System.Diagnostics;
10+
using System.Globalization;
1011
using System.Runtime.CompilerServices;
1112
using System.Runtime.InteropServices;
1213
using System.Text;
@@ -254,7 +255,7 @@ protected override bool PrintMembers(StringBuilder builder)
254255
builder.Append(", ");
255256
}
256257

257-
builder.Append($"ByNames[{ByNames.Count}], ByIds[{ByIds.Count}] , TimeDateStamp = {TimeDateStamp}, MajorVersion = {MajorVersion}, MinorVersion = {MinorVersion}");
258+
builder.Append($"ByNames[{ByNames.Count}], ByIds[{ByIds.Count}] , TimeDateStamp = {TimeDateStamp.ToString("MM/dd/yyyy HH:mm:ss", CultureInfo.InvariantCulture)}, MajorVersion = {MajorVersion}, MinorVersion = {MinorVersion}");
258259

259260
return true;
260261
}

‎src/LibObjectFile/PE/PEFile.Read.cs‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,13 @@ public override unsafe void Read(PEImageReader reader)
9191
// Read the DOS stub
9292
var dosStubSize = DosHeader.SizeOfParagraphsHeader * 16;
9393

94-
if (dosStubSize + sizeof(PEDosHeader) > pePosition)
94+
// e_cparhdr describes the DOS header rather than the space available before
95+
// the PE header. Some Windows binaries have less than e_cparhdr * 16 bytes
96+
// available for the stub, so limit the stub to the actual available space.
97+
var availableDosStubSize = pePosition - sizeof(PEDosHeader);
98+
if (dosStubSize > availableDosStubSize)
9599
{
96-
diagnostics.Error(DiagnosticId.PE_ERR_InvalidDosStubSize, $"Invalid DOS stub size {dosStubSize} going beyond the PE header");
97-
return;
100+
dosStubSize = (int)availableDosStubSize;
98101
}
99102

100103
if (dosStubSize > 0)
@@ -743,4 +746,4 @@ private static void FillDirectoryWithStreams(PEImageReader imageReader, PEDataDi
743746
{
744747
FillSectionDataWithMissingStreams(imageReader, directory, directory.Content, (uint)(directory.Position + directory.HeaderSize), (uint)(directory.Size - directory.HeaderSize), null);
745748
}
746-
}
749+
}

‎src/LibObjectFile/PE/PEPrinter.cs‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the license.txt file in the project root for more information.
44

55
using System;
6+
using System.Globalization;
67
using System.IO;
78
using LibObjectFile.IO;
89
using static System.Runtime.InteropServices.JavaScript.JSType;
@@ -413,7 +414,7 @@ private static void Print(PEExceptionDirectory data, ref TextWriterIndenter writ
413414

414415
private static void Print(PEExportDirectory data, ref TextWriterIndenter writer)
415416
{
416-
writer.WriteLine($"{nameof(PEExportDirectory.TimeStamp)} = {data.TimeStamp}");
417+
writer.WriteLine($"{nameof(PEExportDirectory.TimeStamp)} = {FormatTimestamp(data.TimeStamp)}");
417418
writer.WriteLine($"{nameof(PEExportDirectory.MajorVersion)} = {data.MajorVersion}");
418419
writer.WriteLine($"{nameof(PEExportDirectory.MinorVersion)} = {data.MinorVersion}");
419420
writer.WriteLine($"{nameof(PEExportDirectory.OrdinalBase)} = 0x{data.OrdinalBase:X}");
@@ -575,7 +576,7 @@ private static void Print(PEResourceEntry data, ref TextWriterIndenter writer)
575576
writer.WriteLine($"> CodePage = {resourceFile.CodePage?.EncodingName ?? "null"}, Data = {resourceFile.Data}");
576577
break;
577578
case PEResourceDirectoryEntry dir:
578-
writer.WriteLine($"> ByNames[{dir.ByNames.Count}], ByIds[{dir.ByIds.Count}] , TimeDateStamp = {dir.TimeDateStamp}, Version = {dir.MajorVersion}.{dir.MinorVersion}");
579+
writer.WriteLine($"> ByNames[{dir.ByNames.Count}], ByIds[{dir.ByIds.Count}] , TimeDateStamp = {FormatTimestamp(dir.TimeDateStamp)}, Version = {dir.MajorVersion}.{dir.MinorVersion}");
579580
writer.Indent();
580581

581582
for (var i = 0; i < dir.ByNames.Count; i++)
@@ -740,4 +741,6 @@ static string PEParent(PEObjectBase? obj)
740741
return "";
741742
}
742743
}
743-
}
744+
745+
private static string FormatTimestamp(DateTime timestamp) => timestamp.ToString("MM/dd/yyyy HH:mm:ss", CultureInfo.InvariantCulture);
746+
}

0 commit comments

Comments
 (0)