: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
dictMap[key] = this.getObj(cipherTransform);
if (lexer.beginInlineImagePos !== -1) {
dictLength = stream.pos - lexer.beginInlineImagePos;
const filter = this.xref.fetchIfRef(dictMap.F || dictMap.Filter);
if (filter instanceof Name) {
filterName = filter.name;
} else if (Array.isArray(filter)) {
const filterZero = this.xref.fetchIfRef(filter[0]);
if (filterZero instanceof Name) {
filterName = filterZero.name;
const startPos = stream.pos;
length = this.findDCTDecodeInlineStreamEnd(stream);
length = this.findASCII85DecodeInlineStreamEnd(stream);
length = this.findASCIIHexDecodeInlineStreamEnd(stream);
length = this.findDefaultInlineStreamEnd(stream);
if (length < MAX_LENGTH_TO_CACHE && dictLength > 0) {
const initialStreamPos = stream.pos;
stream.pos = lexer.beginInlineImagePos;
cacheKey = getInlineImageCacheKey(stream.getBytes(dictLength + length));
stream.pos = initialStreamPos;
const cacheEntry = this.imageCache[cacheKey];
if (cacheEntry !== undefined) {
this.buf2 = Cmd.get("EI");
const dict = new Dict(this.xref);
for (const key in dictMap) {
dict.set(key, dictMap[key]);
let imageStream = stream.makeSubStream(startPos, length, dict);
imageStream = cipherTransform.createStream(imageStream, length);
imageStream = this.filter(imageStream, dict, length);
if (cacheKey !== undefined) {
imageStream.cacheKey = `inline_img_${++this._imageId}`;
this.imageCache[cacheKey] = imageStream;
this.buf2 = Cmd.get("EI");
#findStreamLength(startPos) {
const SCAN_BLOCK_LENGTH = 2048;
const signatureLength = "endstream".length;
const END_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64]);
const endLength = END_SIGNATURE.length;
const PARTIAL_SIGNATURE = [new Uint8Array([0x73, 0x74, 0x72, 0x65, 0x61, 0x6d]), new Uint8Array([0x73, 0x74, 0x65, 0x61, 0x6d]), new Uint8Array([0x73, 0x74, 0x72, 0x65, 0x61])];
const normalLength = signatureLength - endLength;
while (stream.pos < stream.end) {
const scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);
const scanLength = scanBytes.length - signatureLength;
while (pos < scanLength) {
while (j < endLength && scanBytes[pos + j] === END_SIGNATURE[j]) {
for (const part of PARTIAL_SIGNATURE) {
const partLen = part.length;
while (k < partLen && scanBytes[pos + j + k] === part[k]) {
const lastByte = scanBytes[pos + j + k];
if (isWhiteSpace(lastByte)) {
info(`Found "${bytesToString([...END_SIGNATURE, ...part])}" when ` + "searching for endstream command.");
return stream.pos - startPos;
stream.pos += scanLength;
makeStream(dict, cipherTransform) {
const lexer = this.lexer;
let stream = lexer.stream;
const startPos = stream.pos - 1;
let length = dict.get("Length");
if (!Number.isInteger(length)) {
info(`Bad length "${length && length.toString()}" in stream.`);
stream.pos = startPos + length;
if (this.tryShift() && isCmd(this.buf2, "endstream")) {
length = this.#findStreamLength(startPos);
throw new FormatError("Missing endstream command.");
stream = stream.makeSubStream(startPos, length, dict);
stream = cipherTransform.createStream(stream, length);
stream = this.filter(stream, dict, length);
filter(stream, dict, length) {
let filter = dict.get("F", "Filter");
let params = dict.get("DP", "DecodeParms");
if (filter instanceof Name) {
if (Array.isArray(params)) {
warn("/DecodeParms should not be an Array, when /Filter is a Name.");
return this.makeFilter(stream, filter.name, length, params);
let maybeLength = length;
if (Array.isArray(filter)) {
const filterArray = filter;
const paramsArray = params;
for (let i = 0, ii = filterArray.length; i < ii; ++i) {
filter = this.xref.fetchIfRef(filterArray[i]);
if (!(filter instanceof Name)) {
throw new FormatError(`Bad filter name "${filter}"`);
if (Array.isArray(paramsArray) && i in paramsArray) {
params = this.xref.fetchIfRef(paramsArray[i]);
stream = this.makeFilter(stream, filter.name, maybeLength, params);
makeFilter(stream, name, maybeLength, params) {
warn(`Empty "${name}" stream.`);
return new PredictorStream(new FlateStream(stream, maybeLength), maybeLength, params);
return new FlateStream(stream, maybeLength);
if (params.has("EarlyChange")) {
earlyChange = params.get("EarlyChange");
return new PredictorStream(new LZWStream(stream, maybeLength, earlyChange), maybeLength, params);
return new LZWStream(stream, maybeLength, earlyChange);
return new JpegStream(stream, maybeLength, params);
return new JpxStream(stream, maybeLength, params);
return new Ascii85Stream(stream, maybeLength);
return new AsciiHexStream(stream, maybeLength);
return new CCITTFaxStream(stream, maybeLength, params);
return new RunLengthStream(stream, maybeLength);
return new Jbig2Stream(stream, maybeLength, params);
warn(`Filter "${name}" is not supported.`);
if (ex instanceof MissingDataException) {
warn(`Invalid stream: "${ex}"`);
const specialChars = [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
function toHexDigit(ch) {
if (ch >= 0x30 && ch <= 0x39) {
if (ch >= 0x41 && ch <= 0x46 || ch >= 0x61 && ch <= 0x66) {
constructor(stream, knownCommands = null) {
this.knownCommands = knownCommands;
this._hexStringNumWarn = 0;
this.beginInlineImagePos = -1;
return this.currentChar = this.stream.getByte();
return this.stream.peekByte();
let ch = this.currentChar;
} else if (ch === 0x2b) {
if (ch === 0x0a || ch === 0x0d) {
} while (ch === 0x0a || ch === 0x0d);
if (ch < 0x30 || ch > 0x39) {
const msg = `Invalid number: ${String.fromCharCode(ch)} (charCode ${ch})`;
if (isWhiteSpace(ch) || ch === -1) {
info(`Lexer.getNumber - "${msg}".`);
throw new FormatError(msg);
let baseValue = ch - 0x30;
while ((ch = this.nextChar()) >= 0) {
if (ch >= 0x30 && ch <= 0x39) {
const currentDigit = ch - 0x30;
powerValue = powerValue * 10 + currentDigit;
baseValue = baseValue * 10 + currentDigit;
} else if (ch === 0x2e) {
} else if (ch === 0x2d) {
warn("Badly formatted number: minus sign in the middle");
} else if (ch === 0x45 || ch === 0x65) {
if (ch === 0x2b || ch === 0x2d) {
powerValueSign = ch === 0x2d ? -1 : 1;
} else if (ch < 0x30 || ch > 0x39) {
baseValue *= 10 ** (powerValueSign * powerValue);
const strBuf = this.strBuf;
let ch = this.nextChar();
let charBuffered = false;
warn("Unterminated string");
warn("Unterminated string");
strBuf.push(String.fromCharCode(ch));
if (ch >= 0x30 && ch <= 0x37) {
x = (x << 3) + (ch & 0x0f);
if (ch >= 0x30 && ch <= 0x37) {
x = (x << 3) + (ch & 0x0f);
strBuf.push(String.fromCharCode(x));
if (this.peekChar() === 0x0a) {
strBuf.push(String.fromCharCode(ch));
strBuf.push(String.fromCharCode(ch));
const strBuf = this.strBuf;
while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) {
warn("Lexer_getName: " + "NUMBER SIGN (#) should be followed by a hexadecimal number.");
const x = toHexDigit(ch);
const x2 = toHexDigit(ch);
warn(`Lexer_getName: Illegal digit (${String.fromCharCode(ch)}) ` + "in hexadecimal number.");
strBuf.push("#", String.fromCharCode(previousCh));
strBuf.push(String.fromCharCode(ch));
strBuf.push(String.fromCharCode(x << 4 | x2));
strBuf.push("#", String.fromCharCode(ch));
strBuf.push(String.fromCharCode(ch));
if (strBuf.length > 127) {
warn(`Name token is longer than allowed by the spec: ${strBuf.length}`);
return Name.get(strBuf.join(""));
const MAX_HEX_STRING_NUM_WARN = 5;
if (this._hexStringNumWarn++ === MAX_HEX_STRING_NUM_WARN) {
warn("getHexString - ignoring additional invalid characters.");
if (this._hexStringNumWarn > MAX_HEX_STRING_NUM_WARN) {
warn(`getHexString - ignoring invalid character: ${ch}`);
const strBuf = this.strBuf;
let ch = this.currentChar;
let firstDigit, secondDigit;
this._hexStringNumWarn = 0;
warn("Unterminated hex string");
} else if (ch === 0x3e) {
} else if (specialChars[ch] === 1) {