Skip to content

Commit

Permalink
[maxp] Attempt to improve fixup of bad 'maxp' version numbers.
Browse files Browse the repository at this point in the history
If the version number is less than 0x00010000 (e.g. an example reported at
mozilla/pdf.js#16839 apparently has 0x0100),
it will be treated as version 0.5 and only the num_glyphs field is kept.

However, this can prevent the font working on Windows, which apparently
requires the full maxp table for truetype fonts.

So if the version number was bad, but there is in fact enough data to
parse as version 1.0, let's try correcting it to 1.0 rather than 0.5.

Also make the max_zones fixup more general, as the example font from the
above issue has max_zones=512(!). Correcting it to 2 should be harmless.
  • Loading branch information
jfkthame committed Nov 10, 2023
1 parent c9b38cf commit b3cc775
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 7 deletions.
5 changes: 5 additions & 0 deletions src/cff.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,11 @@ bool OpenTypeCFF::Parse(const uint8_t *data, size_t length) {
if (!maxp) {
return Error("Required maxp table missing");
}
if (maxp->version_1) {
Warning("Fixing incorrect maxp version for CFF font");
maxp->version_1 = false;
}

const uint16_t num_glyphs = maxp->num_glyphs;
const size_t sid_max = string_index.count + kNStdString;
// string_index.count == 0 is allowed.
Expand Down
27 changes: 20 additions & 7 deletions src/maxp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@ bool OpenTypeMAXP::Parse(const uint8_t *data, size_t length) {
return Error("numGlyphs is 0");
}

// Per https://learn.microsoft.com/en-gb/typography/opentype/spec/maxp,
// the only two 'maxp' version numbers are 0.5 (for CFF/CFF2) and 1.0
// (for TrueType).
if (version == 0x00005000) {
this->version_1 = false;
return true;
}

if (version != 0x00010000) {
Warning("Unrecognized version %08x, attempting to fix", version);
// If there's at least enough data to read as a version 1.0 table,
// we'll try that.
if (length >= 32) {
version = 0x00010000;
}
}

if (version >> 16 == 1) {
this->version_1 = true;
if (!table.ReadU16(&this->max_points) ||
Expand All @@ -47,19 +64,15 @@ bool OpenTypeMAXP::Parse(const uint8_t *data, size_t length) {
return Error("Failed to read version 1 table data");
}

if (this->max_zones == 0) {
if (this->max_zones < 1) {
// workaround for ipa*.ttf Japanese fonts.
Warning("Bad maxZones: %u", this->max_zones);
this->max_zones = 1;
} else if (this->max_zones == 3) {
// workaround for Ecolier-*.ttf fonts.
} else if (this->max_zones > 2) {
// workaround for Ecolier-*.ttf fonts and bad fonts in some PDFs
Warning("Bad maxZones: %u", this->max_zones);
this->max_zones = 2;
}

if ((this->max_zones != 1) && (this->max_zones != 2)) {
return Error("Bad maxZones: %u", this->max_zones);
}
} else {
this->version_1 = false;
}
Expand Down

0 comments on commit b3cc775

Please sign in to comment.