mirror of
https://github.com/UglyToad/PdfPig.git
synced 2026-03-10 00:23:29 +08:00
Fix buggy font (#283)
* Adds checksum on font file reading * fix name table parsing on broken table * only warn if checksum invalid, avoid exception with bounds check #258 also returns a null object when the object generation number exceeds ushort.maxvalue since this is the maximum allowed value and this broke tests attempting to parse all objects in the file from #258 * remove potentially problematic document it might be sensitive data * use ttf from file to test without including full file Co-authored-by: romain v <rvergnory@lucca.fr>
This commit is contained in:
@@ -22,10 +22,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
var strings = new TrueTypeNameRecord[count];
|
var strings = new TrueTypeNameRecord[count];
|
||||||
|
var offset = header.Offset + stringOffset;
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var nameRecord = names[i];
|
strings[i] = GetTrueTypeNameRecord(names[i], data, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NameTable(header, GetName(4, strings), GetName(1, strings), GetName(2, strings), strings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TrueTypeNameRecord GetTrueTypeNameRecord(NameRecordBuilder nameRecord, TrueTypeDataBytes data, uint offset)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
var encoding = OtherEncodings.Iso88591;
|
var encoding = OtherEncodings.Iso88591;
|
||||||
|
|
||||||
switch (nameRecord.PlatformId)
|
switch (nameRecord.PlatformId)
|
||||||
@@ -62,16 +71,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var position = header.Offset + stringOffset + nameRecord.Offset;
|
var position = offset + nameRecord.Offset;
|
||||||
|
|
||||||
|
if (position >= data.Length)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
data.Seek(position);
|
data.Seek(position);
|
||||||
|
|
||||||
var str = data.ReadString(nameRecord.Length, encoding);
|
var str = data.ReadString(nameRecord.Length, encoding);
|
||||||
|
|
||||||
strings[i] = nameRecord.ToNameRecord(str);
|
return nameRecord.ToNameRecord(str);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NameTable(header, GetName(4, strings), GetName(1, strings), GetName(2, strings), strings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetName(int nameId, TrueTypeNameRecord[] names)
|
private static string GetName(int nameId, TrueTypeNameRecord[] names)
|
||||||
@@ -84,7 +100,7 @@
|
|||||||
{
|
{
|
||||||
var name = names[i];
|
var name = names[i];
|
||||||
|
|
||||||
if (name.NameId != nameId)
|
if (name is null || name.NameId != nameId)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
namespace UglyToad.PdfPig.Fonts.TrueType.Parser
|
namespace UglyToad.PdfPig.Fonts.TrueType.Parser
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using Tables;
|
using Tables;
|
||||||
|
|
||||||
internal static class TableParser
|
internal static class TableParser
|
||||||
@@ -13,6 +14,20 @@
|
|||||||
|
|
||||||
public static T Parse<T>(TrueTypeHeaderTable table, TrueTypeDataBytes data, TableRegister.Builder register) where T : ITrueTypeTable
|
public static T Parse<T>(TrueTypeHeaderTable table, TrueTypeDataBytes data, TableRegister.Builder register) where T : ITrueTypeTable
|
||||||
{
|
{
|
||||||
|
//checksum https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6.html
|
||||||
|
uint sum = 0;
|
||||||
|
var nLongs = (table.Length + 3) / 4;
|
||||||
|
data.Seek(table.Offset);
|
||||||
|
while (nLongs-- > 0)
|
||||||
|
{
|
||||||
|
sum += (uint)data.ReadSignedInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sum != table.CheckSum)
|
||||||
|
{
|
||||||
|
Trace.TraceWarning("Table with invalid checksum found in TrueType font file.");
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof(T) == typeof(CMapTable))
|
if (typeof(T) == typeof(CMapTable))
|
||||||
{
|
{
|
||||||
return (T) (object) CMapTableParser.Parse(table, data, register);
|
return (T) (object) CMapTableParser.Parse(table, data, register);
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
string any = null;
|
string any = null;
|
||||||
foreach (var nameRecord in NameRecords)
|
foreach (var nameRecord in NameRecords)
|
||||||
{
|
{
|
||||||
if (nameRecord.NameId != 6)
|
if (nameRecord is null || nameRecord.NameId != 6)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,6 +210,20 @@ namespace UglyToad.PdfPig.Tests.Fonts.TrueType.Parser
|
|||||||
Assert.Equal(points, glyph.Points.Length);
|
Assert.Equal(points, glyph.Points.Length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ParseIssue258CorruptNameTable()
|
||||||
|
{
|
||||||
|
var bytes = TrueTypeTestHelper.GetFileBytes("issue-258-corrupt-name-table");
|
||||||
|
|
||||||
|
var input = new TrueTypeDataBytes(new ByteArrayInputBytes(bytes));
|
||||||
|
|
||||||
|
var font = TrueTypeFontParser.Parse(input);
|
||||||
|
|
||||||
|
Assert.NotNull(font);
|
||||||
|
Assert.NotNull(font.TableRegister.NameTable);
|
||||||
|
Assert.NotEmpty(font.TableRegister.NameTable.NameRecords);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -39,6 +39,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Remove="Fonts\TrueType\Andada-Regular.ttf" />
|
<EmbeddedResource Remove="Fonts\TrueType\Andada-Regular.ttf" />
|
||||||
<EmbeddedResource Remove="Fonts\TrueType\google-simple-doc.ttf" />
|
<EmbeddedResource Remove="Fonts\TrueType\google-simple-doc.ttf" />
|
||||||
|
<EmbeddedResource Remove="Fonts\TrueType\issue-258-corrupt-name-table.ttf" />
|
||||||
<EmbeddedResource Remove="Fonts\TrueType\PMingLiU.ttf" />
|
<EmbeddedResource Remove="Fonts\TrueType\PMingLiU.ttf" />
|
||||||
<EmbeddedResource Remove="Fonts\TrueType\Roboto-Regular.ttf" />
|
<EmbeddedResource Remove="Fonts\TrueType\Roboto-Regular.ttf" />
|
||||||
<EmbeddedResource Remove="Fonts\Type1\AdobeUtopia.pfa" />
|
<EmbeddedResource Remove="Fonts\Type1\AdobeUtopia.pfa" />
|
||||||
@@ -64,6 +65,9 @@
|
|||||||
<Content Include="Fonts\TrueType\google-simple-doc.ttf">
|
<Content Include="Fonts\TrueType\google-simple-doc.ttf">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Fonts\TrueType\issue-258-corrupt-name-table.ttf">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="Fonts\TrueType\PMingLiU.ttf">
|
<Content Include="Fonts\TrueType\PMingLiU.ttf">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|||||||
@@ -688,6 +688,11 @@
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (offset == 0 && reference.Generation > ushort.MaxValue)
|
||||||
|
{
|
||||||
|
return new ObjectToken(offset, reference, NullToken.Instance);
|
||||||
|
}
|
||||||
|
|
||||||
Seek(offset);
|
Seek(offset);
|
||||||
|
|
||||||
if (!MoveNext())
|
if (!MoveNext())
|
||||||
|
|||||||
Reference in New Issue
Block a user