Merge pull request #18017 from Snuffleupagus/validate-widths

Add more validation of width-data
This commit is contained in:
Jonas Jenwald 2024-04-29 14:17:23 +02:00 committed by GitHub
commit 627fe2d826
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -3892,66 +3892,97 @@ class PartialEvaluator {
let defaultWidth = 0; let defaultWidth = 0;
const glyphsVMetrics = []; const glyphsVMetrics = [];
let defaultVMetrics; let defaultVMetrics;
let i, ii, j, jj, start, code, widths;
if (properties.composite) { if (properties.composite) {
defaultWidth = dict.has("DW") ? dict.get("DW") : 1000; const dw = dict.get("DW");
defaultWidth = Number.isInteger(dw) ? dw : 1000;
const widths = dict.get("W");
if (Array.isArray(widths)) {
for (let i = 0, ii = widths.length; i < ii; i++) {
let start = xref.fetchIfRef(widths[i++]);
if (!Number.isInteger(start)) {
break; // Invalid /W data.
}
const code = xref.fetchIfRef(widths[i]);
widths = dict.get("W");
if (widths) {
for (i = 0, ii = widths.length; i < ii; i++) {
start = xref.fetchIfRef(widths[i++]);
code = xref.fetchIfRef(widths[i]);
if (Array.isArray(code)) { if (Array.isArray(code)) {
for (j = 0, jj = code.length; j < jj; j++) { for (const c of code) {
glyphsWidths[start++] = xref.fetchIfRef(code[j]); const width = xref.fetchIfRef(c);
if (typeof width === "number") {
glyphsWidths[start] = width;
}
start++;
} }
} else { } else if (Number.isInteger(code)) {
const width = xref.fetchIfRef(widths[++i]); const width = xref.fetchIfRef(widths[++i]);
for (j = start; j <= code; j++) { if (typeof width !== "number") {
continue;
}
for (let j = start; j <= code; j++) {
glyphsWidths[j] = width; glyphsWidths[j] = width;
} }
} else {
break; // Invalid /W data.
} }
} }
} }
if (properties.vertical) { if (properties.vertical) {
let vmetrics = dict.getArray("DW2") || [880, -1000]; const dw2 = dict.getArray("DW2");
let vmetrics = isNumberArray(dw2, 2) ? dw2 : [880, -1000];
defaultVMetrics = [vmetrics[1], defaultWidth * 0.5, vmetrics[0]]; defaultVMetrics = [vmetrics[1], defaultWidth * 0.5, vmetrics[0]];
vmetrics = dict.get("W2"); vmetrics = dict.get("W2");
if (vmetrics) { if (Array.isArray(vmetrics)) {
for (i = 0, ii = vmetrics.length; i < ii; i++) { for (let i = 0, ii = vmetrics.length; i < ii; i++) {
start = xref.fetchIfRef(vmetrics[i++]); let start = xref.fetchIfRef(vmetrics[i++]);
code = xref.fetchIfRef(vmetrics[i]); if (!Number.isInteger(start)) {
break; // Invalid /W2 data.
}
const code = xref.fetchIfRef(vmetrics[i]);
if (Array.isArray(code)) { if (Array.isArray(code)) {
for (j = 0, jj = code.length; j < jj; j++) { for (let j = 0, jj = code.length; j < jj; j++) {
glyphsVMetrics[start++] = [ const vmetric = [
xref.fetchIfRef(code[j++]), xref.fetchIfRef(code[j++]),
xref.fetchIfRef(code[j++]), xref.fetchIfRef(code[j++]),
xref.fetchIfRef(code[j]), xref.fetchIfRef(code[j]),
]; ];
if (isNumberArray(vmetric, null)) {
glyphsVMetrics[start] = vmetric;
}
start++;
} }
} else { } else if (Number.isInteger(code)) {
const vmetric = [ const vmetric = [
xref.fetchIfRef(vmetrics[++i]), xref.fetchIfRef(vmetrics[++i]),
xref.fetchIfRef(vmetrics[++i]), xref.fetchIfRef(vmetrics[++i]),
xref.fetchIfRef(vmetrics[++i]), xref.fetchIfRef(vmetrics[++i]),
]; ];
for (j = start; j <= code; j++) { if (!isNumberArray(vmetric, null)) {
continue;
}
for (let j = start; j <= code; j++) {
glyphsVMetrics[j] = vmetric; glyphsVMetrics[j] = vmetric;
} }
} else {
break; // Invalid /W2 data.
} }
} }
} }
} }
} else { } else {
const firstChar = properties.firstChar; const widths = dict.get("Widths");
widths = dict.get("Widths"); if (Array.isArray(widths)) {
if (widths) { let j = properties.firstChar;
j = firstChar; for (const w of widths) {
for (i = 0, ii = widths.length; i < ii; i++) { const width = xref.fetchIfRef(w);
glyphsWidths[j++] = xref.fetchIfRef(widths[i]); if (typeof width === "number") {
glyphsWidths[j] = width;
}
j++;
} }
defaultWidth = parseFloat(descriptor.get("MissingWidth")) || 0; const missingWidth = descriptor.get("MissingWidth");
defaultWidth = typeof missingWidth === "number" ? missingWidth : 0;
} else { } else {
// Trying get the BaseFont metrics (see comment above). // Trying get the BaseFont metrics (see comment above).
const baseFontName = dict.get("BaseFont"); const baseFontName = dict.get("BaseFont");