dotnet/wpf · error · FileFormatException
FileFormatException(SourceUri, e)
Error message
FileFormatException(SourceUri, e)
What it means
TrueTypeFontDriver's constructor reads the font file's offset table; CheckedPointer bounds-checks every access and throws ArgumentOutOfRangeException when a table offset/size points outside the file. The driver catches it and rethrows FileFormatException(SourceUri, e), converting 'bad pointer' into 'this font file is malformed or truncated'.
Solutions
- Re-install or re-download the font file and verify its size/checksum
- Catch FileFormatException around font loading and fall back to a fallback font family
- Check InnerException for the CheckedPointer offset that ran out of range
- Validate the file is a real TrueType font (starts with 0x00010000 or 'true') before loading
Example fix
// before
driver = new TrueTypeFontDriver(stream, uri); // throws on truncated font
// after
try { driver = new TrueTypeFontDriver(stream, uri); }
catch (FileFormatException e) {
log.Warn($"Malformed font {uri}: {e.Message}");
driver = null; // fall back
} Defensive patterns
Strategy: try-catch
Validate before calling
using var fs = File.OpenRead(path);
if (fs.Length < 12) throw new IOException("Not a TrueType font: too small");
Span<byte> hdr = stackalloc byte[4]; fs.ReadExactly(hdr);
bool plausible = hdr[0]==0 && hdr[1]==1 && hdr[2]==0 && hdr[3]==0; // 0x00010000 Type guard
bool LooksLikeTrueType(byte[] b) => b.Length >= 4 && (b[0]==0 && b[1]==1 && b[2]==0 && b[3]==0 || b[0]==(byte)'t' && b[1]==(byte)'r' && b[2]==(byte)'u' && b[3]==(byte)'e');
Try / catch
try { LoadFont(stream); }
catch (FileFormatException e)
{
log.Warn($"Font {e.SourceUri} is malformed: {e.InnerException?.Message}");
UseFallbackFont();
} Prevention
- Verify font checksums after download/deployment
- Use binary-safe transfer for .ttf files
- Isolate each font load in its own try-catch so one bad file doesn't abort enumeration
When it happens
Trigger: Constructing a TrueTypeFontDriver (e.g. via ComputeTypefaceFontDriver / font enumeration) on a font stream whose header claims offsets or table lengths beyond the actual stream length.
Common situations: Corrupted font file from an interrupted download, font embedded in a resource that was truncated, disk-full during font deployment, running the parser on a non-font file renamed to .ttf.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- FileFormatException(SourceUri)
- Count must be 1 when CommitPolicies is set to…
- FileFormatException
- FileFormatException
- FileFormatException(new Uri(fileName…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/65c9bd0a91a0905d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontFace/FontDriver.cs:144
_technology = FontTechnology.TrueTypeCollection;
seekPosition += 4; // skip version
_numFaces = ReadOpenTypeLong(seekPosition);
}
else if (typeTag == TrueTypeTags.OTTO)
{
_technology = FontTechnology.PostscriptOpenType;
_numFaces = 1;
}
else
{
_technology = FontTechnology.TrueType;
_numFaces = 1;
}
}
catch (ArgumentOutOfRangeException e)
{
// convert exceptions from CheckedPointer to FileFormatException
throw new FileFormatException(SourceUri, e);
}
}
internal void SetFace(int faceIndex)
{
if (_technology == FontTechnology.TrueTypeCollection)
{
ArgumentOutOfRangeException.ThrowIfNegative(faceIndex);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(faceIndex, _numFaces);
}
else
{
if (faceIndex != 0)
throw new ArgumentOutOfRangeException(nameof(faceIndex), SR.FaceIndexValidOnlyForTTC);
}
try
{View on GitHub (pinned to 81131a70a4)