#71 ignore malformed dates in true type header table. fix reading of dates from bytes

This commit is contained in:
Eliot Jones
2019-10-16 10:51:02 +01:00
parent e2c9db8d50
commit 6174877892
3 changed files with 53 additions and 27 deletions

View File

@@ -48,15 +48,15 @@
Assert.Equal(2048, font.TableRegister.HeaderTable.UnitsPerEm); Assert.Equal(2048, font.TableRegister.HeaderTable.UnitsPerEm);
Assert.Equal(2008, font.TableRegister.HeaderTable.Created.Year); Assert.Equal(2008, font.TableRegister.HeaderTable.Created.Year);
Assert.Equal(10, font.TableRegister.HeaderTable.Created.Month); Assert.Equal(09, font.TableRegister.HeaderTable.Created.Month);
Assert.Equal(13, font.TableRegister.HeaderTable.Created.Day); Assert.Equal(12, font.TableRegister.HeaderTable.Created.Day);
Assert.Equal(12, font.TableRegister.HeaderTable.Created.Hour); Assert.Equal(12, font.TableRegister.HeaderTable.Created.Hour);
Assert.Equal(29, font.TableRegister.HeaderTable.Created.Minute); Assert.Equal(29, font.TableRegister.HeaderTable.Created.Minute);
Assert.Equal(34, font.TableRegister.HeaderTable.Created.Second); Assert.Equal(34, font.TableRegister.HeaderTable.Created.Second);
Assert.Equal(2011, font.TableRegister.HeaderTable.Modified.Year); Assert.Equal(2011, font.TableRegister.HeaderTable.Modified.Year);
Assert.Equal(12, font.TableRegister.HeaderTable.Modified.Month); Assert.Equal(11, font.TableRegister.HeaderTable.Modified.Month);
Assert.Equal(31, font.TableRegister.HeaderTable.Modified.Day); Assert.Equal(30, font.TableRegister.HeaderTable.Modified.Day);
Assert.Equal(5, font.TableRegister.HeaderTable.Modified.Hour); Assert.Equal(5, font.TableRegister.HeaderTable.Modified.Hour);
Assert.Equal(13, font.TableRegister.HeaderTable.Modified.Minute); Assert.Equal(13, font.TableRegister.HeaderTable.Modified.Minute);
Assert.Equal(10, font.TableRegister.HeaderTable.Modified.Second); Assert.Equal(10, font.TableRegister.HeaderTable.Modified.Second);
@@ -158,6 +158,20 @@
var name = font.Name; var name = font.Name;
Assert.Equal("Andada Regular", name); Assert.Equal("Andada Regular", name);
Assert.Equal(1.001999m, font.TableRegister.HeaderTable.Revision);
Assert.Equal(11, font.TableRegister.HeaderTable.Flags);
Assert.Equal(1000, font.TableRegister.HeaderTable.UnitsPerEm);
Assert.Equal(2011, font.TableRegister.HeaderTable.Created.Year);
Assert.Equal(9, font.TableRegister.HeaderTable.Created.Month);
Assert.Equal(30, font.TableRegister.HeaderTable.Created.Day);
Assert.Equal(2017, font.TableRegister.HeaderTable.Modified.Year);
Assert.Equal(5, font.TableRegister.HeaderTable.Modified.Month);
Assert.Equal(4, font.TableRegister.HeaderTable.Modified.Day);
} }
[Fact] [Fact]

View File

@@ -2,6 +2,7 @@
{ {
using System; using System;
using Geometry; using Geometry;
using PdfPig.Exceptions;
/// <summary> /// <summary>
/// The 'head' table contains global information about the font. /// The 'head' table contains global information about the font.
@@ -99,8 +100,26 @@
throw new InvalidOperationException($"The units per em for this TrueType font was incorrect, value should be between 16 and 16384 but found {unitsPerEm} istead."); throw new InvalidOperationException($"The units per em for this TrueType font was incorrect, value should be between 16 and 16384 but found {unitsPerEm} istead.");
} }
var created = data.ReadInternationalDate(); DateTime created;
var modified = data.ReadInternationalDate(); try
{
created = data.ReadInternationalDate();
}
catch (PdfDocumentFormatException)
{
created = DateTime.MinValue;
}
DateTime modified;
try
{
modified = data.ReadInternationalDate();
}
catch (PdfDocumentFormatException)
{
modified = DateTime.MinValue;
}
var xMin = data.ReadSignedShort(); var xMin = data.ReadSignedShort();
var yMin = data.ReadSignedShort(); var yMin = data.ReadSignedShort();
var xMax = data.ReadSignedShort(); var xMax = data.ReadSignedShort();

View File

@@ -4,6 +4,7 @@
using System.IO; using System.IO;
using System.Text; using System.Text;
using IO; using IO;
using PdfPig.Exceptions;
internal class TrueTypeDataBytes internal class TrueTypeDataBytes
{ {
@@ -99,43 +100,35 @@
public long ReadLong() public long ReadLong()
{ {
ReadBuffered(internalBuffer, 8); var upper = (long)ReadSignedInt();
var lower = ReadSignedInt();
var result = FromBytes(internalBuffer, 0, 8); var result = (upper << 32) + (lower & 0xFFFFFFFF);
return result; return result;
} }
public DateTime ReadInternationalDate() public DateTime ReadInternationalDate()
{ {
// TODO: this returns the wrong value, investigate... var secondsSince1904 = ReadLong();
long secondsSince1904 = ReadLong();
var date = new DateTime(1904, 1, 1, 0, 0, 0, DateTimeKind.Utc); var date = new DateTime(1904, 1, 1, 0, 0, 0, DateTimeKind.Utc);
try
{
var result = date.AddSeconds(secondsSince1904); var result = date.AddSeconds(secondsSince1904);
result = result.AddMonths(1);
result = result.AddDays(1);
return result; return result;
} }
catch (ArgumentOutOfRangeException)
{
throw new PdfDocumentFormatException($"Invalid date offset ({secondsSince1904} seconds) encountered in TrueType header table.");
}
}
public void Seek(long position) public void Seek(long position)
{ {
inputBytes.Seek(position); inputBytes.Seek(position);
} }
private long FromBytes(byte[] buffer, int startIndex, int bytesToConvert)
{
long ret = 0;
for (int i = 0; i < bytesToConvert; i++)
{
ret = unchecked((ret << 8) | buffer[startIndex + i]);
}
return ret;
}
public int ReadSignedByte() public int ReadSignedByte()
{ {
ReadBuffered(internalBuffer, 1); ReadBuffered(internalBuffer, 1);