From 5205495c29aee25f4a1882cfd4791540284b30dd Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Thu, 1 Feb 2024 09:50:35 -0800 Subject: [PATCH] Validate buffer length when reading PNG chunks --- .../Formats/Png/PngMetadataReader.cs | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/MetadataExtractor/Formats/Png/PngMetadataReader.cs b/MetadataExtractor/Formats/Png/PngMetadataReader.cs index 21a0742a8..d2bcfdee2 100644 --- a/MetadataExtractor/Formats/Png/PngMetadataReader.cs +++ b/MetadataExtractor/Formats/Png/PngMetadataReader.cs @@ -295,32 +295,50 @@ private static IEnumerable ProcessChunk(PngChunk chunk) } else if (chunkType == PngChunkType.tIME) { - var reader = new BufferReader(bytes, isBigEndian: true); - var year = reader.GetUInt16(); - var month = reader.GetByte(); - int day = reader.GetByte(); - int hour = reader.GetByte(); - int minute = reader.GetByte(); - int second = reader.GetByte(); var directory = new PngDirectory(PngChunkType.tIME); - if (DateUtil.IsValidDate(year, month, day) && DateUtil.IsValidTime(hour, minute, second)) + + if (bytes.Length < 2 + 1 + 1 + 1 + 1 + 1) { - var time = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Unspecified); - directory.Set(PngDirectory.TagLastModificationTime, time); + directory.AddError("Insufficient bytes for PNG tIME chunk."); } else { - directory.AddError($"PNG tIME data describes an invalid date/time: year={year} month={month} day={day} hour={hour} minute={minute} second={second}"); + var reader = new BufferReader(bytes, isBigEndian: true); + + var year = reader.GetUInt16(); + var month = reader.GetByte(); + int day = reader.GetByte(); + int hour = reader.GetByte(); + int minute = reader.GetByte(); + int second = reader.GetByte(); + + if (DateUtil.IsValidDate(year, month, day) && DateUtil.IsValidTime(hour, minute, second)) + { + var time = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Unspecified); + directory.Set(PngDirectory.TagLastModificationTime, time); + } + else + { + directory.AddError($"PNG tIME data describes an invalid date/time: year={year} month={month} day={day} hour={hour} minute={minute} second={second}"); + } + yield return directory; } - yield return directory; } else if (chunkType == PngChunkType.pHYs) { + var directory = new PngDirectory(PngChunkType.pHYs); + + if (bytes.Length < 4 + 4 + 1) + { + directory.AddError("Insufficient bytes for PNG pHYs chunk."); + } + var reader = new BufferReader(bytes, isBigEndian: true); + var pixelsPerUnitX = reader.GetInt32(); var pixelsPerUnitY = reader.GetInt32(); var unitSpecifier = reader.GetSByte(); - var directory = new PngDirectory(PngChunkType.pHYs); + directory.Set(PngDirectory.TagPixelsPerUnitX, pixelsPerUnitX); directory.Set(PngDirectory.TagPixelsPerUnitY, pixelsPerUnitY); directory.Set(PngDirectory.TagUnitSpecifier, unitSpecifier);