Re-factor the PDFDocument.documentInfo method

This removes the `DocumentInfoValidators` structure, and thus (slightly) simplifies the code overall. With these changes we only have to iterate through, and validate, the actually available Dictionary entries.
This commit is contained in:
Jonas Jenwald 2022-02-23 16:57:03 +01:00
parent 620174a23c
commit 6bd4e0f5af

View File

@ -20,7 +20,6 @@ import {
InvalidPDFException, InvalidPDFException,
isArrayBuffer, isArrayBuffer,
isArrayEqual, isArrayEqual,
isString,
OPS, OPS,
PageActionEventType, PageActionEventType,
RenderingIntentFlag, RenderingIntentFlag,
@ -1129,18 +1128,6 @@ class PDFDocument {
} }
get documentInfo() { get documentInfo() {
const DocumentInfoValidators = {
Title: isString,
Author: isString,
Subject: isString,
Keywords: isString,
Creator: isString,
Producer: isString,
CreationDate: isString,
ModDate: isString,
Trapped: isName,
};
let version = this._version; let version = this._version;
if ( if (
typeof version !== "string" || typeof version !== "string" ||
@ -1172,46 +1159,64 @@ class PDFDocument {
} }
info("The document information dictionary is invalid."); info("The document information dictionary is invalid.");
} }
if (!(infoDict instanceof Dict)) {
return shadow(this, "documentInfo", docInfo);
}
if (infoDict instanceof Dict) { for (const key of infoDict.getKeys()) {
// Fill the document info with valid entries from the specification, const value = infoDict.get(key);
// as well as any existing well-formed custom entries.
for (const key of infoDict.getKeys()) {
const value = infoDict.get(key);
if (DocumentInfoValidators[key]) { switch (key) {
// Make sure the (standard) value conforms to the specification. case "Title":
if (DocumentInfoValidators[key](value)) { case "Author":
docInfo[key] = case "Subject":
typeof value !== "string" ? value : stringToPDFString(value); case "Keywords":
} else { case "Creator":
info(`Bad value in document info for "${key}".`); case "Producer":
case "CreationDate":
case "ModDate":
if (typeof value === "string") {
docInfo[key] = stringToPDFString(value);
continue;
} }
} else { break;
case "Trapped":
if (value instanceof Name) {
docInfo[key] = value;
continue;
}
break;
default:
// For custom values, only accept white-listed types to prevent // For custom values, only accept white-listed types to prevent
// errors that would occur when trying to send non-serializable // errors that would occur when trying to send non-serializable
// objects to the main-thread (for example `Dict` or `Stream`). // objects to the main-thread (for example `Dict` or `Stream`).
const customType = typeof value;
let customValue; let customValue;
if (customType === "string") { switch (typeof value) {
customValue = stringToPDFString(value); case "string":
} else if ( customValue = stringToPDFString(value);
value instanceof Name || break;
customType === "number" || case "number":
customType === "boolean" case "boolean":
) { customValue = value;
customValue = value; break;
} else { default:
info(`Unsupported value in document info for (custom) "${key}".`); if (value instanceof Name) {
continue; customValue = value;
}
break;
} }
if (customValue === undefined) {
warn(`Bad value, for custom key "${key}", in Info: ${value}.`);
continue;
}
if (!docInfo.Custom) { if (!docInfo.Custom) {
docInfo.Custom = Object.create(null); docInfo.Custom = Object.create(null);
} }
docInfo.Custom[key] = customValue; docInfo.Custom[key] = customValue;
} continue;
} }
warn(`Bad value, for key "${key}", in Info: ${value}.`);
} }
return shadow(this, "documentInfo", docInfo); return shadow(this, "documentInfo", docInfo);
} }