Skip to content

Commit 22932f7

Browse files
committed
Fix the loca table length when there is enough space for it
It fixes #13425.
1 parent 33e8579 commit 22932f7

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed

src/core/fonts.js

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2702,13 +2702,36 @@ class Font {
27022702
writeUint32(tables.maxp.data, 0, version);
27032703
}
27042704

2705+
let isGlyphLocationsLong = int16(
2706+
tables.head.data[50],
2707+
tables.head.data[51]
2708+
);
2709+
if (tables.loca) {
2710+
const locaLength = isGlyphLocationsLong
2711+
? (numGlyphs + 1) * 4
2712+
: (numGlyphs + 1) * 2;
2713+
if (tables.loca.length !== locaLength) {
2714+
warn("Incorrect 'loca' table length -- attempting to fix it.");
2715+
// The length of the loca table is wrong (see #13425), so we check if we
2716+
// have enough space to fix it.
2717+
const sortedTables = Object.values(tables)
2718+
.filter(Boolean)
2719+
.sort((a, b) => a.offset - b.offset);
2720+
const locaIndex = sortedTables.indexOf(tables.loca);
2721+
const nextTable = sortedTables[locaIndex + 1] || null;
2722+
if (nextTable && tables.loca.offset + locaLength < nextTable.offset) {
2723+
const previousPos = font.pos;
2724+
font.pos = font.start || 0;
2725+
font.skip(tables.loca.offset);
2726+
tables.loca.data = font.getBytes(locaLength);
2727+
tables.loca.length = locaLength;
2728+
font.pos = previousPos;
2729+
}
2730+
}
2731+
}
2732+
27052733
if (properties.scaleFactors?.length === numGlyphs && isTrueType) {
27062734
const { scaleFactors } = properties;
2707-
const isGlyphLocationsLong = int16(
2708-
tables.head.data[50],
2709-
tables.head.data[51]
2710-
);
2711-
27122735
const glyphs = new GlyfTable({
27132736
glyfTable: tables.glyf.data,
27142737
isGlyphLocationsLong,
@@ -2723,7 +2746,7 @@ class Font {
27232746

27242747
if (isLocationLong !== !!isGlyphLocationsLong) {
27252748
tables.head.data[50] = 0;
2726-
tables.head.data[51] = isLocationLong ? 1 : 0;
2749+
isGlyphLocationsLong = tables.head.data[51] = isLocationLong ? 1 : 0;
27272750
}
27282751

27292752
const metrics = tables.hmtx.data;
@@ -2801,10 +2824,6 @@ class Font {
28012824

28022825
let missingGlyphs = Object.create(null);
28032826
if (isTrueType) {
2804-
const isGlyphLocationsLong = int16(
2805-
tables.head.data[50],
2806-
tables.head.data[51]
2807-
);
28082827
const glyphsInfo = sanitizeGlyphLocations(
28092828
tables.loca,
28102829
tables.glyf,

test/pdfs/issue13425.pdf.link

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://github.com/mozilla/pdf.js/files/6529459/20200927_204903_509.pdf

test/test_manifest.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13115,5 +13115,13 @@
1311513115
"md5": "b85c798b9a4cc2cd4337d335321cc612",
1311613116
"rounds": 1,
1311713117
"type": "eq"
13118+
},
13119+
{
13120+
"id": "issue13425",
13121+
"file": "pdfs/issue13425.pdf",
13122+
"md5": "36854e6ad43b8e0446d3d64e8f2950bf",
13123+
"rounds": 1,
13124+
"link": true,
13125+
"type": "eq"
1311813126
}
1311913127
]

0 commit comments

Comments
 (0)