Skip to content

Commit

Permalink
Validate buffer length when reading PNG chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
iamcarbon committed Feb 1, 2024
1 parent 945686f commit 5205495
Showing 1 changed file with 31 additions and 13 deletions.
44 changes: 31 additions & 13 deletions MetadataExtractor/Formats/Png/PngMetadataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,32 +295,50 @@ private static IEnumerable<Directory> 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);
Expand Down

0 comments on commit 5205495

Please sign in to comment.