: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
this.data.annotationType = AnnotationType.STRIKEOUT;
const quadPoints = this.data.quadPoints = getQuadPoints(dict, null);
const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];
const strokeAlpha = dict.get("CA");
this._setDefaultAppearance({
pointsCallback: (buffer, points) => {
buffer.push(`${(points[0].x + points[2].x) / 2} ` + `${(points[0].y + points[2].y) / 2} m`, `${(points[1].x + points[3].x) / 2} ` + `${(points[1].y + points[3].y) / 2} l`, "S");
return [points[0].x, points[1].x, points[3].y, points[1].y];
this.data.popupRef = null;
class StampAnnotation extends MarkupAnnotation {
this.data.annotationType = AnnotationType.STAMP;
this.data.hasOwnCanvas = this.data.noRotate;
this.data.noHTML = false;
static async createImage(bitmap, xref) {
const canvas = new OffscreenCanvas(width, height);
const ctx = canvas.getContext("2d", {
ctx.drawImage(bitmap, 0, 0);
const data = ctx.getImageData(0, 0, width, height).data;
const buf32 = new Uint32Array(data.buffer);
const hasAlpha = buf32.some(FeatureTest.isLittleEndian ? x => x >>> 24 !== 0xff : x => (x & 0xff) !== 0xff);
ctx.fillRect(0, 0, width, height);
ctx.drawImage(bitmap, 0, 0);
const jpegBufferPromise = canvas.convertToBlob({
}).then(blob => blob.arrayBuffer());
const xobjectName = Name.get("XObject");
const imageName = Name.get("Image");
const image = new Dict(xref);
image.set("Type", xobjectName);
image.set("Subtype", imageName);
image.set("BitsPerComponent", 8);
image.set("ColorSpace", Name.get("DeviceRGB"));
image.set("Filter", Name.get("DCTDecode"));
image.set("BBox", [0, 0, width, height]);
image.set("Width", width);
image.set("Height", height);
const alphaBuffer = new Uint8Array(buf32.length);
if (FeatureTest.isLittleEndian) {
for (let i = 0, ii = buf32.length; i < ii; i++) {
alphaBuffer[i] = buf32[i] >>> 24;
for (let i = 0, ii = buf32.length; i < ii; i++) {
alphaBuffer[i] = buf32[i] & 0xff;
const smask = new Dict(xref);
smask.set("Type", xobjectName);
smask.set("Subtype", imageName);
smask.set("BitsPerComponent", 8);
smask.set("ColorSpace", Name.get("DeviceGray"));
smask.set("Width", width);
smask.set("Height", height);
smaskStream = new Stream(alphaBuffer, 0, 0, smask);
const imageStream = new Stream(await jpegBufferPromise, 0, 0, image);
static createNewDict(annotation, xref, {
const stamp = new Dict(xref);
stamp.set("Type", Name.get("Annot"));
stamp.set("Subtype", Name.get("Stamp"));
stamp.set("CreationDate", `D:${getModificationDate()}`);
stamp.set("Border", [0, 0, 0]);
stamp.set("Rotate", rotation);
stamp.set("T", isAscii(user) ? user : stringToUTF16String(user, true));
const n = new Dict(xref);
static async createNewAppearanceStream(annotation, xref, params) {
const resources = new Dict(xref);
const xobject = new Dict(xref);
resources.set("XObject", xobject);
xobject.set("Im0", imageRef);
const appearance = `q ${width} 0 0 ${height} 0 0 cm /Im0 Do Q`;
const appearanceStreamDict = new Dict(xref);
appearanceStreamDict.set("FormType", 1);
appearanceStreamDict.set("Subtype", Name.get("Form"));
appearanceStreamDict.set("Type", Name.get("XObject"));
appearanceStreamDict.set("BBox", [0, 0, width, height]);
appearanceStreamDict.set("Resources", resources);
const matrix = getRotationMatrix(rotation, width, height);
appearanceStreamDict.set("Matrix", matrix);
const ap = new StringStream(appearance);
ap.dict = appearanceStreamDict;
class FileAttachmentAnnotation extends MarkupAnnotation {
const file = new FileSpec(dict.get("FS"), xref);
this.data.annotationType = AnnotationType.FILEATTACHMENT;
this.data.hasOwnCanvas = this.data.noRotate;
this.data.noHTML = false;
this.data.file = file.serializable;
const name = dict.get("Name");
this.data.name = name instanceof Name ? stringToPDFString(name.name) : "PushPin";
const fillAlpha = dict.get("ca");
this.data.fillAlpha = typeof fillAlpha === "number" && fillAlpha >= 0 && fillAlpha <= 1 ? fillAlpha : null;
;// CONCATENATED MODULE: ./src/core/dataset_reader.js
function decodeString(str) {
return stringToUTF8String(str);
warn(`UTF-8 decoding failed: "${ex}".`);
class DatasetXMLParser extends SimpleXMLParser {
const node = super.onEndElement(name);
if (node && name === "xfa:datasets") {
throw new Error("Aborting DatasetXMLParser.");
this.node = new SimpleXMLParser({
}).parseFromString(data.datasets).documentElement;
const parser = new DatasetXMLParser({
parser.parseFromString(data["xdp:xdp"]);
if (!this.node || !path) {
const node = this.node.searchNode(parseXFAPath(path), 0);
const first = node.firstChild;
if (first?.nodeName === "value") {
return node.children.map(child => decodeString(child.textContent));
return decodeString(node.textContent);
;// CONCATENATED MODULE: ./src/core/xref.js
constructor(stream, pdfManager) {
this.pdfManager = pdfManager;
this._xrefStms = new Set();
this._cacheMap = new Map();
this._pendingRefs = new RefSet();
this._newPersistentRefNum = null;
this._newTemporaryRefNum = null;
this._persistentRefsCache = null;
getNewPersistentRef(obj) {
if (this._newPersistentRefNum === null) {
this._newPersistentRefNum = this.entries.length || 1;
const num = this._newPersistentRefNum++;
this._cacheMap.set(num, obj);
if (this._newTemporaryRefNum === null) {
this._newTemporaryRefNum = this.entries.length || 1;
if (this._newPersistentRefNum) {
this._persistentRefsCache = new Map();
for (let i = this._newTemporaryRefNum; i < this._newPersistentRefNum; i++) {
this._persistentRefsCache.set(i, this._cacheMap.get(i));
this._cacheMap.delete(i);
return Ref.get(this._newTemporaryRefNum++, 0);
this._newTemporaryRefNum = null;
if (this._persistentRefsCache) {
for (const [num, obj] of this._persistentRefsCache) {
this._cacheMap.set(num, obj);
this._persistentRefsCache = null;
setStartXRef(startXRef) {
this.startXRefQueue = [startXRef];
parse(recoveryMode = false) {
trailerDict = this.readXRef();
warn("Indexing all PDF objects");
trailerDict = this.indexObjects();
trailerDict.assignXref(this);
this.trailer = trailerDict;
encrypt = trailerDict.get("Encrypt");
if (ex instanceof MissingDataException) {
warn(`XRef.parse - Invalid "Encrypt" reference: "${ex}".`);
if (encrypt instanceof Dict) {
const ids = trailerDict.get("ID");
const fileId = ids?.length ? ids[0] : "";
encrypt.suppressEncryption = true;
this.encrypt = new CipherTransformFactory(encrypt, fileId, this.pdfManager.password);
root = trailerDict.get("Root");
if (ex instanceof MissingDataException) {
warn(`XRef.parse - Invalid "Root" reference: "${ex}".`);
if (root instanceof Dict) {
const pages = root.get("Pages");
if (pages instanceof Dict) {
if (ex instanceof MissingDataException) {
warn(`XRef.parse - Invalid "Pages" reference: "${ex}".`);
throw new XRefParseException();
throw new InvalidPDFException("Invalid Root reference.");
processXRefTable(parser) {
if (!("tableState" in this)) {
streamPos: parser.lexer.stream.pos,
const obj = this.readXRefTable(parser);
if (!isCmd(obj, "trailer")) {
throw new FormatError("Invalid XRef table: could not find trailer dictionary");
let dict = parser.getObj();
if (!(dict instanceof Dict) && dict.dict) {
if (!(dict instanceof Dict)) {
throw new FormatError("Invalid XRef table: could not parse trailer dictionary");
const stream = parser.lexer.stream;
const tableState = this.tableState;
stream.pos = tableState.streamPos;
parser.buf1 = tableState.parserBuf1;
parser.buf2 = tableState.parserBuf2;
if (!("firstEntryNum" in tableState) || !("entryCount" in tableState)) {
if (isCmd(obj = parser.getObj(), "trailer")) {
tableState.firstEntryNum = obj;
tableState.entryCount = parser.getObj();
let first = tableState.firstEntryNum;
const count = tableState.entryCount;
if (!Number.isInteger(first) || !Number.isInteger(count)) {
throw new FormatError("Invalid XRef table: wrong types in subsection header");
for (let i = tableState.entryNum; i < count; i++) {
tableState.streamPos = stream.pos;
tableState.parserBuf1 = parser.buf1;
tableState.parserBuf2 = parser.buf2;
entry.offset = parser.getObj();
entry.gen = parser.getObj();
const type = parser.getObj();
if (type instanceof Cmd) {
entry.uncompressed = true;
if (!Number.isInteger(entry.offset) || !Number.isInteger(entry.gen) || !(entry.free || entry.uncompressed)) {
throw new FormatError(`Invalid entry in XRef subsection: ${first}, ${count}`);
if (i === 0 && entry.free && first === 1) {
if (!this.entries[i + first]) {
this.entries[i + first] = entry;
tableState.streamPos = stream.pos;
tableState.parserBuf1 = parser.buf1;
tableState.parserBuf2 = parser.buf2;
delete tableState.firstEntryNum;
delete tableState.entryCount;
if (this.entries[0] && !this.entries[0].free) {
throw new FormatError("Invalid XRef table: unexpected first object");
processXRefStream(stream) {
if (!("streamState" in this)) {
const streamParameters = stream.dict;
const byteWidths = streamParameters.get("W");
let range = streamParameters.get("Index");
range = [0, streamParameters.get("Size")];
this.readXRefStream(stream);
const streamState = this.streamState;
stream.pos = streamState.streamPos;
const [typeFieldWidth, offsetFieldWidth, generationFieldWidth] = streamState.byteWidths;
const entryRanges = streamState.entryRanges;
while (entryRanges.length > 0) {
const [first, n] = entryRanges;
if (!Number.isInteger(first) || !Number.isInteger(n)) {
throw new FormatError(`Invalid XRef range fields: ${first}, ${n}`);
if (!Number.isInteger(typeFieldWidth) || !Number.isInteger(offsetFieldWidth) || !Number.isInteger(generationFieldWidth)) {
throw new FormatError(`Invalid XRef entry fields length: ${first}, ${n}`);
for (let i = streamState.entryNum; i < n; ++i) {
streamState.entryNum = i;
streamState.streamPos = stream.pos;
for (let j = 0; j < typeFieldWidth; ++j) {
const typeByte = stream.getByte();
throw new FormatError("Invalid XRef byteWidths 'type'.");
type = type << 8 | typeByte;
if (typeFieldWidth === 0) {
for (let j = 0; j < offsetFieldWidth; ++j) {
const offsetByte = stream.getByte();
throw new FormatError("Invalid XRef byteWidths 'offset'.");
offset = offset << 8 | offsetByte;
for (let j = 0; j < generationFieldWidth; ++j) {
const generationByte = stream.getByte();
if (generationByte === -1) {
throw new FormatError("Invalid XRef byteWidths 'generation'.");
generation = generation << 8 | generationByte;