Harden assembly timestamp handling

This commit is contained in:
Andy Howard
2026-09-16 12:20:14 +01:00
parent 0a5ec1259e
commit 8ef6e12788
4 changed files with 183 additions and 52 deletions
@@ -0,0 +1,107 @@
using System;
using System.IO;
using System.Reflection;
using NUnit.Framework;
using Sarand.Net.Standard.Base.Utils;
namespace Sarand.UnitTests.Core.Base.Utils
{
[TestFixture]
public class AssemblyUtil_Tester
{
// --- Tests ---
[Test]
public void TryGetBuildDateTime_ReadsCoffTimestamp()
{
DateTime expected = new DateTime(2024, 7, 8, 9, 10, 11, DateTimeKind.Utc);
String assemblyPath = CreatePeFile((UInt32)(expected - DateTime.UnixEpoch).TotalSeconds);
try
{
Boolean result = AssemblyUtil.TryGetBuildDateTime(assemblyPath, out DateTime actual);
Assert.That(result, Is.True);
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual.Kind, Is.EqualTo(DateTimeKind.Utc));
}
finally
{
File.Delete(assemblyPath);
}
}
[Test]
public void TryGetBuildDateTime_ReturnsFalseForInvalidPeSignature()
{
String assemblyPath = CreatePeFile(0, 0);
try
{
Boolean result = AssemblyUtil.TryGetBuildDateTime(assemblyPath, out DateTime buildDateTime);
Assert.That(result, Is.False);
Assert.That(buildDateTime, Is.EqualTo(DateTime.MinValue));
}
finally
{
File.Delete(assemblyPath);
}
}
[Test]
public void TryGetBuildDateTime_ReturnsFalseForTruncatedFile()
{
String assemblyPath = Path.GetTempFileName();
try
{
Boolean result = AssemblyUtil.TryGetBuildDateTime(assemblyPath, out DateTime buildDateTime);
Assert.That(result, Is.False);
Assert.That(buildDateTime, Is.EqualTo(DateTime.MinValue));
}
finally
{
File.Delete(assemblyPath);
}
}
[Test]
public void TryGetBuildDateTime_ReadsLoadedAssembly()
{
Assembly assembly = typeof(AssemblyUtil).Assembly;
Boolean result = assembly.TryGetBuildDateTime(out DateTime buildDateTime);
Assert.That(result, Is.True);
Assert.That(buildDateTime.Kind, Is.EqualTo(DateTimeKind.Utc));
Assert.That(assembly.GetBuildDateTime(), Is.EqualTo(buildDateTime));
}
[Test]
public void TryGetBuildDateTime_RejectsNullAssembly()
{
Assembly assembly = null;
Assert.That(() => assembly.TryGetBuildDateTime(out _), Throws.ArgumentNullException);
}
// --- Test Support ---
private static String CreatePeFile(UInt32 timeDateStamp, UInt32 peSignature = 0x00004550)
{
const Int32 coffHeaderOffset = 0x80;
Byte[] content = new Byte[coffHeaderOffset + 12];
BitConverter.GetBytes((UInt32)coffHeaderOffset).CopyTo(content, 0x3c);
BitConverter.GetBytes(peSignature).CopyTo(content, coffHeaderOffset);
BitConverter.GetBytes(timeDateStamp).CopyTo(content, coffHeaderOffset + 8);
String path = Path.Combine(Path.GetTempPath(), $"AssemblyUtil-{Guid.NewGuid():N}.dll");
File.WriteAllBytes(path, content);
return path;
}
// --- The End ---
}
}