diff --git a/.eslintrc b/.eslintrc index ef0fe2cd3..03dc596df 100644 --- a/.eslintrc +++ b/.eslintrc @@ -179,6 +179,18 @@ "selector": "CallExpression[callee.name='assert'][arguments.length!=2]", "message": "`assert()` must always be invoked with two arguments.", }, + { + "selector": "CallExpression[callee.name='isCmd'][arguments.length<2]", + "message": "Use `instanceof Cmd` rather than `isCmd()` with one argument.", + }, + { + "selector": "CallExpression[callee.name='isDict'][arguments.length<2]", + "message": "Use `instanceof Dict` rather than `isDict()` with one argument.", + }, + { + "selector": "CallExpression[callee.name='isName'][arguments.length<2]", + "message": "Use `instanceof Name` rather than `isName()` with one argument.", + }, { "selector": "NewExpression[callee.name='Cmd']", "message": "Use `Cmd.get()` rather than `new Cmd()`.", diff --git a/src/core/annotation.js b/src/core/annotation.js index 0e6792811..34bbe9257 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -39,7 +39,7 @@ import { createDefaultAppearance, parseDefaultAppearance, } from "./default_appearance.js"; -import { Dict, isDict, isName, Name, Ref, RefSet } from "./primitives.js"; +import { Dict, isName, Name, Ref, RefSet } from "./primitives.js"; import { BaseStream } from "./base_stream.js"; import { bidi } from "./bidi.js"; import { Catalog } from "./catalog.js"; @@ -95,7 +95,7 @@ class AnnotationFactory { pageIndex = -1 ) { const dict = xref.fetchIfRef(ref); - if (!isDict(dict)) { + if (!(dict instanceof Dict)) { return undefined; } @@ -104,7 +104,7 @@ class AnnotationFactory { // Determine the annotation's subtype. let subtype = dict.get("Subtype"); - subtype = isName(subtype) ? subtype.name : null; + subtype = subtype instanceof Name ? subtype.name : null; // Return the right annotation object based on the subtype and field type. const parameters = { @@ -128,7 +128,7 @@ class AnnotationFactory { case "Widget": let fieldType = getInheritableProperty({ dict, key: "FT" }); - fieldType = isName(fieldType) ? fieldType.name : null; + fieldType = fieldType instanceof Name ? fieldType.name : null; switch (fieldType) { case "Tx": @@ -209,7 +209,7 @@ class AnnotationFactory { static async _getPageIndex(xref, ref, pdfManager) { try { const annotDict = await xref.fetchIfRefAsync(ref); - if (!isDict(annotDict)) { + if (!(annotDict instanceof Dict)) { return -1; } const pageRef = annotDict.getRaw("P"); @@ -636,7 +636,7 @@ class Annotation { } this.borderStyle = new AnnotationBorderStyle(); - if (!isDict(borderStyle)) { + if (!(borderStyle instanceof Dict)) { return; } if (borderStyle.has("BS")) { @@ -681,7 +681,7 @@ class Annotation { this.appearance = null; const appearanceStates = dict.get("AP"); - if (!isDict(appearanceStates)) { + if (!(appearanceStates instanceof Dict)) { return; } @@ -691,14 +691,14 @@ class Annotation { this.appearance = normalAppearanceState; return; } - if (!isDict(normalAppearanceState)) { + if (!(normalAppearanceState instanceof Dict)) { return; } // In case the normal appearance is a dictionary, the `AS` entry provides // the key of the stream in this dictionary. const as = dict.get("AS"); - if (!isName(as) || !normalAppearanceState.has(as.name)) { + if (!(as instanceof Name) || !normalAppearanceState.has(as.name)) { return; } this.appearance = normalAppearanceState.get(as.name); @@ -912,7 +912,7 @@ class AnnotationBorderStyle { // Some corrupt PDF generators may provide the width as a `Name`, // rather than as a number (fixes issue 10385). - if (isName(width)) { + if (width instanceof Name) { this.width = 0; // This is consistent with the behaviour in Adobe Reader. return; } @@ -946,7 +946,7 @@ class AnnotationBorderStyle { * @see {@link shared/util.js} */ setStyle(style) { - if (!isName(style)) { + if (!(style instanceof Name)) { return; } switch (style.name) { @@ -1055,7 +1055,8 @@ class MarkupAnnotation extends Annotation { this.data.inReplyTo = rawIRT instanceof Ref ? rawIRT.toString() : null; const rt = dict.get("RT"); - this.data.replyType = isName(rt) ? rt.name : AnnotationReplyType.REPLY; + this.data.replyType = + rt instanceof Name ? rt.name : AnnotationReplyType.REPLY; } if (this.data.replyType === AnnotationReplyType.GROUP) { @@ -1265,7 +1266,7 @@ class WidgetAnnotation extends Annotation { ); const fieldType = getInheritableProperty({ dict, key: "FT" }); - data.fieldType = isName(fieldType) ? fieldType.name : null; + data.fieldType = fieldType instanceof Name ? fieldType.name : null; const localResources = getInheritableProperty({ dict, key: "DR" }); const acroFormResources = params.acroForm.get("DR"); @@ -1306,7 +1307,7 @@ class WidgetAnnotation extends Annotation { return formValue .filter(item => isString(item)) .map(item => stringToPDFString(item)); - } else if (isName(formValue)) { + } else if (formValue instanceof Name) { return stringToPDFString(formValue.name); } else if (isString(formValue)) { return stringToPDFString(formValue); @@ -1418,7 +1419,7 @@ class WidgetAnnotation extends Annotation { const { xref } = evaluator; const dict = xref.fetchIfRef(this.ref); - if (!isDict(dict)) { + if (!(dict instanceof Dict)) { return null; } @@ -2085,7 +2086,7 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { } const dict = evaluator.xref.fetchIfRef(this.ref); - if (!isDict(dict)) { + if (!(dict instanceof Dict)) { return null; } @@ -2131,7 +2132,7 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { } const dict = evaluator.xref.fetchIfRef(this.ref); - if (!isDict(dict)) { + if (!(dict instanceof Dict)) { return null; } @@ -2158,7 +2159,7 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { parentBuffer = [`${this.parent.num} ${this.parent.gen} obj\n`]; writeDict(parent, parentBuffer, parentTransform); parentBuffer.push("\nendobj\n"); - } else if (isDict(this.parent)) { + } else if (this.parent instanceof Dict) { this.parent.set("V", name); } } @@ -2250,12 +2251,12 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { _processCheckBox(params) { const customAppearance = params.dict.get("AP"); - if (!isDict(customAppearance)) { + if (!(customAppearance instanceof Dict)) { return; } const normalAppearance = customAppearance.get("N"); - if (!isDict(normalAppearance)) { + if (!(normalAppearance instanceof Dict)) { return; } @@ -2318,21 +2319,21 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { // The parent field's `V` entry holds a `Name` object with the appearance // state of whichever child field is currently in the "on" state. const fieldParent = params.dict.get("Parent"); - if (isDict(fieldParent)) { + if (fieldParent instanceof Dict) { this.parent = params.dict.getRaw("Parent"); const fieldParentValue = fieldParent.get("V"); - if (isName(fieldParentValue)) { + if (fieldParentValue instanceof Name) { this.data.fieldValue = this._decodeFormValue(fieldParentValue); } } // The button's value corresponds to its appearance state. const appearanceStates = params.dict.get("AP"); - if (!isDict(appearanceStates)) { + if (!(appearanceStates instanceof Dict)) { return; } const normalAppearance = appearanceStates.get("N"); - if (!isDict(normalAppearance)) { + if (!(normalAppearance instanceof Dict)) { return; } for (const key of normalAppearance.getKeys()) { @@ -2566,7 +2567,8 @@ class PopupAnnotation extends Annotation { } const parentSubtype = parentItem.get("Subtype"); - this.data.parentType = isName(parentSubtype) ? parentSubtype.name : null; + this.data.parentType = + parentSubtype instanceof Name ? parentSubtype.name : null; const rawParent = parameters.dict.getRaw("Parent"); this.data.parentId = rawParent instanceof Ref ? rawParent.toString() : null; diff --git a/src/core/catalog.js b/src/core/catalog.js index 662f4012f..edaec0547 100644 --- a/src/core/catalog.js +++ b/src/core/catalog.js @@ -120,7 +120,7 @@ class Catalog { let collection = null; try { const obj = this._catDict.get("Collection"); - if (isDict(obj) && obj.size > 0) { + if (obj instanceof Dict && obj.size > 0) { collection = obj; } } catch (ex) { @@ -136,7 +136,7 @@ class Catalog { let acroForm = null; try { const obj = this._catDict.get("AcroForm"); - if (isDict(obj) && obj.size > 0) { + if (obj instanceof Dict && obj.size > 0) { acroForm = obj; } } catch (ex) { @@ -208,7 +208,7 @@ class Catalog { */ _readMarkInfo() { const obj = this._catDict.get("MarkInfo"); - if (!isDict(obj)) { + if (!(obj instanceof Dict)) { return null; } @@ -249,7 +249,7 @@ class Catalog { */ _readStructTreeRoot() { const obj = this._catDict.get("StructTreeRoot"); - if (!isDict(obj)) { + if (!(obj instanceof Dict)) { return null; } const root = new StructTreeRoot(obj); @@ -259,7 +259,7 @@ class Catalog { get toplevelPagesDict() { const pagesObj = this._catDict.get("Pages"); - if (!isDict(pagesObj)) { + if (!(pagesObj instanceof Dict)) { throw new FormatError("Invalid top-level pages dictionary."); } return shadow(this, "toplevelPagesDict", pagesObj); @@ -283,7 +283,7 @@ class Catalog { */ _readDocumentOutline() { let obj = this._catDict.get("Outlines"); - if (!isDict(obj)) { + if (!(obj instanceof Dict)) { return null; } obj = obj.getRaw("First"); @@ -376,7 +376,7 @@ class Catalog { */ _readPermissions() { const encrypt = this.xref.trailer.get("Encrypt"); - if (!isDict(encrypt)) { + if (!(encrypt instanceof Dict)) { return null; } @@ -529,9 +529,10 @@ class Catalog { creator: isString(config.get("Creator")) ? stringToPDFString(config.get("Creator")) : null, - baseState: isName(config.get("BaseState")) - ? config.get("BaseState").name - : null, + baseState: + config.get("BaseState") instanceof Name + ? config.get("BaseState").name + : null, on: parseOnOff(config.get("ON")), off: parseOnOff(config.get("OFF")), order: parseOrder(config.get("Order")), @@ -654,7 +655,7 @@ class Catalog { const labelDict = nums.get(i); if (labelDict !== undefined) { - if (!isDict(labelDict)) { + if (!(labelDict instanceof Dict)) { throw new FormatError("PageLabel is not a dictionary."); } @@ -667,7 +668,7 @@ class Catalog { if (labelDict.has("S")) { const s = labelDict.get("S"); - if (!isName(s)) { + if (!(s instanceof Name)) { throw new FormatError("Invalid style in PageLabel dictionary."); } style = s.name; @@ -743,7 +744,7 @@ class Catalog { // affect the Scroll mode (continuous/non-continuous) used in Adobe Reader. let pageLayout = ""; - if (isName(obj)) { + if (obj instanceof Name) { switch (obj.name) { case "SinglePage": case "OneColumn": @@ -761,7 +762,7 @@ class Catalog { const obj = this._catDict.get("PageMode"); let pageMode = "UseNone"; // Default value. - if (isName(obj)) { + if (obj instanceof Name) { switch (obj.name) { case "UseNone": case "UseOutlines": @@ -799,7 +800,7 @@ class Catalog { const obj = this._catDict.get("ViewerPreferences"); let prefs = null; - if (isDict(obj)) { + if (obj instanceof Dict) { for (const key in ViewerPreferencesValidators) { if (!obj.has(key)) { continue; @@ -921,7 +922,7 @@ class Catalog { const obj = this._catDict.get("OpenAction"); const openAction = Object.create(null); - if (isDict(obj)) { + if (obj instanceof Dict) { // Convert the OpenAction dictionary into a format that works with // `parseDestDictionary`, to avoid having to re-implement those checks. const destDict = new Dict(this.xref); @@ -1337,7 +1338,7 @@ class Catalog { if ( isRefsEqual(kidRef, pageRef) && !isDict(node, "Page") && - !(isDict(node) && !node.has("Type") && node.has("Contents")) + !(node instanceof Dict && !node.has("Type") && node.has("Contents")) ) { throw new FormatError( "The reference does not point to a /Page dictionary." @@ -1346,7 +1347,7 @@ class Catalog { if (!node) { return null; } - if (!isDict(node)) { + if (!(node instanceof Dict)) { throw new FormatError("Node must be a dictionary."); } parentRef = node.getRaw("Parent"); @@ -1356,7 +1357,7 @@ class Catalog { if (!parent) { return null; } - if (!isDict(parent)) { + if (!(parent instanceof Dict)) { throw new FormatError("Parent must be a dictionary."); } return parent.getAsync("Kids"); @@ -1379,7 +1380,7 @@ class Catalog { } kidPromises.push( xref.fetchAsync(kid).then(function (obj) { - if (!isDict(obj)) { + if (!(obj instanceof Dict)) { throw new FormatError("Kid node must be a dictionary."); } if (obj.has("Count")) { @@ -1430,7 +1431,7 @@ class Catalog { */ static parseDestDictionary(params) { const destDict = params.destDict; - if (!isDict(destDict)) { + if (!(destDict instanceof Dict)) { warn("parseDestDictionary: `destDict` must be a dictionary."); return; } @@ -1444,14 +1445,14 @@ class Catalog { let action = destDict.get("A"), url, dest; - if (!isDict(action)) { + if (!(action instanceof Dict)) { if (destDict.has("Dest")) { // A /Dest entry should *only* contain a Name or an Array, but some bad // PDF generators ignore that and treat it as an /A entry. action = destDict.get("Dest"); } else { action = destDict.get("AA"); - if (isDict(action)) { + if (action instanceof Dict) { if (action.has("D")) { // MouseDown action = action.get("D"); @@ -1463,9 +1464,9 @@ class Catalog { } } - if (isDict(action)) { + if (action instanceof Dict) { const actionType = action.get("S"); - if (!isName(actionType)) { + if (!(actionType instanceof Name)) { warn("parseDestDictionary: Invalid type in Action dictionary."); return; } @@ -1508,7 +1509,7 @@ class Catalog { case "GoToR": const urlDict = action.get("F"); - if (isDict(urlDict)) { + if (urlDict instanceof Dict) { // We assume that we found a FileSpec dictionary // and fetch the URL without checking any further. url = urlDict.get("F") || null; @@ -1519,7 +1520,7 @@ class Catalog { // NOTE: the destination is relative to the *remote* document. let remoteDest = action.get("D"); if (remoteDest) { - if (isName(remoteDest)) { + if (remoteDest instanceof Name) { remoteDest = remoteDest.name; } if (isString(url)) { @@ -1540,7 +1541,7 @@ class Catalog { case "Named": const namedAction = action.get("N"); - if (isName(namedAction)) { + if (namedAction instanceof Name) { resultObj.action = namedAction.name; } break; @@ -1587,7 +1588,7 @@ class Catalog { resultObj.unsafeUrl = url; } if (dest) { - if (isName(dest)) { + if (dest instanceof Name) { dest = dest.name; } if (isString(dest) || Array.isArray(dest)) { diff --git a/src/core/ccitt_stream.js b/src/core/ccitt_stream.js index d716b4841..0e3b1cea3 100644 --- a/src/core/ccitt_stream.js +++ b/src/core/ccitt_stream.js @@ -13,9 +13,9 @@ * limitations under the License. */ -import { Dict, isDict } from "./primitives.js"; import { CCITTFaxDecoder } from "./ccitt.js"; import { DecodeStream } from "./decode_stream.js"; +import { Dict } from "./primitives.js"; class CCITTFaxStream extends DecodeStream { constructor(str, maybeLength, params) { @@ -24,7 +24,7 @@ class CCITTFaxStream extends DecodeStream { this.str = str; this.dict = str.dict; - if (!isDict(params)) { + if (!(params instanceof Dict)) { params = Dict.empty; } diff --git a/src/core/cmap.js b/src/core/cmap.js index 9c0c373ff..2316608ca 100644 --- a/src/core/cmap.js +++ b/src/core/cmap.js @@ -20,7 +20,7 @@ import { unreachable, warn, } from "../shared/util.js"; -import { EOF, isCmd, isName } from "./primitives.js"; +import { Cmd, EOF, isCmd, Name } from "./primitives.js"; import { BaseStream } from "./base_stream.js"; import { Lexer } from "./parser.js"; import { MissingDataException } from "./core_utils.js"; @@ -901,7 +901,7 @@ const CMapFactory = (function CMapFactoryClosure() { function parseCMapName(cMap, lexer) { const obj = lexer.getObj(); - if (isName(obj) && isString(obj.name)) { + if (obj instanceof Name && isString(obj.name)) { cMap.name = obj.name; } } @@ -913,19 +913,19 @@ const CMapFactory = (function CMapFactoryClosure() { const obj = lexer.getObj(); if (obj === EOF) { break; - } else if (isName(obj)) { + } else if (obj instanceof Name) { if (obj.name === "WMode") { parseWMode(cMap, lexer); } else if (obj.name === "CMapName") { parseCMapName(cMap, lexer); } previous = obj; - } else if (isCmd(obj)) { + } else if (obj instanceof Cmd) { switch (obj.cmd) { case "endcmap": break objLoop; case "usecmap": - if (isName(previous)) { + if (previous instanceof Name) { embeddedUseCMap = previous.name; } break; @@ -1024,7 +1024,7 @@ const CMapFactory = (function CMapFactoryClosure() { const fetchBuiltInCMap = params.fetchBuiltInCMap; const useCMap = params.useCMap; - if (isName(encoding)) { + if (encoding instanceof Name) { return createBuiltInCMap(encoding.name, fetchBuiltInCMap); } else if (encoding instanceof BaseStream) { const parsedCMap = await parseCMap( diff --git a/src/core/colorspace.js b/src/core/colorspace.js index 5dc8fc681..145498461 100644 --- a/src/core/colorspace.js +++ b/src/core/colorspace.js @@ -21,7 +21,7 @@ import { unreachable, warn, } from "../shared/util.js"; -import { isDict, isName, Name, Ref } from "./primitives.js"; +import { Dict, Name, Ref } from "./primitives.js"; import { BaseStream } from "./base_stream.js"; import { MissingDataException } from "./core_utils.js"; @@ -378,7 +378,7 @@ class ColorSpace { */ static _parse(cs, xref, resources = null, pdfFunctionFactory) { cs = xref.fetchIfRef(cs); - if (isName(cs)) { + if (cs instanceof Name) { switch (cs.name) { case "G": case "DeviceGray": @@ -392,12 +392,12 @@ class ColorSpace { case "Pattern": return new PatternCS(/* baseCS = */ null); default: - if (isDict(resources)) { + if (resources instanceof Dict) { const colorSpaces = resources.get("ColorSpace"); - if (isDict(colorSpaces)) { + if (colorSpaces instanceof Dict) { const resourcesCS = colorSpaces.get(cs.name); if (resourcesCS) { - if (isName(resourcesCS)) { + if (resourcesCS instanceof Name) { return this._parse( resourcesCS, xref, diff --git a/src/core/crypto.js b/src/core/crypto.js index d76b6f483..4aeddae95 100644 --- a/src/core/crypto.js +++ b/src/core/crypto.js @@ -24,7 +24,7 @@ import { utf8StringToString, warn, } from "../shared/util.js"; -import { isDict, isName, Name } from "./primitives.js"; +import { Dict, isName, Name } from "./primitives.js"; import { DecryptStream } from "./decrypt_stream.js"; class ARCFourCipher { @@ -1647,7 +1647,7 @@ const CipherTransformFactory = (function CipherTransformFactoryClosure() { } function buildCipherConstructor(cf, name, num, gen, key) { - if (!isName(name)) { + if (!(name instanceof Name)) { throw new FormatError("Invalid crypt filter name."); } const cryptFilter = cf.get(name.name); @@ -1713,7 +1713,7 @@ const CipherTransformFactory = (function CipherTransformFactoryClosure() { // Trying to find default handler -- it usually has Length. const cfDict = dict.get("CF"); const streamCryptoName = dict.get("StmF"); - if (isDict(cfDict) && isName(streamCryptoName)) { + if (cfDict instanceof Dict && streamCryptoName instanceof Name) { cfDict.suppressEncryption = true; // See comment below. const handlerDict = cfDict.get(streamCryptoName.name); keyLength = (handlerDict && handlerDict.get("Length")) || 128; @@ -1838,7 +1838,7 @@ const CipherTransformFactory = (function CipherTransformFactoryClosure() { if (algorithm >= 4) { const cf = dict.get("CF"); - if (isDict(cf)) { + if (cf instanceof Dict) { // The 'CF' dictionary itself should not be encrypted, and by setting // `suppressEncryption` we can prevent an infinite loop inside of // `XRef_fetchUncompressed` if the dictionary contains indirect diff --git a/src/core/document.js b/src/core/document.js index a11b75365..bcef7d875 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -44,7 +44,7 @@ import { XRefEntryException, XRefParseException, } from "./core_utils.js"; -import { Dict, isDict, isName, Name, Ref } from "./primitives.js"; +import { Dict, isName, Name, Ref } from "./primitives.js"; import { getXfaFontDict, getXfaFontName } from "./xfa_fonts.js"; import { NullStream, Stream } from "./stream.js"; import { AnnotationFactory } from "./annotation.js"; @@ -120,7 +120,7 @@ class Page { if (!Array.isArray(value)) { return value; } - if (value.length === 1 || !isDict(value[0])) { + if (value.length === 1 || !(value[0] instanceof Dict)) { return value[0]; } return Dict.merge({ xref: this.xref, dictArray: value }); @@ -1175,7 +1175,7 @@ class PDFDocument { info("The document information dictionary is invalid."); } - if (isDict(infoDict)) { + if (infoDict instanceof Dict) { // Fill the document info with valid entries from the specification, // as well as any existing well-formed custom entries. for (const key of infoDict.getKeys()) { @@ -1196,7 +1196,7 @@ class PDFDocument { let customValue; if (isString(value)) { customValue = stringToPDFString(value); - } else if (isName(value) || isNum(value) || isBool(value)) { + } else if (value instanceof Name || isNum(value) || isBool(value)) { customValue = value; } else { info(`Unsupported value in document info for (custom) "${key}".`); diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 47bc38133..6b8b907b5 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -35,16 +35,7 @@ import { warn, } from "../shared/util.js"; import { CMapFactory, IdentityCMap } from "./cmap.js"; -import { - Cmd, - Dict, - EOF, - isDict, - isName, - Name, - Ref, - RefSet, -} from "./primitives.js"; +import { Cmd, Dict, EOF, isName, Name, Ref, RefSet } from "./primitives.js"; import { ErrorFont, Font } from "./fonts.js"; import { FontFlags, getFontType } from "./fonts_utils.js"; import { @@ -133,7 +124,7 @@ function normalizeBlendMode(value, parsingArray = false) { return "source-over"; } - if (!isName(value)) { + if (!(value instanceof Name)) { if (parsingArray) { return null; } @@ -1042,7 +1033,7 @@ class PartialEvaluator { gStateObj.push([key, false]); break; } - if (isDict(value)) { + if (value instanceof Dict) { isSimpleGState = false; promise = promise.then(() => { @@ -1162,7 +1153,7 @@ class PartialEvaluator { } font = xref.fetchIfRef(fontRef); - if (!isDict(font)) { + if (!(font instanceof Dict)) { return errorFont(); } @@ -1190,7 +1181,7 @@ class PartialEvaluator { fontID = `f${fontRef.toString()}`; } - if (hash && isDict(descriptor)) { + if (hash && descriptor instanceof Dict) { if (!descriptor.fontAliases) { descriptor.fontAliases = Object.create(null); } @@ -1459,7 +1450,7 @@ class PartialEvaluator { } const length = array.length; const operator = this.xref.fetchIfRef(array[0]); - if (length < 2 || !isName(operator)) { + if (length < 2 || !(operator instanceof Name)) { warn("Invalid visibility expression"); return; } @@ -1490,10 +1481,10 @@ class PartialEvaluator { async parseMarkedContentProps(contentProperties, resources) { let optionalContent; - if (isName(contentProperties)) { + if (contentProperties instanceof Name) { const properties = resources.get("Properties"); optionalContent = properties.get(contentProperties.name); - } else if (isDict(contentProperties)) { + } else if (contentProperties instanceof Dict) { optionalContent = contentProperties; } else { throw new FormatError("Optional content properties malformed."); @@ -1521,7 +1512,7 @@ class PartialEvaluator { const optionalContentGroups = optionalContent.get("OCGs"); if ( Array.isArray(optionalContentGroups) || - isDict(optionalContentGroups) + optionalContentGroups instanceof Dict ) { const groupIds = []; if (Array.isArray(optionalContentGroups)) { @@ -1536,9 +1527,10 @@ class PartialEvaluator { return { type: optionalContentType, ids: groupIds, - policy: isName(optionalContent.get("P")) - ? optionalContent.get("P").name - : null, + policy: + optionalContent.get("P") instanceof Name + ? optionalContent.get("P").name + : null, expression: null, }; } else if (optionalContentGroups instanceof Ref) { @@ -1667,7 +1659,7 @@ class PartialEvaluator { } const type = xobj.dict.get("Subtype"); - if (!isName(type)) { + if (!(type instanceof Name)) { throw new FormatError("XObject should have a Name subtype"); } @@ -2067,7 +2059,7 @@ class PartialEvaluator { // but doing so is meaningless without knowing the semantics. continue; case OPS.beginMarkedContentProps: - if (!isName(args[0])) { + if (!(args[0] instanceof Name)) { warn(`Expected name for beginMarkedContentProps arg0=${args[0]}`); continue; } @@ -2989,7 +2981,7 @@ class PartialEvaluator { } const type = xobj.dict.get("Subtype"); - if (!isName(type)) { + if (!(type instanceof Name)) { throw new FormatError("XObject should have a Name subtype"); } @@ -3125,7 +3117,7 @@ class PartialEvaluator { if (includeMarkedContent) { textContent.items.push({ type: "beginMarkedContent", - tag: isName(args[0]) ? args[0].name : null, + tag: args[0] instanceof Name ? args[0].name : null, }); } break; @@ -3133,7 +3125,7 @@ class PartialEvaluator { if (includeMarkedContent) { flushTextContentItem(); let mcid = null; - if (isDict(args[1])) { + if (args[1] instanceof Dict) { mcid = args[1].get("MCID"); } textContent.items.push({ @@ -3141,7 +3133,7 @@ class PartialEvaluator { id: Number.isInteger(mcid) ? `${self.idFactory.getPageObjId()}_mcid${mcid}` : null, - tag: isName(args[0]) ? args[0].name : null, + tag: args[0] instanceof Name ? args[0].name : null, }); } break; @@ -3197,7 +3189,7 @@ class PartialEvaluator { if (properties.composite) { // CIDSystemInfo helps to match CID to glyphs const cidSystemInfo = dict.get("CIDSystemInfo"); - if (isDict(cidSystemInfo)) { + if (cidSystemInfo instanceof Dict) { properties.cidSystemInfo = { registry: stringToPDFString(cidSystemInfo.get("Registry")), ordering: stringToPDFString(cidSystemInfo.get("Ordering")), @@ -3222,11 +3214,10 @@ class PartialEvaluator { let encoding; if (dict.has("Encoding")) { encoding = dict.get("Encoding"); - if (isDict(encoding)) { + if (encoding instanceof Dict) { baseEncodingName = encoding.get("BaseEncoding"); - baseEncodingName = isName(baseEncodingName) - ? baseEncodingName.name - : null; + baseEncodingName = + baseEncodingName instanceof Name ? baseEncodingName.name : null; // Load the differences between the base and original if (encoding.has("Differences")) { const diffEncoding = encoding.get("Differences"); @@ -3235,7 +3226,7 @@ class PartialEvaluator { const data = xref.fetchIfRef(diffEncoding[j]); if (isNum(data)) { index = data; - } else if (isName(data)) { + } else if (data instanceof Name) { differences[index++] = data.name; } else { throw new FormatError( @@ -3244,7 +3235,7 @@ class PartialEvaluator { } } } - } else if (isName(encoding)) { + } else if (encoding instanceof Name) { baseEncodingName = encoding.name; } else { throw new FormatError("Encoding is not a Name nor a Dict"); @@ -3496,7 +3487,7 @@ class PartialEvaluator { if (!cmapObj) { return Promise.resolve(null); } - if (isName(cmapObj)) { + if (cmapObj instanceof Name) { return CMapFactory.create({ encoding: cmapObj, fetchBuiltInCMap: this._fetchBuiltInCMapBound, @@ -3648,7 +3639,7 @@ class PartialEvaluator { } else { // Trying get the BaseFont metrics (see comment above). const baseFontName = dict.get("BaseFont"); - if (isName(baseFontName)) { + if (baseFontName instanceof Name) { const metrics = this.getBaseFontMetrics(baseFontName.name); glyphsWidths = this.buildCharCodeToWidth(metrics.widths, properties); @@ -3746,7 +3737,7 @@ class PartialEvaluator { preEvaluateFont(dict) { const baseDict = dict; let type = dict.get("Subtype"); - if (!isName(type)) { + if (!(type instanceof Name)) { throw new FormatError("invalid font Subtype"); } @@ -3767,7 +3758,7 @@ class PartialEvaluator { throw new FormatError("Descendant font is not a dictionary."); } type = dict.get("Subtype"); - if (!isName(type)) { + if (!(type instanceof Name)) { throw new FormatError("invalid font Subtype"); } composite = true; @@ -3780,13 +3771,13 @@ class PartialEvaluator { hash = new MurmurHash3_64(); const encoding = baseDict.getRaw("Encoding"); - if (isName(encoding)) { + if (encoding instanceof Name) { hash.update(encoding.name); } else if (encoding instanceof Ref) { hash.update(encoding.toString()); - } else if (isDict(encoding)) { + } else if (encoding instanceof Dict) { for (const entry of encoding.getRawValues()) { - if (isName(entry)) { + if (entry instanceof Name) { hash.update(entry.name); } else if (entry instanceof Ref) { hash.update(entry.toString()); @@ -3797,7 +3788,7 @@ class PartialEvaluator { for (let j = 0; j < diffLength; j++) { const diffEntry = entry[j]; - if (isName(diffEntry)) { + if (diffEntry instanceof Name) { diffBuf[j] = diffEntry.name; } else if (isNum(diffEntry) || diffEntry instanceof Ref) { diffBuf[j] = diffEntry.toString(); @@ -3821,7 +3812,7 @@ class PartialEvaluator { stream.end - stream.start ); hash.update(uint8array); - } else if (isName(toUnicode)) { + } else if (toUnicode instanceof Name) { hash.update(toUnicode.name); } @@ -3909,7 +3900,7 @@ class PartialEvaluator { // FontDescriptor was not required. // This case is here for compatibility. let baseFontName = dict.get("BaseFont"); - if (!isName(baseFontName)) { + if (!(baseFontName instanceof Name)) { throw new FormatError("Base font is not specified"); } @@ -4005,7 +3996,7 @@ class PartialEvaluator { } fontName = fontName || baseFont; - if (!isName(fontName)) { + if (!(fontName instanceof Name)) { throw new FormatError("invalid font name"); } @@ -4089,7 +4080,7 @@ class PartialEvaluator { if (composite) { const cidEncoding = baseDict.get("Encoding"); - if (isName(cidEncoding)) { + if (cidEncoding instanceof Name) { properties.cidEncoding = cidEncoding.name; } const cMap = await CMapFactory.create({ diff --git a/src/core/file_spec.js b/src/core/file_spec.js index 5d0dda9f4..3eb1c5a7d 100644 --- a/src/core/file_spec.js +++ b/src/core/file_spec.js @@ -15,7 +15,7 @@ import { stringToPDFString, warn } from "../shared/util.js"; import { BaseStream } from "./base_stream.js"; -import { isDict } from "./primitives.js"; +import { Dict } from "./primitives.js"; function pickPlatformItem(dict) { // Look for the filename in this order: @@ -43,7 +43,7 @@ function pickPlatformItem(dict) { */ class FileSpec { constructor(root, xref) { - if (!root || !isDict(root)) { + if (!(root instanceof Dict)) { return; } this.xref = xref; diff --git a/src/core/function.js b/src/core/function.js index 05a2e317d..d402d067b 100644 --- a/src/core/function.js +++ b/src/core/function.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { Dict, isDict, Ref } from "./primitives.js"; +import { Dict, Ref } from "./primitives.js"; import { FormatError, info, @@ -508,7 +508,7 @@ function isPDFFunction(v) { let fnDict; if (typeof v !== "object") { return false; - } else if (isDict(v)) { + } else if (v instanceof Dict) { fnDict = v; } else if (v instanceof BaseStream) { fnDict = v.dict; diff --git a/src/core/image.js b/src/core/image.js index 850967185..322903b58 100644 --- a/src/core/image.js +++ b/src/core/image.js @@ -14,12 +14,12 @@ */ import { assert, FormatError, ImageKind, info, warn } from "../shared/util.js"; -import { isName, Name } from "./primitives.js"; import { BaseStream } from "./base_stream.js"; import { ColorSpace } from "./colorspace.js"; import { DecodeStream } from "./decode_stream.js"; import { JpegStream } from "./jpeg_stream.js"; import { JpxImage } from "./jpx.js"; +import { Name } from "./primitives.js"; /** * Decode and clamp a value. The formula is different from the spec because we @@ -95,7 +95,7 @@ class PDFImage { const dict = image.dict; const filter = dict.get("F", "Filter"); - if (isName(filter)) { + if (filter instanceof Name) { switch (filter.name) { case "JPXDecode": const jpxImage = new JpxImage(); diff --git a/src/core/jbig2_stream.js b/src/core/jbig2_stream.js index a83d6a9b1..bbea4c539 100644 --- a/src/core/jbig2_stream.js +++ b/src/core/jbig2_stream.js @@ -15,7 +15,7 @@ import { BaseStream } from "./base_stream.js"; import { DecodeStream } from "./decode_stream.js"; -import { isDict } from "./primitives.js"; +import { Dict } from "./primitives.js"; import { Jbig2Image } from "./jbig2.js"; import { shadow } from "../shared/util.js"; @@ -50,7 +50,7 @@ class Jbig2Stream extends DecodeStream { const jbig2Image = new Jbig2Image(); const chunks = []; - if (isDict(this.params)) { + if (this.params instanceof Dict) { const globalsStream = this.params.get("JBIG2Globals"); if (globalsStream instanceof BaseStream) { const globals = globalsStream.getBytes(); diff --git a/src/core/jpeg_stream.js b/src/core/jpeg_stream.js index 7cd822ec7..11bdf5e43 100644 --- a/src/core/jpeg_stream.js +++ b/src/core/jpeg_stream.js @@ -14,7 +14,7 @@ */ import { DecodeStream } from "./decode_stream.js"; -import { isDict } from "./primitives.js"; +import { Dict } from "./primitives.js"; import { JpegImage } from "./jpg.js"; import { shadow } from "../shared/util.js"; @@ -81,7 +81,7 @@ class JpegStream extends DecodeStream { } } // Fetching the 'ColorTransform' entry, if it exists. - if (isDict(this.params)) { + if (this.params instanceof Dict) { const colorTransform = this.params.get("ColorTransform"); if (Number.isInteger(colorTransform)) { jpegOptions.colorTransform = colorTransform; diff --git a/src/core/name_number_tree.js b/src/core/name_number_tree.js index e0bf13ec8..96089841c 100644 --- a/src/core/name_number_tree.js +++ b/src/core/name_number_tree.js @@ -13,8 +13,8 @@ * limitations under the License. */ +import { Dict, RefSet } from "./primitives.js"; import { FormatError, unreachable, warn } from "../shared/util.js"; -import { isDict, RefSet } from "./primitives.js"; /** * A NameTree/NumberTree is like a Dict but has some advantageous properties, @@ -43,7 +43,7 @@ class NameOrNumberTree { const queue = [this.root]; while (queue.length > 0) { const obj = xref.fetchIfRef(queue.shift()); - if (!isDict(obj)) { + if (!(obj instanceof Dict)) { continue; } if (obj.has("Kids")) { diff --git a/src/core/parser.js b/src/core/parser.js index 7eae17afa..e3267783d 100644 --- a/src/core/parser.js +++ b/src/core/parser.js @@ -22,16 +22,7 @@ import { StreamType, warn, } from "../shared/util.js"; -import { - Cmd, - Dict, - EOF, - isCmd, - isDict, - isName, - Name, - Ref, -} from "./primitives.js"; +import { Cmd, Dict, EOF, isCmd, Name, Ref } from "./primitives.js"; import { isWhiteSpace, MissingDataException, @@ -137,7 +128,7 @@ class Parser { case "<<": // dictionary or stream const dict = new Dict(this.xref); while (!isCmd(this.buf1, ">>") && this.buf1 !== EOF) { - if (!isName(this.buf1)) { + if (!(this.buf1 instanceof Name)) { info("Malformed dictionary: key must be a name object"); this.shift(); continue; @@ -498,7 +489,7 @@ class Parser { const dict = new Dict(this.xref); let dictLength; while (!isCmd(this.buf1, "ID") && this.buf1 !== EOF) { - if (!isName(this.buf1)) { + if (!(this.buf1 instanceof Name)) { throw new FormatError("Dictionary key must be a name object"); } const key = this.buf1.name; @@ -515,11 +506,11 @@ class Parser { // Extract the name of the first (i.e. the current) image filter. const filter = dict.get("F", "Filter"); let filterName; - if (isName(filter)) { + if (filter instanceof Name) { filterName = filter.name; } else if (Array.isArray(filter)) { const filterZero = this.xref.fetchIfRef(filter[0]); - if (isName(filterZero)) { + if (filterZero instanceof Name) { filterName = filterZero.name; } } @@ -704,7 +695,7 @@ class Parser { let filter = dict.get("F", "Filter"); let params = dict.get("DP", "DecodeParms"); - if (isName(filter)) { + if (filter instanceof Name) { if (Array.isArray(params)) { warn("/DecodeParms should not be an Array, when /Filter is a Name."); } @@ -717,7 +708,7 @@ class Parser { const paramsArray = params; for (let i = 0, ii = filterArray.length; i < ii; ++i) { filter = this.xref.fetchIfRef(filterArray[i]); - if (!isName(filter)) { + if (!(filter instanceof Name)) { throw new FormatError(`Bad filter name "${filter}"`); } @@ -1401,7 +1392,7 @@ class Linearization { Number.isInteger(obj1) && Number.isInteger(obj2) && isCmd(obj3, "obj") && - isDict(linDict) && + linDict instanceof Dict && isNum((obj = linDict.get("Linearized"))) && obj > 0 ) diff --git a/src/core/predictor_stream.js b/src/core/predictor_stream.js index afeec2adb..e36920a11 100644 --- a/src/core/predictor_stream.js +++ b/src/core/predictor_stream.js @@ -14,14 +14,14 @@ */ import { DecodeStream } from "./decode_stream.js"; +import { Dict } from "./primitives.js"; import { FormatError } from "../shared/util.js"; -import { isDict } from "./primitives.js"; class PredictorStream extends DecodeStream { constructor(str, maybeLength, params) { super(maybeLength); - if (!isDict(params)) { + if (!(params instanceof Dict)) { return str; // no prediction } const predictor = (this.predictor = params.get("Predictor") || 1); diff --git a/src/core/struct_tree.js b/src/core/struct_tree.js index e91124f5e..740ab4499 100644 --- a/src/core/struct_tree.js +++ b/src/core/struct_tree.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { isDict, isName, Ref } from "./primitives.js"; +import { Dict, isName, Name, Ref } from "./primitives.js"; import { isString, stringToPDFString, warn } from "../shared/util.js"; import { NumberTree } from "./name_number_tree.js"; @@ -38,11 +38,11 @@ class StructTreeRoot { readRoleMap() { const roleMapDict = this.dict.get("RoleMap"); - if (!isDict(roleMapDict)) { + if (!(roleMapDict instanceof Dict)) { return; } roleMapDict.forEach((key, value) => { - if (!isName(value)) { + if (!(value instanceof Name)) { return; } this.roleMap.set(key, value.name); @@ -64,7 +64,7 @@ class StructElementNode { get role() { const nameObj = this.dict.get("S"); - const name = isName(nameObj) ? nameObj.name : ""; + const name = nameObj instanceof Name ? nameObj.name : ""; const { root } = this.tree; if (root.roleMap.has(name)) { return root.roleMap.get(name); @@ -112,7 +112,7 @@ class StructElementNode { let kidDict = null; if (kid instanceof Ref) { kidDict = this.dict.xref.fetch(kid); - } else if (isDict(kid)) { + } else if (kid instanceof Dict) { kidDict = kid; } if (!kidDict) { @@ -123,7 +123,8 @@ class StructElementNode { pageObjId = pageRef.toString(); } - const type = isName(kidDict.get("Type")) ? kidDict.get("Type").name : null; + const type = + kidDict.get("Type") instanceof Name ? kidDict.get("Type").name : null; if (type === "MCR") { if (this.tree.pageDict.objId !== pageObjId) { return null; @@ -256,7 +257,7 @@ class StructTreePage { return false; } - if (isDict(obj)) { + if (obj instanceof Dict) { if (obj.objId !== dict.objId) { return false; } diff --git a/src/core/writer.js b/src/core/writer.js index 9985f7bb1..5d525c961 100644 --- a/src/core/writer.js +++ b/src/core/writer.js @@ -14,7 +14,7 @@ */ import { bytesToString, escapeString, warn } from "../shared/util.js"; -import { Dict, isDict, isName, Name, Ref } from "./primitives.js"; +import { Dict, Name, Ref } from "./primitives.js"; import { escapePDFName, parseXFAPath } from "./core_utils.js"; import { SimpleDOMNode, SimpleXMLParser } from "./xml_parser.js"; import { BaseStream } from "./base_stream.js"; @@ -71,7 +71,7 @@ function numberToString(value) { } function writeValue(value, buffer, transform) { - if (isName(value)) { + if (value instanceof Name) { buffer.push(`/${escapePDFName(value.name)}`); } else if (value instanceof Ref) { buffer.push(`${value.num} ${value.gen} R`); @@ -86,7 +86,7 @@ function writeValue(value, buffer, transform) { buffer.push(numberToString(value)); } else if (typeof value === "boolean") { buffer.push(value.toString()); - } else if (isDict(value)) { + } else if (value instanceof Dict) { writeDict(value, buffer, transform); } else if (value instanceof BaseStream) { writeStream(value, buffer, transform); diff --git a/test/unit/primitives_spec.js b/test/unit/primitives_spec.js index fbcdaa62f..e2fb10edb 100644 --- a/test/unit/primitives_spec.js +++ b/test/unit/primitives_spec.js @@ -470,6 +470,8 @@ describe("primitives", function () { }); describe("isName", function () { + /* eslint-disable no-restricted-syntax */ + it("handles non-names", function () { const nonName = {}; expect(isName(nonName)).toEqual(false); @@ -493,9 +495,13 @@ describe("primitives", function () { expect(isName(emptyName, "")).toEqual(true); expect(isName(emptyName, "string")).toEqual(false); }); + + /* eslint-enable no-restricted-syntax */ }); describe("isCmd", function () { + /* eslint-disable no-restricted-syntax */ + it("handles non-commands", function () { const nonCmd = {}; expect(isCmd(nonCmd)).toEqual(false); @@ -511,9 +517,13 @@ describe("primitives", function () { expect(isCmd(cmd, "BT")).toEqual(true); expect(isCmd(cmd, "ET")).toEqual(false); }); + + /* eslint-enable no-restricted-syntax */ }); describe("isDict", function () { + /* eslint-disable no-restricted-syntax */ + it("handles non-dictionaries", function () { const nonDict = {}; expect(isDict(nonDict)).toEqual(false); @@ -531,6 +541,8 @@ describe("primitives", function () { expect(isDict(dict, "Page")).toEqual(true); expect(isDict(dict, "Contents")).toEqual(false); }); + + /* eslint-enable no-restricted-syntax */ }); describe("isRefsEqual", function () {