diff --git a/src/core/cff_parser.js b/src/core/cff_parser.js index fd0e33829..08d64a86e 100644 --- a/src/core/cff_parser.js +++ b/src/core/cff_parser.js @@ -14,7 +14,7 @@ */ import { - assert, bytesToString, error, info, isArray, stringToBytes, Util, warn + assert, bytesToString, FormatError, info, isArray, stringToBytes, Util, warn } from '../shared/util'; import { ExpertCharset, ExpertSubsetCharset, ISOAdobeCharset @@ -291,8 +291,9 @@ var CFFParser = (function CFFParserClosure() { ++offset; } if (offset >= bytesLength) { - error('Invalid CFF header'); - } else if (offset !== 0) { + throw new FormatError('Invalid CFF header'); + } + if (offset !== 0) { info('cff data is shifted'); bytes = bytes.subarray(offset); this.bytes = bytes; @@ -750,7 +751,7 @@ var CFFParser = (function CFFParserClosure() { } break; default: - error('Unknown charset format'); + throw new FormatError('Unknown charset format'); } // Raw won't be needed if we actually compile the charset. var end = pos; @@ -811,8 +812,7 @@ var CFFParser = (function CFFParserClosure() { break; default: - error('Unknown encoding format: ' + format + ' in CFF'); - break; + throw new FormatError(`Unknown encoding format: ${format} in CFF`); } var dataEnd = pos; if (format & 0x80) { // hasSupplement @@ -869,8 +869,7 @@ var CFFParser = (function CFFParserClosure() { } break; default: - error('parseFDSelect: Unknown format "' + format + '".'); - break; + throw new FormatError(`parseFDSelect: Unknown format "${format}".`); } assert(fdSelect.length === length, 'parseFDSelect: Invalid font data.'); @@ -999,7 +998,7 @@ var CFFDict = (function CFFDictClosure() { }, setByName: function CFFDict_setByName(name, value) { if (!(name in this.nameToKeyMap)) { - error('Invalid dictionary name "' + name + '"'); + throw new FormatError(`Invalid dictionary name "${name}"`); } this.values[this.nameToKeyMap[name]] = value; }, @@ -1008,7 +1007,7 @@ var CFFDict = (function CFFDictClosure() { }, getByName: function CFFDict_getByName(name) { if (!(name in this.nameToKeyMap)) { - error('Invalid dictionary name "' + name + '"'); + throw new FormatError(`Invalid dictionary name ${name}"`); } var key = this.nameToKeyMap[name]; if (!(key in this.values)) { @@ -1182,7 +1181,7 @@ var CFFOffsetTracker = (function CFFOffsetTrackerClosure() { }, track: function CFFOffsetTracker_track(key, location) { if (key in this.offsets) { - error('Already tracking location of ' + key); + throw new FormatError(`Already tracking location of ${key}`); } this.offsets[key] = location; }, @@ -1195,7 +1194,7 @@ var CFFOffsetTracker = (function CFFOffsetTrackerClosure() { values, output) { if (!(key in this.offsets)) { - error('Not tracking location of ' + key); + throw new FormatError(`Not tracking location of ${key}`); } var data = output.data; var dataOffset = this.offsets[key]; @@ -1209,7 +1208,7 @@ var CFFOffsetTracker = (function CFFOffsetTrackerClosure() { // It's easy to screw up offsets so perform this sanity check. if (data[offset0] !== 0x1d || data[offset1] !== 0 || data[offset2] !== 0 || data[offset3] !== 0 || data[offset4] !== 0) { - error('writing to an offset that is not empty'); + throw new FormatError('writing to an offset that is not empty'); } var value = values[i]; data[offset0] = 0x1d; @@ -1520,8 +1519,7 @@ var CFFCompiler = (function CFFCompilerClosure() { } break; default: - error('Unknown data type of ' + type); - break; + throw new FormatError(`Unknown data type of ${type}`); } } out = out.concat(dict.opcodes[key]); diff --git a/src/core/cmap.js b/src/core/cmap.js index 16babb3af..c75624ad6 100644 --- a/src/core/cmap.js +++ b/src/core/cmap.js @@ -14,8 +14,8 @@ */ import { - assert, CMapCompressionType, error, isInt, isString, MissingDataException, - Util, warn + assert, CMapCompressionType, FormatError, isInt, isString, + MissingDataException, Util, warn } from '../shared/util'; import { isCmd, isEOF, isName, isStream } from './primitives'; import { Lexer } from './parser'; @@ -354,19 +354,19 @@ var IdentityCMap = (function IdentityCMapClosure() { addCodespaceRange: CMap.prototype.addCodespaceRange, mapCidRange(low, high, dstLow) { - error('should not call mapCidRange'); + throw new Error('should not call mapCidRange'); }, mapBfRange(low, high, dstLow) { - error('should not call mapBfRange'); + throw new Error('should not call mapBfRange'); }, mapBfRangeToArray(low, high, array) { - error('should not call mapBfRangeToArray'); + throw new Error('should not call mapBfRangeToArray'); }, mapOne(src, dst) { - error('should not call mapCidOne'); + throw new Error('should not call mapCidOne'); }, lookup(code) { @@ -403,7 +403,7 @@ var IdentityCMap = (function IdentityCMapClosure() { }, get isIdentityCMap() { - error('should not access .isIdentityCMap'); + throw new Error('should not access .isIdentityCMap'); }, }; @@ -472,7 +472,7 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() { do { var b = this.readByte(); if (b < 0) { - error('unexpected EOF in bcmap'); + throw new FormatError('unexpected EOF in bcmap'); } last = !(b & 0x80); n = (n << 7) | (b & 0x7F); @@ -494,7 +494,7 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() { do { var b = this.readByte(); if (b < 0) { - error('unexpected EOF in bcmap'); + throw new FormatError('unexpected EOF in bcmap'); } last = !(b & 0x80); stack[sp++] = b & 0x7F; @@ -711,13 +711,13 @@ var CMapFactory = (function CMapFactoryClosure() { function expectString(obj) { if (!isString(obj)) { - error('Malformed CMap: expected string.'); + throw new FormatError('Malformed CMap: expected string.'); } } function expectInt(obj) { if (!isInt(obj)) { - error('Malformed CMap: expected int.'); + throw new FormatError('Malformed CMap: expected int.'); } } @@ -770,7 +770,7 @@ var CMapFactory = (function CMapFactoryClosure() { break; } } - error('Invalid bf range.'); + throw new FormatError('Invalid bf range.'); } function parseCidChar(cMap, lexer) { @@ -832,7 +832,7 @@ var CMapFactory = (function CMapFactoryClosure() { var high = strToInt(obj); cMap.addCodespaceRange(obj.length, low, high); } - error('Invalid codespace range.'); + throw new FormatError('Invalid codespace range.'); } function parseWMode(cMap, lexer) { diff --git a/src/core/colorspace.js b/src/core/colorspace.js index 979e44c6a..beded882b 100644 --- a/src/core/colorspace.js +++ b/src/core/colorspace.js @@ -13,7 +13,9 @@ * limitations under the License. */ -import { error, info, isArray, isString, shadow, warn } from '../shared/util'; +import { + FormatError, info, isArray, isString, shadow, warn +} from '../shared/util'; import { isDict, isName, isStream } from './primitives'; import { PDFFunction } from './function'; @@ -55,7 +57,7 @@ var ColorSpace = (function ColorSpaceClosure() { // Constructor should define this.numComps, this.defaultColor, this.name function ColorSpace() { - error('should not call ColorSpace constructor'); + throw new Error('should not call ColorSpace constructor'); } ColorSpace.prototype = { @@ -75,7 +77,7 @@ var ColorSpace = (function ColorSpaceClosure() { */ getRgbItem: function ColorSpace_getRgbItem(src, srcOffset, dest, destOffset) { - error('Should not call ColorSpace.getRgbItem'); + throw new Error('Should not call ColorSpace.getRgbItem'); }, /** * Converts the specified number of the color values to the RGB colors. @@ -89,7 +91,7 @@ var ColorSpace = (function ColorSpaceClosure() { getRgbBuffer: function ColorSpace_getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) { - error('Should not call ColorSpace.getRgbBuffer'); + throw new Error('Should not call ColorSpace.getRgbBuffer'); }, /** * Determines the number of bytes required to store the result of the @@ -98,7 +100,7 @@ var ColorSpace = (function ColorSpaceClosure() { */ getOutputLength: function ColorSpace_getOutputLength(inputLength, alpha01) { - error('Should not call ColorSpace.getOutputLength'); + throw new Error('Should not call ColorSpace.getOutputLength'); }, /** * Returns true if source data will be equal the result/output data. @@ -254,9 +256,8 @@ var ColorSpace = (function ColorSpaceClosure() { var range = IR[3]; return new LabCS(whitePoint, blackPoint, range); default: - error('Unknown name ' + name); + throw new FormatError(`Unknown colorspace name: ${name}`); } - return null; }; ColorSpace.parseToIR = function ColorSpace_parseToIR(cs, xref, res) { @@ -285,9 +286,10 @@ var ColorSpace = (function ColorSpaceClosure() { case 'Pattern': return ['PatternCS', null]; default: - error('unrecognized colorspace ' + cs.name); + throw new FormatError(`unrecognized colorspace ${cs.name}`); } - } else if (isArray(cs)) { + } + if (isArray(cs)) { var mode = xref.fetchIfRef(cs[0]).name; var numComps, params, alt, whitePoint, blackPoint, gamma; @@ -366,12 +368,10 @@ var ColorSpace = (function ColorSpaceClosure() { var range = params.getArray('Range'); return ['LabCS', whitePoint, blackPoint, range]; default: - error('unimplemented color space object "' + mode + '"'); + throw new FormatError(`unimplemented color space object "${mode}"`); } - } else { - error('unrecognized color space object: "' + cs + '"'); } - return null; + throw new FormatError(`unrecognized color space object: "${cs}"`); }; /** * Checks if a decode map matches the default decode map for a color space. @@ -528,7 +528,7 @@ var IndexedCS = (function IndexedCSClosure() { } else if (lookup instanceof Uint8Array || lookup instanceof Array) { this.lookup = lookup; } else { - error('Unrecognized lookup table: ' + lookup); + throw new FormatError(`Unrecognized lookup table: ${lookup}`); } } @@ -753,7 +753,8 @@ var CalGrayCS = (function CalGrayCSClosure() { this.defaultColor = new Float32Array(this.numComps); if (!whitePoint) { - error('WhitePoint missing - required for color space CalGray'); + throw new FormatError( + 'WhitePoint missing - required for color space CalGray'); } blackPoint = blackPoint || [0, 0, 0]; gamma = gamma || 1; @@ -771,8 +772,8 @@ var CalGrayCS = (function CalGrayCSClosure() { // Validate variables as per spec. if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) { - error('Invalid WhitePoint components for ' + this.name + - ', no fallback available'); + throw new FormatError(`Invalid WhitePoint components for ${this.name}` + + ', no fallback available'); } if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { @@ -876,7 +877,8 @@ var CalRGBCS = (function CalRGBCSClosure() { this.defaultColor = new Float32Array(this.numComps); if (!whitePoint) { - error('WhitePoint missing - required for color space CalRGB'); + throw new FormatError( + 'WhitePoint missing - required for color space CalRGB'); } blackPoint = blackPoint || new Float32Array(3); gamma = gamma || new Float32Array([1, 1, 1]); @@ -909,8 +911,8 @@ var CalRGBCS = (function CalRGBCSClosure() { // Validate variables as per spec. if (XW < 0 || ZW < 0 || YW !== 1) { - error('Invalid WhitePoint components for ' + this.name + - ', no fallback available'); + throw new FormatError(`Invalid WhitePoint components for ${this.name}` + + ', no fallback available'); } if (XB < 0 || YB < 0 || ZB < 0) { @@ -1152,7 +1154,8 @@ var LabCS = (function LabCSClosure() { this.defaultColor = new Float32Array(this.numComps); if (!whitePoint) { - error('WhitePoint missing - required for color space Lab'); + throw new FormatError( + 'WhitePoint missing - required for color space Lab'); } blackPoint = blackPoint || [0, 0, 0]; range = range || [-100, 100, -100, 100]; @@ -1174,7 +1177,8 @@ var LabCS = (function LabCSClosure() { // Validate vars as per spec if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) { - error('Invalid WhitePoint components, no fallback available'); + throw new FormatError( + 'Invalid WhitePoint components, no fallback available'); } if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { diff --git a/src/core/crypto.js b/src/core/crypto.js index 37ae7051a..905ae508c 100644 --- a/src/core/crypto.js +++ b/src/core/crypto.js @@ -14,8 +14,8 @@ */ import { - assert, bytesToString, error, isInt, PasswordException, PasswordResponses, - stringToBytes, utf8StringToString, warn + assert, bytesToString, FormatError, isInt, PasswordException, + PasswordResponses, stringToBytes, utf8StringToString, warn } from '../shared/util'; import { isDict, isName, Name } from './primitives'; import { DecryptStream } from './stream'; @@ -1858,14 +1858,14 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { function CipherTransformFactory(dict, fileId, password) { var filter = dict.get('Filter'); if (!isName(filter, 'Standard')) { - error('unknown encryption method'); + throw new FormatError('unknown encryption method'); } this.dict = dict; var algorithm = dict.get('V'); if (!isInt(algorithm) || (algorithm !== 1 && algorithm !== 2 && algorithm !== 4 && algorithm !== 5)) { - error('unsupported encryption algorithm'); + throw new FormatError('unsupported encryption algorithm'); } this.algorithm = algorithm; var keyLength = dict.get('Length'); @@ -1892,7 +1892,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { } if (!isInt(keyLength) || keyLength < 40 || (keyLength % 8) !== 0) { - error('invalid key length'); + throw new FormatError('invalid key length'); } // prepare keys @@ -2023,7 +2023,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { return new AES256Cipher(key); }; } - error('Unknown crypto method'); + throw new FormatError('Unknown crypto method'); } CipherTransformFactory.prototype = { diff --git a/src/core/document.js b/src/core/document.js index 79e0c2494..088044fac 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -14,7 +14,7 @@ */ import { - assert, error, info, isArray, isArrayBuffer, isNum, isSpace, isString, + assert, info, isArray, isArrayBuffer, isNum, isSpace, isString, MissingDataException, OPS, shadow, stringToBytes, stringToPDFString, Util, warn } from '../shared/util'; @@ -353,7 +353,7 @@ var PDFDocument = (function PDFDocumentClosure() { } else if (isArrayBuffer(arg)) { stream = new Stream(arg); } else { - error('PDFDocument: Unknown argument type'); + throw new Error('PDFDocument: Unknown argument type'); } assert(stream.length > 0, 'stream must have data'); diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 42c505e2d..19a0d4199 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -14,9 +14,9 @@ */ import { - assert, CMapCompressionType, createPromiseCapability, error, - FONT_IDENTITY_MATRIX, getLookupTableFactory, IDENTITY_MATRIX, ImageKind, info, - isArray, isNum, isString, NativeImageDecoding, OPS, TextRenderingMode, + assert, CMapCompressionType, createPromiseCapability, FONT_IDENTITY_MATRIX, + FormatError, getLookupTableFactory, IDENTITY_MATRIX, ImageKind, info, isArray, + isNum, isString, NativeImageDecoding, OPS, TextRenderingMode, UNSUPPORTED_FEATURES, Util, warn } from '../shared/util'; import { CMapFactory, IdentityCMap } from './cmap'; @@ -953,7 +953,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { info('Ignored XObject subtype PS'); continue; } else { - error('Unhandled XObject subtype ' + type.name); + throw new FormatError( + `Unhandled XObject subtype ${type.name}`); } } break; @@ -1791,14 +1792,15 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { } else if (isName(data)) { differences[index++] = data.name; } else { - error('Invalid entry in \'Differences\' array: ' + data); + throw new FormatError( + `Invalid entry in 'Differences' array: ${data}`); } } } } else if (isName(encoding)) { baseEncodingName = encoding.name; } else { - error('Encoding is not a Name nor a Dict'); + throw new FormatError('Encoding is not a Name nor a Dict'); } // According to table 114 if the encoding is a named encoding it must be // one of these predefined encodings. diff --git a/src/core/font_renderer.js b/src/core/font_renderer.js index 2c401c9aa..2673a61ba 100644 --- a/src/core/font_renderer.js +++ b/src/core/font_renderer.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { bytesToString, error, Util } from '../shared/util'; +import { bytesToString, FormatError, Util } from '../shared/util'; import { CFFParser } from './cff_parser'; import { getGlyphsUnicode } from './glyphlist'; import { StandardEncoding } from './encodings'; @@ -76,7 +76,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() { } return ranges; } - error('not supported cmap: ' + format); + throw new FormatError(`unsupported cmap: ${format}`); } function parseCff(data, start, end, seacAnalysisEnabled) { @@ -423,7 +423,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() { bezierCurveTo(xa, ya, xb, yb, x, y); break; default: - error('unknown operator: 12 ' + v); + throw new FormatError(`unknown operator: 12 ${v}`); } break; case 14: // endchar @@ -566,7 +566,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() { break; default: if (v < 32) { - error('unknown operator: ' + v); + throw new FormatError(`unknown operator: ${v}`); } if (v < 247) { stack.push(v - 139); @@ -628,7 +628,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() { }, compileGlyphImpl() { - error('Children classes should implement this.'); + throw new Error('Children classes should implement this.'); }, hasBuiltPath(unicode) { diff --git a/src/core/fonts.js b/src/core/fonts.js index 7d7807ca4..d5f86bae6 100644 --- a/src/core/fonts.js +++ b/src/core/fonts.js @@ -14,9 +14,9 @@ */ import { - assert, bytesToString, error, FONT_IDENTITY_MATRIX, FontType, info, isArray, - isInt, isNum, isSpace, MissingDataException, readUint32, shadow, string32, - warn + assert, bytesToString, FONT_IDENTITY_MATRIX, FontType, FormatError, info, + isArray, isInt, isNum, isSpace, MissingDataException, readUint32, shadow, + string32, warn } from '../shared/util'; import { CFF, CFFCharset, CFFCompiler, CFFHeader, CFFIndex, CFFParser, CFFPrivateDict, @@ -295,7 +295,7 @@ var IdentityToUnicodeMap = (function IdentityToUnicodeMapClosure() { }, amend(map) { - error('Should not call amend()'); + throw new Error('Should not call amend()'); }, }; @@ -683,8 +683,7 @@ var Font = (function FontClosure() { break; default: - error('Font ' + type + ' is not supported'); - break; + throw new FormatError(`Font ${type} is not supported`); } this.data = data; @@ -1079,7 +1078,8 @@ var Font = (function FontClosure() { } else if (position < 123) { ulUnicodeRange4 |= 1 << position - 96; } else { - error('Unicode ranges Bits > 123 are reserved for internal usage'); + throw new FormatError( + 'Unicode ranges Bits > 123 are reserved for internal usage'); } } } else { @@ -2170,7 +2170,7 @@ var Font = (function FontClosure() { this.isOpenType = true; } else { if (!tables['loca']) { - error('Required "loca" table is not found'); + throw new FormatError('Required "loca" table is not found'); } if (!tables['glyf']) { warn('Required "glyf" table is not found -- trying to recover.'); @@ -2184,7 +2184,7 @@ var Font = (function FontClosure() { } if (!tables['maxp']) { - error('Required "maxp" table is not found'); + throw new FormatError('Required "maxp" table is not found'); } font.pos = (font.start || 0) + tables['maxp'].offset; @@ -2226,7 +2226,7 @@ var Font = (function FontClosure() { sanitizeMetrics(font, tables['hhea'], tables['hmtx'], numGlyphs); if (!tables['head']) { - error('Required "head" table is not found'); + throw new FormatError('Required "head" table is not found'); } sanitizeHead(tables['head'], numGlyphs, @@ -2242,7 +2242,7 @@ var Font = (function FontClosure() { } if (!tables['hhea']) { - error('Required "hhea" table is not found'); + throw new FormatError('Required "hhea" table is not found'); } // Sanitizer reduces the glyph advanceWidth to the maxAdvanceWidth diff --git a/src/core/function.js b/src/core/function.js index 4a604e4c4..0d92eeb94 100644 --- a/src/core/function.js +++ b/src/core/function.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { error, info, isArray, isBool } from '../shared/util'; +import { FormatError, info, isArray, isBool } from '../shared/util'; import { isDict, isStream } from './primitives'; import { PostScriptLexer, PostScriptParser } from './ps_parser'; @@ -69,7 +69,7 @@ var PDFFunction = (function PDFFunctionClosure() { var typeNum = dict.get('FunctionType'); var typeFn = types[typeNum]; if (!typeFn) { - error('Unknown type of function'); + throw new FormatError('Unknown type of function'); } return typeFn.call(this, fn, dict, xref); @@ -128,7 +128,7 @@ var PDFFunction = (function PDFFunctionClosure() { var range = dict.getArray('Range'); if (!domain || !range) { - error('No domain or range'); + throw new FormatError('No domain or range'); } var inputSize = domain.length / 2; @@ -263,7 +263,8 @@ var PDFFunction = (function PDFFunctionClosure() { var n = dict.get('N'); if (!isArray(c0) || !isArray(c1)) { - error('Illegal dictionary for interpolated function'); + throw new FormatError( + 'Illegal dictionary for interpolated function'); } var length = c0.length; @@ -297,12 +298,12 @@ var PDFFunction = (function PDFFunctionClosure() { var domain = dict.getArray('Domain'); if (!domain) { - error('No domain'); + throw new FormatError('No domain'); } var inputSize = domain.length / 2; if (inputSize !== 1) { - error('Bad domain for stiched function'); + throw new FormatError('Bad domain for stiched function'); } var fnRefs = dict.get('Functions'); @@ -378,11 +379,11 @@ var PDFFunction = (function PDFFunctionClosure() { var range = dict.getArray('Range'); if (!domain) { - error('No domain.'); + throw new FormatError('No domain.'); } if (!range) { - error('No range.'); + throw new FormatError('No range.'); } var lexer = new PostScriptLexer(fn); @@ -488,19 +489,19 @@ var PostScriptStack = (function PostScriptStackClosure() { PostScriptStack.prototype = { push: function PostScriptStack_push(value) { if (this.stack.length >= MAX_STACK_SIZE) { - error('PostScript function stack overflow.'); + throw new Error('PostScript function stack overflow.'); } this.stack.push(value); }, pop: function PostScriptStack_pop() { if (this.stack.length <= 0) { - error('PostScript function stack underflow.'); + throw new Error('PostScript function stack underflow.'); } return this.stack.pop(); }, copy: function PostScriptStack_copy(n) { if (this.stack.length + n >= MAX_STACK_SIZE) { - error('PostScript function stack overflow.'); + throw new Error('PostScript function stack overflow.'); } var stack = this.stack; for (var i = stack.length - n, j = n - 1; j >= 0; j--, i++) { @@ -755,8 +756,7 @@ var PostScriptEvaluator = (function PostScriptEvaluatorClosure() { } break; default: - error('Unknown operator ' + operator); - break; + throw new FormatError(`Unknown operator ${operator}`); } } return stack.stack; diff --git a/src/core/image.js b/src/core/image.js index 031db844e..466b49833 100644 --- a/src/core/image.js +++ b/src/core/image.js @@ -13,7 +13,9 @@ * limitations under the License. */ -import { assert, error, ImageKind, info, isArray, warn } from '../shared/util'; +import { + assert, FormatError, ImageKind, info, isArray, warn +} from '../shared/util'; import { DecodeStream, JpegStream } from './stream'; import { isStream, Name } from './primitives'; import { ColorSpace } from './colorspace'; @@ -96,8 +98,8 @@ var PDFImage = (function PDFImageClosure() { this.height = dict.get('Height', 'H'); if (this.width < 1 || this.height < 1) { - error('Invalid image width: ' + this.width + ' or height: ' + - this.height); + throw new FormatError(`Invalid image width: ${this.width} or ` + + `height: ${this.height}`); } this.interpolate = dict.get('Interpolate', 'I') || false; @@ -111,7 +113,8 @@ var PDFImage = (function PDFImageClosure() { if (this.imageMask) { bitsPerComponent = 1; } else { - error('Bits per component missing in image: ' + this.imageMask); + throw new FormatError( + `Bits per component missing in image: ${this.imageMask}`); } } } @@ -132,8 +135,8 @@ var PDFImage = (function PDFImageClosure() { colorSpace = Name.get('DeviceCMYK'); break; default: - error('JPX images with ' + this.numComps + - ' color components not supported.'); + throw new Error(`JPX images with ${this.numComps} ` + + 'color components not supported.'); } } this.colorSpace = ColorSpace.parse(colorSpace, xref, res); @@ -424,7 +427,7 @@ var PDFImage = (function PDFImageClosure() { alphaBuf[i] = opacity; } } else { - error('Unknown mask format.'); + throw new FormatError('Unknown mask format.'); } } @@ -583,7 +586,8 @@ var PDFImage = (function PDFImageClosure() { fillGrayBuffer: function PDFImage_fillGrayBuffer(buffer) { var numComps = this.numComps; if (numComps !== 1) { - error('Reading gray scale from a color image: ' + numComps); + throw new FormatError( + `Reading gray scale from a color image: ${numComps}`); } var width = this.width; diff --git a/src/core/jbig2.js b/src/core/jbig2.js index 71671541b..c0beebcdf 100644 --- a/src/core/jbig2.js +++ b/src/core/jbig2.js @@ -14,10 +14,22 @@ */ import { - error, log2, readInt8, readUint16, readUint32, shadow + log2, readInt8, readUint16, readUint32, shadow } from '../shared/util'; import { ArithmeticDecoder } from './arithmetic_decoder'; +let Jbig2Error = (function Jbig2ErrorClosure() { + function Jbig2Error(msg) { + this.message = 'JBIG2 error: ' + msg; + } + + Jbig2Error.prototype = new Error(); + Jbig2Error.prototype.name = 'Jbig2Error'; + Jbig2Error.constructor = Jbig2Error; + + return Jbig2Error; +})(); + var Jbig2Image = (function Jbig2ImageClosure() { // Utility data structures function ContextCache() {} @@ -194,7 +206,7 @@ var Jbig2Image = (function Jbig2ImageClosure() { function decodeBitmap(mmr, width, height, templateIndex, prediction, skip, at, decodingContext) { if (mmr) { - error('JBIG2 error: MMR encoding is not supported'); + throw new Jbig2Error('MMR encoding is not supported'); } // Use optimized version for the most common case @@ -361,7 +373,7 @@ var Jbig2Image = (function Jbig2ImageClosure() { var sltp = decoder.readBit(contexts, pseudoPixelContext); ltp ^= sltp; if (ltp) { - error('JBIG2 error: prediction is not supported'); + throw new Jbig2Error('prediction is not supported'); } } var row = new Uint8Array(width); @@ -403,7 +415,7 @@ var Jbig2Image = (function Jbig2ImageClosure() { refinementTemplateIndex, refinementAt, decodingContext) { if (huffman) { - error('JBIG2 error: huffman is not supported'); + throw new Jbig2Error('huffman is not supported'); } var newSymbols = []; @@ -490,7 +502,7 @@ var Jbig2Image = (function Jbig2ImageClosure() { refinementTemplateIndex, refinementAt, decodingContext) { if (huffman) { - error('JBIG2 error: huffman is not supported'); + throw new Jbig2Error('huffman is not supported'); } // Prepare bitmap @@ -566,8 +578,8 @@ var Jbig2Image = (function Jbig2ImageClosure() { } break; default: - error('JBIG2 error: operator ' + combinationOperator + - ' is not supported'); + throw new Jbig2Error( + `operator ${combinationOperator} is not supported`); } } currentS += symbolHeight - 1; @@ -590,8 +602,8 @@ var Jbig2Image = (function Jbig2ImageClosure() { } break; default: - error('JBIG2 error: operator ' + combinationOperator + - ' is not supported'); + throw new Jbig2Error( + `operator ${combinationOperator} is not supported`); } } currentS += symbolWidth - 1; @@ -613,7 +625,7 @@ var Jbig2Image = (function Jbig2ImageClosure() { var flags = data[start + 4]; var segmentType = flags & 0x3F; if (!SegmentTypes[segmentType]) { - error('JBIG2 error: invalid segment type: ' + segmentType); + throw new Jbig2Error('invalid segment type: ' + segmentType); } segmentHeader.type = segmentType; segmentHeader.typeName = SegmentTypes[segmentType]; @@ -633,7 +645,7 @@ var Jbig2Image = (function Jbig2ImageClosure() { retainBits.push(data[position++]); } } else if (referredFlags === 5 || referredFlags === 6) { - error('JBIG2 error: invalid referred-to flags'); + throw new Jbig2Error('invalid referred-to flags'); } segmentHeader.retainBits = retainBits; @@ -687,10 +699,10 @@ var Jbig2Image = (function Jbig2ImageClosure() { } } if (segmentHeader.length === 0xFFFFFFFF) { - error('JBIG2 error: segment end was not found'); + throw new Jbig2Error('segment end was not found'); } } else { - error('JBIG2 error: invalid unknown segment length'); + throw new Jbig2Error('invalid unknown segment length'); } } segmentHeader.headerEnd = position; @@ -834,7 +846,7 @@ var Jbig2Image = (function Jbig2ImageClosure() { position += 4; // TODO 7.4.3.1.7 Symbol ID Huffman table decoding if (textRegion.huffman) { - error('JBIG2 error: huffman is not supported'); + throw new Jbig2Error('huffman is not supported'); } args = [textRegion, header.referredTo, data, position, end]; break; @@ -891,8 +903,8 @@ var Jbig2Image = (function Jbig2ImageClosure() { // are comments and can be ignored. break; default: - error('JBIG2 error: segment type ' + header.typeName + '(' + - header.type + ') is not implemented'); + throw new Jbig2Error(`segment type ${header.typeName}(${header.type})` + + ' is not implemented'); } var callbackName = 'on' + header.typeName; if (callbackName in visitor) { @@ -912,7 +924,7 @@ var Jbig2Image = (function Jbig2ImageClosure() { data[position + 2] !== 0x42 || data[position + 3] !== 0x32 || data[position + 4] !== 0x0D || data[position + 5] !== 0x0A || data[position + 6] !== 0x1A || data[position + 7] !== 0x0A) { - error('JBIG2 error: invalid header'); + throw new Jbig2Error('invalid header'); } var header = {}; position += 8; @@ -923,7 +935,7 @@ var Jbig2Image = (function Jbig2ImageClosure() { position += 4; } readSegments(header, data, position, end); // segments - error('Not implemented'); + throw new Error('Not implemented'); // processSegments(segments, new SimpleSegmentVisitor()); } @@ -999,8 +1011,8 @@ var Jbig2Image = (function Jbig2ImageClosure() { } break; default: - error('JBIG2 error: operator ' + combinationOperator + - ' is not supported'); + throw new Jbig2Error( + `operator ${combinationOperator} is not supported`); } }, onImmediateGenericRegion: @@ -1024,7 +1036,7 @@ var Jbig2Image = (function Jbig2ImageClosure() { data, start, end) { var huffmanTables; if (dictionary.huffman) { - error('JBIG2 error: huffman is not supported'); + throw new Jbig2Error('huffman is not supported'); } // Combines exported symbols from all referred segments diff --git a/src/core/jpg.js b/src/core/jpg.js index 47d4854c9..c6111d74e 100644 --- a/src/core/jpg.js +++ b/src/core/jpg.js @@ -14,7 +14,19 @@ */ /* eslint-disable no-multi-spaces */ -import { error, warn } from '../shared/util'; +import { warn } from '../shared/util'; + +let JpegError = (function JpegErrorClosure() { + function JpegError(msg) { + this.message = 'JPEG error: ' + msg; + } + + JpegError.prototype = new Error(); + JpegError.prototype.name = 'JpegError'; + JpegError.constructor = JpegError; + + return JpegError; +})(); /** * This code was forked from https://github.com/notmasteryet/jpgjs. @@ -115,8 +127,8 @@ var JpegImage = (function JpegImageClosure() { if (bitsData === 0xFF) { var nextByte = data[offset++]; if (nextByte) { - error('JPEG error: unexpected marker ' + - ((bitsData << 8) | nextByte).toString(16)); + throw new JpegError( + `unexpected marker ${((bitsData << 8) | nextByte).toString(16)}`); } // unstuff 0 } @@ -132,7 +144,7 @@ var JpegImage = (function JpegImageClosure() { return node; } if (typeof node !== 'object') { - error('JPEG error: invalid huffman sequence'); + throw new JpegError('invalid huffman sequence'); } } } @@ -239,7 +251,7 @@ var JpegImage = (function JpegImageClosure() { } } else { if (s !== 1) { - error('JPEG error: invalid ACn encoding'); + throw new JpegError('invalid ACn encoding'); } successiveACNextValue = receiveAndExtend(s); successiveACState = r ? 2 : 3; @@ -362,7 +374,7 @@ var JpegImage = (function JpegImageClosure() { } var marker = fileMarker && fileMarker.marker; if (!marker || marker <= 0xFF00) { - error('JPEG error: marker was not found'); + throw new JpegError('marker was not found'); } if (marker >= 0xFFD0 && marker <= 0xFFD7) { // RSTx @@ -396,7 +408,7 @@ var JpegImage = (function JpegImageClosure() { var t; if (!qt) { - error('JPEG error: missing required Quantization Table.'); + throw new JpegError('missing required Quantization Table.'); } // inverse DCT on rows @@ -680,7 +692,7 @@ var JpegImage = (function JpegImageClosure() { var huffmanTablesAC = [], huffmanTablesDC = []; var fileMarker = readUint16(); if (fileMarker !== 0xFFD8) { // SOI (Start of Image) - error('JPEG error: SOI not found'); + throw new JpegError('SOI not found'); } fileMarker = readUint16(); @@ -755,7 +767,7 @@ var JpegImage = (function JpegImageClosure() { tableData[z] = readUint16(); } } else { - error('JPEG error: DQT - invalid table spec'); + throw new JpegError('DQT - invalid table spec'); } quantizationTables[quantizationTableSpec & 15] = tableData; } @@ -765,7 +777,7 @@ var JpegImage = (function JpegImageClosure() { case 0xFFC1: // SOF1 (Start of Frame, Extended DCT) case 0xFFC2: // SOF2 (Start of Frame, Progressive DCT) if (frame) { - error('JPEG error: Only single frame JPEGs supported'); + throw new JpegError('Only single frame JPEGs supported'); } readUint16(); // skip data length frame = {}; @@ -865,7 +877,7 @@ var JpegImage = (function JpegImageClosure() { offset -= 3; break; } - error('JPEG error: unknown marker ' + fileMarker.toString(16)); + throw new JpegError('unknown marker ' + fileMarker.toString(16)); } fileMarker = readUint16(); } @@ -1090,7 +1102,7 @@ var JpegImage = (function JpegImageClosure() { getData: function getData(width, height, forceRGBoutput) { if (this.numComponents > 4) { - error('JPEG error: Unsupported color mode'); + throw new JpegError('Unsupported color mode'); } // type of data: Uint8Array(width * height * numComponents) var data = this._getLinearizedBlockData(width, height); diff --git a/src/core/jpx.js b/src/core/jpx.js index 97d28b107..d6925b44a 100644 --- a/src/core/jpx.js +++ b/src/core/jpx.js @@ -14,10 +14,22 @@ */ import { - error, info, log2, readUint16, readUint32, warn + info, log2, readUint16, readUint32, warn } from '../shared/util'; import { ArithmeticDecoder } from './arithmetic_decoder'; +let JpxError = (function JpxErrorClosure() { + function JpxError(msg) { + this.message = 'JPX error: ' + msg; + } + + JpxError.prototype = new Error(); + JpxError.prototype.name = 'JpxError'; + JpxError.constructor = JpxError; + + return JpxError; +})(); + var JpxImage = (function JpxImageClosure() { // Table E.1 var SubbandsGainLog2 = { @@ -57,7 +69,7 @@ var JpxImage = (function JpxImageClosure() { lbox = length - position + headerSize; } if (lbox < headerSize) { - error('JPX Error: Invalid box field size'); + throw new JpxError('Invalid box field size'); } var dataLength = lbox - headerSize; var jumpDataLength = true; @@ -135,7 +147,7 @@ var JpxImage = (function JpxImageClosure() { return; } } - error('JPX Error: No size marker found in JPX stream'); + throw new JpxError('No size marker found in JPX stream'); }, parseCodestream: function JpxImage_parseCodestream(data, start, end) { var context = {}; @@ -390,7 +402,7 @@ var JpxImage = (function JpxImageClosure() { } } catch (e) { if (doNotRecover || this.failOnCorruptedImage) { - error('JPX Error: ' + e.message); + throw new JpxError(e.message); } else { warn('JPX: Trying to recover from: ' + e.message); } @@ -642,7 +654,7 @@ var JpxImage = (function JpxImageClosure() { } r = 0; } - error('JPX Error: Out of packets'); + throw new JpxError('Out of packets'); }; } function ResolutionLayerComponentPositionIterator(context) { @@ -682,7 +694,7 @@ var JpxImage = (function JpxImageClosure() { } l = 0; } - error('JPX Error: Out of packets'); + throw new JpxError('Out of packets'); }; } function ResolutionPositionComponentLayerIterator(context) { @@ -741,7 +753,7 @@ var JpxImage = (function JpxImageClosure() { } p = 0; } - error('JPX Error: Out of packets'); + throw new JpxError('Out of packets'); }; } function PositionComponentResolutionLayerIterator(context) { @@ -788,7 +800,7 @@ var JpxImage = (function JpxImageClosure() { } px = 0; } - error('JPX Error: Out of packets'); + throw new JpxError('Out of packets'); }; } function ComponentPositionResolutionLayerIterator(context) { @@ -834,7 +846,7 @@ var JpxImage = (function JpxImageClosure() { } py = 0; } - error('JPX Error: Out of packets'); + throw new JpxError('Out of packets'); }; } function getPrecinctIndexIfExist( @@ -1014,7 +1026,7 @@ var JpxImage = (function JpxImageClosure() { new ComponentPositionResolutionLayerIterator(context); break; default: - error('JPX Error: Unsupported progression order ' + progressionOrder); + throw new JpxError(`Unsupported progression order ${progressionOrder}`); } } function parseTilePackets(context, data, offset, dataLength) { @@ -1951,7 +1963,7 @@ var JpxImage = (function JpxImageClosure() { (decoder.readBit(contexts, UNIFORM_CONTEXT) << 1) | decoder.readBit(contexts, UNIFORM_CONTEXT); if (symbol !== 0xA) { - error('JPX Error: Invalid segmentation symbol'); + throw new JpxError('Invalid segmentation symbol'); } }, }; diff --git a/src/core/obj.js b/src/core/obj.js index 5d3b4acfa..3581e57aa 100644 --- a/src/core/obj.js +++ b/src/core/obj.js @@ -14,8 +14,8 @@ */ import { - assert, bytesToString, createPromiseCapability, createValidAbsoluteUrl, error, - info, InvalidPDFException, isArray, isBool, isInt, isString, + assert, bytesToString, createPromiseCapability, createValidAbsoluteUrl, + FormatError, info, InvalidPDFException, isArray, isBool, isInt, isString, MissingDataException, shadow, stringToPDFString, stringToUTF8String, Util, warn, XRefParseException } from '../shared/util'; @@ -534,7 +534,7 @@ var Catalog = (function CatalogClosure() { })); } if (!found) { - error('kid ref not found in parents kids'); + throw new FormatError('kid ref not found in parents kids'); } return Promise.all(kidPromises).then(function () { return [total, parentRef]; @@ -775,7 +775,7 @@ var XRef = (function XRefClosure() { // get the root dictionary (catalog) object if (!(this.root = trailerDict.get('Root'))) { - error('Invalid root reference'); + throw new FormatError('Invalid root reference'); } }, @@ -795,7 +795,8 @@ var XRef = (function XRefClosure() { // Sanity check if (!isCmd(obj, 'trailer')) { - error('Invalid XRef table: could not find trailer dictionary'); + throw new FormatError( + 'Invalid XRef table: could not find trailer dictionary'); } // Read trailer dictionary, e.g. // trailer @@ -813,7 +814,8 @@ var XRef = (function XRefClosure() { dict = dict.dict; } if (!isDict(dict)) { - error('Invalid XRef table: could not parse trailer dictionary'); + throw new FormatError( + 'Invalid XRef table: could not parse trailer dictionary'); } delete this.tableState; @@ -852,7 +854,8 @@ var XRef = (function XRefClosure() { var first = tableState.firstEntryNum; var count = tableState.entryCount; if (!isInt(first) || !isInt(count)) { - error('Invalid XRef table: wrong types in subsection header'); + throw new FormatError( + 'Invalid XRef table: wrong types in subsection header'); } // Inner loop is over objects themselves for (var i = tableState.entryNum; i < count; i++) { @@ -875,7 +878,8 @@ var XRef = (function XRefClosure() { // Validate entry obj if (!isInt(entry.offset) || !isInt(entry.gen) || !(entry.free || entry.uncompressed)) { - error('Invalid entry in XRef subsection: ' + first + ', ' + count); + throw new FormatError( + `Invalid entry in XRef subsection: ${first}, ${count}`); } // The first xref table entry, i.e. obj 0, should be free. Attempting @@ -899,7 +903,8 @@ var XRef = (function XRefClosure() { // Sanity check: as per spec, first object must be free if (this.entries[0] && !this.entries[0].free) { - error('Invalid XRef table: unexpected first object'); + throw new FormatError( + 'Invalid XRef table: unexpected first object'); } return obj; }, @@ -944,11 +949,13 @@ var XRef = (function XRefClosure() { var n = entryRanges[1]; if (!isInt(first) || !isInt(n)) { - error('Invalid XRef range fields: ' + first + ', ' + n); + throw new FormatError( + `Invalid XRef range fields: ${first}, ${n}`); } if (!isInt(typeFieldWidth) || !isInt(offsetFieldWidth) || !isInt(generationFieldWidth)) { - error('Invalid XRef entry fields length: ' + first + ', ' + n); + throw new FormatError( + `Invalid XRef entry fields length: ${first}, ${n}`); } for (i = streamState.entryNum; i < n; ++i) { streamState.entryNum = i; @@ -981,7 +988,7 @@ var XRef = (function XRefClosure() { case 2: break; default: - error('Invalid XRef entry type: ' + type); + throw new FormatError(`Invalid XRef entry type: ${type}`); } if (!this.entries[first + i]) { this.entries[first + i] = entry; @@ -1126,7 +1133,6 @@ var XRef = (function XRefClosure() { return dict; } // nothing helps - // calling error() would reject worker with an UnknownErrorException. throw new InvalidPDFException('Invalid PDF structure'); }, @@ -1167,17 +1173,17 @@ var XRef = (function XRefClosure() { if (!isInt(parser.getObj()) || !isCmd(parser.getObj(), 'obj') || !isStream(obj = parser.getObj())) { - error('Invalid XRef stream'); + throw new FormatError('Invalid XRef stream'); } dict = this.processXRefStream(obj); if (!this.topDict) { this.topDict = dict; } if (!dict) { - error('Failed to read XRef stream'); + throw new FormatError('Failed to read XRef stream'); } } else { - error('Invalid XRef stream header'); + throw new FormatError('Invalid XRef stream header'); } // Recursively get previous dictionary, if any @@ -1260,7 +1266,7 @@ var XRef = (function XRefClosure() { var gen = ref.gen; var num = ref.num; if (xrefEntry.gen !== gen) { - error('inconsistent generation in XRef'); + throw new FormatError('inconsistent generation in XRef'); } var stream = this.stream.makeSubStream(xrefEntry.offset + this.stream.start); @@ -1271,7 +1277,7 @@ var XRef = (function XRefClosure() { if (!isInt(obj1) || parseInt(obj1, 10) !== num || !isInt(obj2) || parseInt(obj2, 10) !== gen || !isCmd(obj3)) { - error('bad XRef entry'); + throw new FormatError('bad XRef entry'); } if (!isCmd(obj3, 'obj')) { // some bad PDFs use "obj1234" and really mean 1234 @@ -1281,7 +1287,7 @@ var XRef = (function XRefClosure() { return num; } } - error('bad XRef entry'); + throw new FormatError('bad XRef entry'); } if (this.encrypt && !suppressEncryption) { xrefEntry = parser.getObj(this.encrypt.createCipherTransform(num, gen)); @@ -1299,12 +1305,13 @@ var XRef = (function XRefClosure() { var tableOffset = xrefEntry.offset; var stream = this.fetch(new Ref(tableOffset, 0)); if (!isStream(stream)) { - error('bad ObjStm stream'); + throw new FormatError('bad ObjStm stream'); } var first = stream.dict.get('First'); var n = stream.dict.get('N'); if (!isInt(first) || !isInt(n)) { - error('invalid first and n parameters for ObjStm stream'); + throw new FormatError( + 'invalid first and n parameters for ObjStm stream'); } var parser = new Parser(new Lexer(stream), false, this); parser.allowStreams = true; @@ -1313,12 +1320,14 @@ var XRef = (function XRefClosure() { for (i = 0; i < n; ++i) { num = parser.getObj(); if (!isInt(num)) { - error('invalid object number in the ObjStm stream: ' + num); + throw new FormatError( + `invalid object number in the ObjStm stream: ${num}`); } nums.push(num); var offset = parser.getObj(); if (!isInt(offset)) { - error('invalid object offset in the ObjStm stream: ' + offset); + throw new FormatError( + `invalid object offset in the ObjStm stream: ${offset}`); } } // read stream objects for cache @@ -1337,7 +1346,7 @@ var XRef = (function XRefClosure() { } xrefEntry = entries[xrefEntry.gen]; if (xrefEntry === undefined) { - error('bad XRef entry for compressed object'); + throw new FormatError('bad XRef entry for compressed object'); } return xrefEntry; }, diff --git a/src/core/parser.js b/src/core/parser.js index 0527815a7..29c433ee0 100644 --- a/src/core/parser.js +++ b/src/core/parser.js @@ -18,8 +18,8 @@ import { JpegStream, JpxStream, LZWStream, NullStream, PredictorStream, RunLengthStream } from './stream'; import { - assert, error, info, isArray, isInt, isNum, isString, MissingDataException, - StreamType, warn + assert, FormatError, info, isArray, isInt, isNum, isString, + MissingDataException, StreamType, warn } from '../shared/util'; import { Cmd, Dict, EOF, isCmd, isDict, isEOF, isName, Name, Ref @@ -79,7 +79,7 @@ var Parser = (function ParserClosure() { } if (isEOF(this.buf1)) { if (!this.recoveryMode) { - error('End of file inside array'); + throw new FormatError('End of file inside array'); } return array; } @@ -103,7 +103,7 @@ var Parser = (function ParserClosure() { } if (isEOF(this.buf1)) { if (!this.recoveryMode) { - error('End of file inside dictionary'); + throw new FormatError('End of file inside dictionary'); } return dict; } @@ -348,7 +348,7 @@ var Parser = (function ParserClosure() { var dict = new Dict(this.xref); while (!isCmd(this.buf1, 'ID') && !isEOF(this.buf1)) { if (!isName(this.buf1)) { - error('Dictionary key must be a name object'); + throw new FormatError('Dictionary key must be a name object'); } var key = this.buf1.name; this.shift(); @@ -482,7 +482,7 @@ var Parser = (function ParserClosure() { stream.pos += scanLength; } if (!found) { - error('Missing endstream'); + throw new FormatError('Missing endstream'); } length = skipped; @@ -517,7 +517,7 @@ var Parser = (function ParserClosure() { for (var i = 0, ii = filterArray.length; i < ii; ++i) { filter = this.xref.fetchIfRef(filterArray[i]); if (!isName(filter)) { - error('Bad filter name: ' + filter); + throw new FormatError('Bad filter name: ' + filter); } params = null; @@ -694,7 +694,8 @@ var Lexer = (function LexerClosure() { } while (ch === 0x0A || ch === 0x0D); } if (ch < 0x30 || ch > 0x39) { // '0' - '9' - error(`Invalid number: ${String.fromCharCode(ch)} (charCode ${ch})`); + throw new FormatError( + `Invalid number: ${String.fromCharCode(ch)} (charCode ${ch})`); } var baseValue = ch - 0x30; // '0' @@ -989,8 +990,7 @@ var Lexer = (function LexerClosure() { // containing try-catch statements, since we would otherwise attempt // to parse the *same* character over and over (fixes issue8061.pdf). this.nextChar(); - error('Illegal character: ' + ch); - break; + throw new FormatError(`Illegal character: ${ch}`); } // command @@ -1005,7 +1005,7 @@ var Lexer = (function LexerClosure() { break; } if (str.length === 128) { - error('Command token too long: ' + str.length); + throw new FormatError(`Command token too long: ${str.length}`); } str = possibleCommand; knownCommandFound = knownCommands && knownCommands[str] !== undefined; diff --git a/src/core/pattern.js b/src/core/pattern.js index ccaa4b8e8..37a25e666 100644 --- a/src/core/pattern.js +++ b/src/core/pattern.js @@ -15,7 +15,8 @@ /* eslint-disable no-multi-spaces */ import { - assert, error, info, MissingDataException, UNSUPPORTED_FEATURES, Util, warn + assert, FormatError, info, MissingDataException, unreachable, + UNSUPPORTED_FEATURES, Util, warn } from '../shared/util'; import { ColorSpace } from './colorspace'; import { isStream } from './primitives'; @@ -34,14 +35,14 @@ var ShadingType = { var Pattern = (function PatternClosure() { // Constructor should define this.getPattern function Pattern() { - error('should not call Pattern constructor'); + throw new Error('should not call Pattern constructor'); } Pattern.prototype = { // Input: current Canvas context // Output: the appropriate fillStyle or strokeStyle getPattern: function Pattern_getPattern(ctx) { - error('Should not call Pattern.getStyle: ' + ctx); + throw new Error(`Should not call Pattern.getStyle: ${ctx}`); }, }; @@ -63,7 +64,7 @@ var Pattern = (function PatternClosure() { case ShadingType.TENSOR_PATCH_MESH: return new Shadings.Mesh(shading, matrix, xref, res); default: - throw new Error('Unsupported ShadingType: ' + type); + throw new FormatError('Unsupported ShadingType: ' + type); } } catch (ex) { if (ex instanceof MissingDataException) { @@ -198,7 +199,7 @@ Shadings.RadialAxial = (function RadialAxialClosure() { r1 = coordsArr[5]; type = 'radial'; } else { - error('getPattern type unknown: ' + shadingType); + unreachable(`getPattern type unknown: ${shadingType}`); } var matrix = this.matrix; @@ -754,7 +755,7 @@ Shadings.Mesh = (function MeshClosure() { patchMesh = true; break; default: - error('Unsupported mesh type.'); + unreachable('Unsupported mesh type.'); break; } @@ -805,7 +806,7 @@ function getTilingPatternIR(operatorList, dict, args) { // Ensure that the pattern has a non-zero width and height, to prevent errors // in `pattern_helper.js` (fixes issue8330.pdf). if ((bbox[2] - bbox[0]) === 0 || (bbox[3] - bbox[1]) === 0) { - throw new Error(`getTilingPatternIR - invalid /BBox array: [${bbox}].`); + throw new FormatError(`Invalid getTilingPatternIR /BBox array: [${bbox}].`); } return [ diff --git a/src/core/ps_parser.js b/src/core/ps_parser.js index 6dc05f42f..5fa02fbea 100644 --- a/src/core/ps_parser.js +++ b/src/core/ps_parser.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { error, isSpace } from '../shared/util'; +import { FormatError, isSpace } from '../shared/util'; import { EOF } from './primitives'; var PostScriptParser = (function PostScriptParserClosure() { @@ -39,8 +39,8 @@ var PostScriptParser = (function PostScriptParserClosure() { if (this.accept(type)) { return true; } - error('Unexpected symbol: found ' + this.token.type + ' expected ' + - type + '.'); + throw new FormatError( + `Unexpected symbol: found ${this.token.type} expected ${type}.`); }, parse: function PostScriptParser_parse() { this.nextToken(); @@ -89,7 +89,7 @@ var PostScriptParser = (function PostScriptParserClosure() { this.operators[conditionLocation] = endOfTrue; this.operators[conditionLocation + 1] = 'jz'; } else { - error('PS Function: error parsing conditional.'); + throw new FormatError('PS Function: error parsing conditional.'); } }, }; @@ -211,7 +211,7 @@ var PostScriptLexer = (function PostScriptLexerClosure() { } var value = parseFloat(strBuf.join('')); if (isNaN(value)) { - error('Invalid floating point number: ' + value); + throw new FormatError(`Invalid floating point number: ${value}`); } return value; }, diff --git a/src/core/stream.js b/src/core/stream.js index 50a8325bc..17b764e6e 100644 --- a/src/core/stream.js +++ b/src/core/stream.js @@ -14,7 +14,7 @@ */ import { - createObjectURL, error, info, isArray, isInt, isSpace, shadow, Util + createObjectURL, FormatError, info, isArray, isInt, isSpace, shadow, Util } from '../shared/util'; import { Dict, isDict, isStream } from './primitives'; import { Jbig2Image } from './jbig2'; @@ -392,16 +392,19 @@ var FlateStream = (function FlateStreamClosure() { var cmf = str.getByte(); var flg = str.getByte(); if (cmf === -1 || flg === -1) { - error('Invalid header in flate stream: ' + cmf + ', ' + flg); + throw new FormatError( + `Invalid header in flate stream: ${cmf}, ${flg}`); } if ((cmf & 0x0f) !== 0x08) { - error('Unknown compression method in flate stream: ' + cmf + ', ' + flg); + throw new FormatError( + `Unknown compression method in flate stream: ${cmf}, ${flg}`); } if ((((cmf << 8) + flg) % 31) !== 0) { - error('Bad FCHECK in flate stream: ' + cmf + ', ' + flg); + throw new FormatError(`Bad FCHECK in flate stream: ${cmf}, ${flg}`); } if (flg & 0x20) { - error('FDICT bit set in flate stream: ' + cmf + ', ' + flg); + throw new FormatError( + `FDICT bit set in flate stream: ${cmf}, ${flg}`); } this.codeSize = 0; @@ -420,7 +423,7 @@ var FlateStream = (function FlateStreamClosure() { var b; while (codeSize < bits) { if ((b = str.getByte()) === -1) { - error('Bad encoding in flate stream'); + throw new FormatError('Bad encoding in flate stream'); } codeBuf |= b << codeSize; codeSize += 8; @@ -453,7 +456,7 @@ var FlateStream = (function FlateStreamClosure() { var codeLen = code >> 16; var codeVal = code & 0xffff; if (codeLen < 1 || codeSize < codeLen) { - error('Bad encoding in flate stream'); + throw new FormatError('Bad encoding in flate stream'); } this.codeBuf = (codeBuf >> codeLen); this.codeSize = (codeSize - codeLen); @@ -515,25 +518,26 @@ var FlateStream = (function FlateStreamClosure() { var b; if ((b = str.getByte()) === -1) { - error('Bad block header in flate stream'); + throw new FormatError('Bad block header in flate stream'); } var blockLen = b; if ((b = str.getByte()) === -1) { - error('Bad block header in flate stream'); + throw new FormatError('Bad block header in flate stream'); } blockLen |= (b << 8); if ((b = str.getByte()) === -1) { - error('Bad block header in flate stream'); + throw new FormatError('Bad block header in flate stream'); } var check = b; if ((b = str.getByte()) === -1) { - error('Bad block header in flate stream'); + throw new FormatError('Bad block header in flate stream'); } check |= (b << 8); if (check !== (~blockLen & 0xffff) && (blockLen !== 0 || check !== 0)) { // Ignoring error for bad "empty" block (see issue 1277) - error('Bad uncompressed block length in flate stream'); + throw new FormatError( + 'Bad uncompressed block length in flate stream'); } this.codeBuf = 0; @@ -608,7 +612,7 @@ var FlateStream = (function FlateStreamClosure() { distCodeTable = this.generateHuffmanTable(codeLengths.subarray(numLitCodes, codes)); } else { - error('Unknown block type in flate stream'); + throw new FormatError('Unknown block type in flate stream'); } buffer = this.buffer; @@ -666,7 +670,7 @@ var PredictorStream = (function PredictorStreamClosure() { return str; // no prediction } if (predictor !== 2 && (predictor < 10 || predictor > 15)) { - error('Unsupported predictor: ' + predictor); + throw new FormatError(`Unsupported predictor: ${predictor}`); } if (predictor === 2) { @@ -851,7 +855,7 @@ var PredictorStream = (function PredictorStreamClosure() { } break; default: - error('Unsupported predictor: ' + predictor); + throw new FormatError(`Unsupported predictor: ${predictor}`); } this.bufferLength += rowBytes; }; diff --git a/src/display/api.js b/src/display/api.js index effecb128..ed74c722d 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -15,7 +15,7 @@ /* globals requirejs, __pdfjsdev_webpack__ */ import { - createPromiseCapability, deprecated, error, getVerbosityLevel, globalScope, + createPromiseCapability, deprecated, getVerbosityLevel, globalScope, info, InvalidPDFException, isArray, isArrayBuffer, isInt, isSameOrigin, loadJpegStream, MessageHandler, MissingPDFException, NativeImageDecoding, PageViewport, PasswordException, StatTimer, stringToBytes, @@ -198,11 +198,12 @@ function getDocument(src, pdfDataRangeTransport, source = { range: src, }; } else { if (typeof src !== 'object') { - error('Invalid parameter in getDocument, need either Uint8Array, ' + - 'string or a parameter object'); + throw new Error('Invalid parameter in getDocument, ' + + 'need either Uint8Array, string or a parameter object'); } if (!src.url && !src.data && !src.range) { - error('Invalid parameter object: need either .data, .range or .url'); + throw new Error( + 'Invalid parameter object: need either .data, .range or .url'); } source = src; @@ -235,8 +236,9 @@ function getDocument(src, pdfDataRangeTransport, } else if (isArrayBuffer(pdfBytes)) { params[key] = new Uint8Array(pdfBytes); } else { - error('Invalid PDF binary data: either typed array, string or ' + - 'array-like object is expected in the data property.'); + throw new Error('Invalid PDF binary data: either typed array, ' + + 'string or array-like object is expected in the ' + + 'data property.'); } continue; } else if (key === 'CMapReaderFactory') { @@ -1214,7 +1216,7 @@ var PDFWorker = (function PDFWorkerClosure() { pdfjsFilePath) { return pdfjsFilePath.replace(/(\.(?:min\.)?js)(\?.*)?$/i, '.worker$1$2'); } - error('No PDFJS.workerSrc specified'); + throw new Error('No PDFJS.workerSrc specified'); } let fakeWorkerFilesLoadedCapability; @@ -1730,7 +1732,7 @@ var WorkerTransport = (function WorkerTransportClosure() { this.commonObjs.resolve(id, data[2]); break; default: - error('Got unknown common object type ' + type); + throw new Error(`Got unknown common object type ${type}`); } }, this); @@ -1765,7 +1767,7 @@ var WorkerTransport = (function WorkerTransportClosure() { } break; default: - error('Got unknown object type ' + type); + throw new Error(`Got unknown object type ${type}`); } }, this); @@ -1794,7 +1796,7 @@ var WorkerTransport = (function WorkerTransportClosure() { if (intentState.displayReadyCapability) { intentState.displayReadyCapability.reject(data.error); } else { - error(data.error); + throw new Error(data.error); } if (intentState.operatorList) { @@ -2038,7 +2040,7 @@ var PDFObjects = (function PDFObjectsClosure() { // If there isn't an object yet or the object isn't resolved, then the // data isn't ready yet! if (!obj || !obj.resolved) { - error('Requesting object that isn\'t resolved yet ' + objId); + throw new Error(`Requesting object that isn't resolved yet ${objId}`); } return obj.data; diff --git a/src/display/canvas.js b/src/display/canvas.js index 4216b2d25..cd0ae59e6 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -14,8 +14,8 @@ */ import { - assert, error, FONT_IDENTITY_MATRIX, IDENTITY_MATRIX, ImageKind, info, - isArray, isLittleEndian, isNum, OPS, shadow, TextRenderingMode, Util, warn + assert, FONT_IDENTITY_MATRIX, IDENTITY_MATRIX, ImageKind, info, isArray, + isLittleEndian, isNum, OPS, shadow, TextRenderingMode, Util, warn } from '../shared/util'; import { getShadingPatternFromIR, TilingPattern } from './pattern_helper'; import { WebGLUtils } from './webgl'; @@ -553,7 +553,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); } } else { - error('bad image kind: ' + imgData.kind); + throw new Error(`bad image kind: ${imgData.kind}`); } } @@ -1277,7 +1277,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var current = this.current; if (!fontObj) { - error('Can\'t find font for ' + fontRefName); + throw new Error(`Can't find font for ${fontRefName}`); } current.fontMatrix = (fontObj.fontMatrix ? @@ -1716,10 +1716,10 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { // Images beginInlineImage: function CanvasGraphics_beginInlineImage() { - error('Should not call beginInlineImage'); + throw new Error('Should not call beginInlineImage'); }, beginImageData: function CanvasGraphics_beginImageData() { - error('Should not call beginImageData'); + throw new Error('Should not call beginImageData'); }, paintFormXObjectBegin: function CanvasGraphics_paintFormXObjectBegin(matrix, diff --git a/src/display/metadata.js b/src/display/metadata.js index 28f4376f6..a77a138e7 100644 --- a/src/display/metadata.js +++ b/src/display/metadata.js @@ -13,8 +13,6 @@ * limitations under the License. */ -import { error } from '../shared/util'; - function fixMetadata(meta) { return meta.replace(/>\\376\\377([^<]+)/g, function(all, codes) { var bytes = codes.replace(/\\([0-3])([0-7])([0-7])/g, @@ -40,7 +38,7 @@ function Metadata(meta) { var parser = new DOMParser(); meta = parser.parseFromString(meta, 'application/xml'); } else if (!(meta instanceof Document)) { - error('Metadata: Invalid metadata object'); + throw new Error('Metadata: Invalid metadata object'); } this.metaDocument = meta; diff --git a/src/display/pattern_helper.js b/src/display/pattern_helper.js index 97256eafc..e05cc10bd 100644 --- a/src/display/pattern_helper.js +++ b/src/display/pattern_helper.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { error, info, isArray, Util } from '../shared/util'; +import { FormatError, info, isArray, Util } from '../shared/util'; import { WebGLUtils } from './webgl'; var ShadingIRs = {}; @@ -140,8 +140,7 @@ var createMeshCanvas = (function createMeshCanvasClosure() { } break; default: - error('illigal figure'); - break; + throw new Error('illegal figure'); } } @@ -288,7 +287,7 @@ ShadingIRs.Dummy = { function getShadingPatternFromIR(raw) { var shadingIR = ShadingIRs[raw[0]]; if (!shadingIR) { - error('Unknown IR type: ' + raw[0]); + throw new Error(`Unknown IR type: ${raw[0]}`); } return shadingIR.fromIR(raw); } @@ -415,7 +414,7 @@ var TilingPattern = (function TilingPatternClosure() { context.strokeStyle = cssColor; break; default: - error('Unsupported paint type: ' + paintType); + throw new FormatError(`Unsupported paint type: ${paintType}`); } }, diff --git a/src/shared/fonts_utils.js b/src/shared/fonts_utils.js index d9a24f662..34a40c17a 100644 --- a/src/shared/fonts_utils.js +++ b/src/shared/fonts_utils.js @@ -13,7 +13,7 @@ * limitations under the License. */ /* globals CFFDictDataMap, CFFDictPrivateDataMap, CFFEncodingMap, CFFStrings, - Components, Dict, dump, error, isNum, netscape, Stream */ + Components, Dict, dump, FormatError, isNum, netscape, Stream */ 'use strict'; @@ -54,7 +54,7 @@ function readCharset(aStream, aCharstrings) { } } } else { - error('Invalid charset format'); + throw new FormatError('Invalid charset format'); } return charset; @@ -176,7 +176,7 @@ function readFontDictData(aString, aMap) { } else if (value <= 254) { token = -(value - 251) * 256 - aString[i++] - 108; } else if (value === 255) { - error('255 is not a valid DICT command'); + throw new FormatError('255 is not a valid DICT command'); } fontDictDataTokens.push(token); @@ -217,8 +217,7 @@ function readFontIndexData(aStream, aIsByte) { return aStream.getByte() << 24 | aStream.getByte() << 16 | aStream.getByte() << 8 | aStream.getByte(); } - error(offsize + ' is not a valid offset size'); - return null; + throw new FormatError(offsize + ' is not a valid offset size'); } var offsets = []; @@ -375,11 +374,11 @@ var Type2Parser = function type2Parser(aFilePath) { dump('Read Charset for ' + charStrings.length + ' glyphs'); var charsetEntry = font.get('charset'); if (charsetEntry === 0) { - error('Need to support CFFISOAdobeCharset'); + throw new FormatError('Need to support CFFISOAdobeCharset'); } else if (charsetEntry === 1) { - error('Need to support CFFExpert'); + throw new FormatError('Need to support CFFExpert'); } else if (charsetEntry === 2) { - error('Need to support CFFExpertSubsetCharset'); + throw new FormatError('Need to support CFFExpertSubsetCharset'); } else { aStream.pos = charsetEntry; readCharset(aStream, charStrings); diff --git a/src/shared/util.js b/src/shared/util.js index 7cd30a027..31ac174b8 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -288,27 +288,13 @@ function deprecated(details) { console.log('Deprecated API usage: ' + details); } -// Fatal errors that should trigger the fallback UI and halt execution by -// throwing an exception. -function error(msg) { - if (verbosity >= VERBOSITY_LEVELS.errors) { - console.log('Error: ' + msg); - console.log(backtrace()); - } +function unreachable(msg) { throw new Error(msg); } -function backtrace() { - try { - throw new Error(); - } catch (e) { - return e.stack ? e.stack.split('\n').slice(2).join('\n') : ''; - } -} - function assert(cond, msg) { if (!cond) { - error(msg); + unreachable(msg); } } @@ -499,6 +485,21 @@ var XRefParseException = (function XRefParseExceptionClosure() { return XRefParseException; })(); +/** + * Error caused during parsing PDF data. + */ +let FormatError = (function FormatErrorClosure() { + function FormatError(msg) { + this.message = msg; + } + + FormatError.prototype = new Error(); + FormatError.prototype.name = 'FormatError'; + FormatError.constructor = FormatError; + + return FormatError; +})(); + var NullCharactersRegExp = /\x00/g; function removeNullCharacters(str) { @@ -1266,7 +1267,7 @@ function MessageHandler(sourceName, targetName, comObj) { callback.resolve(data.data); } } else { - error('Cannot resolve callback ' + callbackId); + throw new Error(`Cannot resolve callback ${callbackId}`); } } else if (data.action in ah) { let action = ah[data.action]; @@ -1302,7 +1303,7 @@ function MessageHandler(sourceName, targetName, comObj) { action[0].call(action[1], data.data); } } else { - error('Unknown action from worker: ' + data.action); + throw new Error(`Unknown action from worker: ${data.action}`); } }; comObj.addEventListener('message', this._onComObjOnMessage); @@ -1312,7 +1313,7 @@ MessageHandler.prototype = { on(actionName, handler, scope) { var ah = this.actionHandler; if (ah[actionName]) { - error('There is already an actionName called "' + actionName + '"'); + throw new Error(`There is already an actionName called "${actionName}"`); } ah[actionName] = [handler, scope]; }, @@ -1633,6 +1634,7 @@ export { UnknownErrorException, Util, XRefParseException, + FormatError, arrayByteLength, arraysToBytes, assert, @@ -1641,7 +1643,6 @@ export { createPromiseCapability, createObjectURL, deprecated, - error, getLookupTableFactory, getVerbosityLevel, globalScope, @@ -1674,4 +1675,5 @@ export { stringToUTF8String, utf8StringToString, warn, + unreachable, };