diff --git a/packages/pdfkit/package.json b/packages/pdfkit/package.json index b6659da4f..1e0179ecb 100644 --- a/packages/pdfkit/package.json +++ b/packages/pdfkit/package.json @@ -30,14 +30,13 @@ ], "dependencies": { "@babel/runtime": "^7.20.13", - "browserify-zlib": "^0.2.0", "@noble/ciphers": "^1.0.0", "@noble/hashes": "^1.6.0", "fontkit": "^2.0.2", "js-md5": "^0.8.3", "linebreak": "^1.1.0", - "png-js": "^2.0.0", - "vite-compatible-readable-stream": "^3.6.1" + "pako": "^2.1.0", + "png-js": "^2.0.0" }, "devDependencies": { "iconv-lite": "^0.4.13" diff --git a/packages/pdfkit/rollup.config.js b/packages/pdfkit/rollup.config.js index ccd1e4299..b7377c90f 100644 --- a/packages/pdfkit/rollup.config.js +++ b/packages/pdfkit/rollup.config.js @@ -18,11 +18,7 @@ const babelConfig = () => ({ }); const getExternal = ({ browser }) => [ - ...Object.keys(pkg.dependencies).filter( - (dep) => - !browser || - !['vite-compatible-readable-stream', 'browserify-zlib'].includes(dep) - ), + ...Object.keys(pkg.dependencies), /\/node_modules\/pako\//, /@babel\/runtime/, 'js-md5', @@ -38,7 +34,6 @@ const getPlugins = ({ browser }) => [ ignore(['fs']), alias({ entries: [ - // See https://github.com/browserify/browserify-zlib/pull/45 { find: 'pako/lib/zlib/zstream', replacement: 'pako/lib/zlib/zstream.js' @@ -46,9 +41,7 @@ const getPlugins = ({ browser }) => [ { find: 'pako/lib/zlib/constants', replacement: 'pako/lib/zlib/constants.js' - }, - { find: 'stream', replacement: 'vite-compatible-readable-stream' }, - { find: 'zlib', replacement: 'browserify-zlib' } + } ] }), commonjs(), diff --git a/packages/pdfkit/src/binary.js b/packages/pdfkit/src/binary.js new file mode 100644 index 000000000..3c9d9a463 --- /dev/null +++ b/packages/pdfkit/src/binary.js @@ -0,0 +1,77 @@ +/* +Binary helpers — Uint8Array-native replacements for Node Buffer operations. +*/ + +const HEX = '0123456789abcdef'; + +export const fromBinaryString = (str) => { + const out = new Uint8Array(str.length); + for (let i = 0; i < str.length; i++) out[i] = str.charCodeAt(i) & 0xff; + return out; +}; + +export const toBinaryString = (bytes) => { + const chunkSize = 0x8000; + let out = ''; + for (let i = 0; i < bytes.length; i += chunkSize) { + const end = Math.min(i + chunkSize, bytes.length); + out += String.fromCharCode.apply(null, bytes.subarray(i, end)); + } + return out; +}; + +export const fromUtf8String = (str) => new TextEncoder().encode(str); + +// Matches Buffer.from(`\ufeff${str}`, 'utf16le') + byte swap: UTF-16BE with BOM. +export const fromUtf16BEWithBOM = (str) => { + const withBom = `\ufeff${str}`; + const out = new Uint8Array(withBom.length * 2); + for (let i = 0; i < withBom.length; i++) { + const code = withBom.charCodeAt(i); + out[i * 2] = (code >> 8) & 0xff; + out[i * 2 + 1] = code & 0xff; + } + return out; +}; + +export const fromBase64 = (str) => fromBinaryString(atob(str)); + +export const toHex = (bytes) => { + let out = ''; + for (let i = 0; i < bytes.length; i++) { + out += HEX[bytes[i] >> 4] + HEX[bytes[i] & 0xf]; + } + return out; +}; + +export const concat = (arrays) => { + let total = 0; + for (const a of arrays) total += a.length; + const out = new Uint8Array(total); + let offset = 0; + for (const a of arrays) { + out.set(a, offset); + offset += a.length; + } + return out; +}; + +export const readUInt16BE = (bytes, offset = 0) => + ((bytes[offset] << 8) | bytes[offset + 1]) >>> 0; + +export const readUInt16LE = (bytes, offset = 0) => + ((bytes[offset + 1] << 8) | bytes[offset]) >>> 0; + +export const readUInt32BE = (bytes, offset = 0) => + (bytes[offset] * 0x1000000 + + ((bytes[offset + 1] << 16) | + (bytes[offset + 2] << 8) | + bytes[offset + 3])) >>> + 0; + +export const readUInt32LE = (bytes, offset = 0) => + ((bytes[offset] | + (bytes[offset + 1] << 8) | + (bytes[offset + 2] << 16)) + + bytes[offset + 3] * 0x1000000) >>> + 0; diff --git a/packages/pdfkit/src/document.js b/packages/pdfkit/src/document.js index b3296f4cd..782d7a406 100644 --- a/packages/pdfkit/src/document.js +++ b/packages/pdfkit/src/document.js @@ -3,7 +3,8 @@ PDFDocument - represents an entire PDF document By Devon Govett */ -import stream from 'stream'; +import MiniReadable from './mini-stream'; +import { fromBinaryString } from './binary'; import PDFObject from './object'; import PDFReference from './reference'; import PDFPage from './page'; @@ -24,9 +25,9 @@ import SubsetMixin from './mixins/subsets'; import TableMixin from './mixins/table'; import MetadataMixin from './mixins/metadata'; -class PDFDocument extends stream.Readable { +class PDFDocument extends MiniReadable { constructor(options = {}) { - super(options); + super(); this.options = options; // PDF version @@ -254,12 +255,9 @@ class PDFDocument extends stream.Readable { return ref; } - _read() {} - // do nothing, but this method is required by node - _write(data) { - if (!Buffer.isBuffer(data)) { - data = Buffer.from(data + '\n', 'binary'); + if (!(data instanceof Uint8Array)) { + data = fromBinaryString(data + '\n'); } this.push(data); diff --git a/packages/pdfkit/src/image.js b/packages/pdfkit/src/image.js index 23af05baf..ff84486fa 100644 --- a/packages/pdfkit/src/image.js +++ b/packages/pdfkit/src/image.js @@ -4,20 +4,21 @@ By Devon Govett */ import fs from 'fs'; +import { fromBase64 } from './binary'; import JPEG from './image/jpeg'; import PNG from './image/png'; class PDFImage { static open(src, label) { let data; - if (Buffer.isBuffer(src)) { + if (src instanceof Uint8Array) { data = src; } else if (src instanceof ArrayBuffer) { - data = Buffer.from(new Uint8Array(src)); + data = new Uint8Array(src); } else { const match = /^data:.+?;base64,(.*)$/.exec(src); if (match) { - data = Buffer.from(match[1], 'base64'); + data = fromBase64(match[1]); } else { data = fs.readFileSync(src); if (!data) { @@ -28,7 +29,12 @@ class PDFImage { if (data[0] === 0xff && data[1] === 0xd8) { return new JPEG(data, label); - } else if (data[0] === 0x89 && data.toString('ascii', 1, 4) === 'PNG') { + } else if ( + data[0] === 0x89 && + data[1] === 0x50 && + data[2] === 0x4e && + data[3] === 0x47 + ) { return new PNG(data, label); } else { throw new Error('Unknown image format.'); diff --git a/packages/pdfkit/src/image/jpeg.js b/packages/pdfkit/src/image/jpeg.js index 8510df32c..b0dcccf96 100644 --- a/packages/pdfkit/src/image/jpeg.js +++ b/packages/pdfkit/src/image/jpeg.js @@ -1,6 +1,14 @@ +import { + readUInt16BE, + readUInt16LE, + readUInt32BE, + readUInt32LE, + toBinaryString, +} from '../binary'; + /** * Parse EXIF orientation from JPEG buffer - * @param {Buffer} data - JPEG image data + * @param {Uint8Array} data - JPEG image data * @returns {number|null} Orientation value (1-8) or null if not found */ const parseExifOrientation = (data) => { @@ -13,7 +21,7 @@ const parseExifOrientation = (data) => { while (pos < data.length && data[pos] !== 0xff) pos++; if (pos >= data.length - 4) return null; - const marker = data.readUInt16BE(pos); + const marker = readUInt16BE(data, pos); pos += 2; // SOS marker - image data starts, stop searching @@ -23,28 +31,28 @@ const parseExifOrientation = (data) => { if ((marker >= 0xffd0 && marker <= 0xffd9) || marker === 0xff01) continue; if (pos + 2 > data.length) return null; - const segmentLength = data.readUInt16BE(pos); + const segmentLength = readUInt16BE(data, pos); // APP1 (EXIF) marker if (marker === 0xffe1 && pos + 8 <= data.length) { - const exifHeader = data.subarray(pos + 2, pos + 8).toString('binary'); + const exifHeader = toBinaryString(data.subarray(pos + 2, pos + 8)); if (exifHeader === 'Exif\x00\x00') { const tiffStart = pos + 8; if (tiffStart + 8 > data.length) return null; // Byte order - const byteOrder = data - .subarray(tiffStart, tiffStart + 2) - .toString('ascii'); + const byteOrder = toBinaryString( + data.subarray(tiffStart, tiffStart + 2), + ); const isLittleEndian = byteOrder === 'II'; if (!isLittleEndian && byteOrder !== 'MM') return null; const read16 = isLittleEndian - ? (o) => data.readUInt16LE(o) - : (o) => data.readUInt16BE(o); + ? (o) => readUInt16LE(data, o) + : (o) => readUInt16BE(data, o); const read32 = isLittleEndian - ? (o) => data.readUInt32LE(o) - : (o) => data.readUInt32BE(o); + ? (o) => readUInt32LE(data, o) + : (o) => readUInt32BE(data, o); // Verify TIFF magic number (42) if (read16(tiffStart + 2) !== 42) return null; @@ -91,7 +99,7 @@ class JPEG { let marker; this.data = data; this.label = label; - if (this.data.readUInt16BE(0) !== 0xffd8) { + if (readUInt16BE(this.data, 0) !== 0xffd8) { throw 'SOI not found in JPEG'; } @@ -104,12 +112,12 @@ class JPEG { while (pos < this.data.length && this.data[pos] !== 0xff) pos++; if (pos >= this.data.length) break; - marker = this.data.readUInt16BE(pos); + marker = readUInt16BE(this.data, pos); pos += 2; if (MARKERS.includes(marker)) { break; } - pos += this.data.readUInt16BE(pos); + pos += readUInt16BE(this.data, pos); } if (!MARKERS.includes(marker)) { @@ -118,10 +126,10 @@ class JPEG { pos += 2; this.bits = this.data[pos++]; - this.height = this.data.readUInt16BE(pos); + this.height = readUInt16BE(this.data, pos); pos += 2; - this.width = this.data.readUInt16BE(pos); + this.width = readUInt16BE(this.data, pos); pos += 2; const channels = this.data[pos++]; diff --git a/packages/pdfkit/src/image/png.js b/packages/pdfkit/src/image/png.js index 9feeff905..49dd080c7 100644 --- a/packages/pdfkit/src/image/png.js +++ b/packages/pdfkit/src/image/png.js @@ -1,4 +1,4 @@ -import zlib from 'zlib'; +import pako from 'pako'; import PNG from 'png-js'; class PNGImage { @@ -48,7 +48,7 @@ class PNGImage { } else { // embed the color palette in the PDF as an object stream const palette = this.document.ref(); - palette.end(Buffer.from(this.image.palette)); + palette.end(new Uint8Array(this.image.palette)); // build the color space array for the image this.obj.data['ColorSpace'] = [ @@ -126,8 +126,8 @@ class PNGImage { let a, p; const colorCount = this.image.colors; const pixelCount = this.width * this.height; - const imgData = Buffer.alloc(pixelCount * colorCount); - const alphaChannel = Buffer.alloc(pixelCount); + const imgData = new Uint8Array(pixelCount * colorCount); + const alphaChannel = new Uint8Array(pixelCount); let i = (p = a = 0); const len = pixels.length; @@ -142,8 +142,8 @@ class PNGImage { i += skipByteCount; } - this.imgData = zlib.deflateSync(imgData); - this.alphaChannel = zlib.deflateSync(alphaChannel); + this.imgData = pako.deflate(imgData); + this.alphaChannel = pako.deflate(alphaChannel); return this.finalize(); }); } @@ -152,7 +152,7 @@ class PNGImage { const transparency = this.image.transparency.indexed; const isInterlaced = this.image.interlaceMethod === 1; return this.image.decodePixels((pixels) => { - const alphaChannel = Buffer.alloc(this.width * this.height); + const alphaChannel = new Uint8Array(this.width * this.height); let i = 0; for (let j = 0, end = pixels.length; j < end; j++) { @@ -161,17 +161,17 @@ class PNGImage { // For interlaced images, re-encode the decoded pixel data if (isInterlaced) { - this.imgData = zlib.deflateSync(Buffer.from(pixels)); + this.imgData = pako.deflate(pixels); } - this.alphaChannel = zlib.deflateSync(alphaChannel); + this.alphaChannel = pako.deflate(alphaChannel); return this.finalize(); }); } decodeData() { this.image.decodePixels((pixels) => { - this.imgData = zlib.deflateSync(pixels); + this.imgData = pako.deflate(pixels); this.finalize(); }); } diff --git a/packages/pdfkit/src/line_wrapper.js b/packages/pdfkit/src/line_wrapper.js index 66aaeb902..4b11d8d40 100644 --- a/packages/pdfkit/src/line_wrapper.js +++ b/packages/pdfkit/src/line_wrapper.js @@ -1,13 +1,12 @@ -import { EventEmitter } from 'events'; import LineBreaker from 'linebreak'; import { PDFNumber } from './utils'; const SOFT_HYPHEN = '\u00AD'; const HYPHEN = '-'; -class LineWrapper extends EventEmitter { +class LineWrapper { constructor(document, options) { - super(); + this._listeners = {}; this.document = document; this.horizontalScaling = options.horizontalScaling || 100; this.indent = ((options.indent || 0) * this.horizontalScaling) / 100; @@ -85,6 +84,29 @@ class LineWrapper extends EventEmitter { }); } + on(event, fn) { + (this._listeners[event] = this._listeners[event] || []).push(fn); + return this; + } + + once(event, fn) { + const wrap = (...args) => { + const arr = this._listeners[event]; + if (arr) { + const idx = arr.indexOf(wrap); + if (idx !== -1) arr.splice(idx, 1); + } + fn(...args); + }; + return this.on(event, wrap); + } + + emit(event, ...args) { + const arr = this._listeners[event]; + if (!arr) return; + for (const fn of arr.slice()) fn(...args); + } + wordWidth(word) { return PDFNumber( this.document.widthOfString(word, this) + diff --git a/packages/pdfkit/src/mini-stream.js b/packages/pdfkit/src/mini-stream.js new file mode 100644 index 000000000..0b19989b4 --- /dev/null +++ b/packages/pdfkit/src/mini-stream.js @@ -0,0 +1,79 @@ +/* +Minimal Readable stream shim — only what PDFDocument needs: +on/once/off/emit, push(chunk|null), pipe(dest). + +Buffers pushes until the first `data` listener is added, then flushes on a +microtask so a caller can attach both `data` and `end` listeners before +flowing starts. After the first flush, pushes emit synchronously. +*/ + +class MiniReadable { + constructor() { + this._listeners = {}; + this._buffered = []; + this._endBuffered = false; + this._flowing = false; + this._scheduled = false; + } + + on(event, fn) { + (this._listeners[event] = this._listeners[event] || []).push(fn); + if (event === 'data' && !this._scheduled) { + this._scheduled = true; + queueMicrotask(() => { + this._flowing = true; + const chunks = this._buffered; + this._buffered = []; + for (const chunk of chunks) this.emit('data', chunk); + if (this._endBuffered) this.emit('end'); + }); + } + return this; + } + + once(event, fn) { + const wrap = (...args) => { + this.off(event, wrap); + fn(...args); + }; + return this.on(event, wrap); + } + + off(event, fn) { + const arr = this._listeners[event]; + if (!arr) return this; + const idx = arr.indexOf(fn); + if (idx !== -1) arr.splice(idx, 1); + return this; + } + + removeListener(event, fn) { + return this.off(event, fn); + } + + emit(event, ...args) { + const arr = this._listeners[event]; + if (!arr) return; + for (const fn of arr.slice()) fn(...args); + } + + push(chunk) { + if (chunk === null) { + if (this._flowing) this.emit('end'); + else this._endBuffered = true; + return false; + } + if (this._flowing) this.emit('data', chunk); + else this._buffered.push(chunk); + return true; + } + + pipe(dest) { + this.on('data', (chunk) => dest.write(chunk)); + this.on('end', () => dest.end && dest.end()); + this.on('error', (err) => dest.emit && dest.emit('error', err)); + return dest; + } +} + +export default MiniReadable; diff --git a/packages/pdfkit/src/mixins/attachments.js b/packages/pdfkit/src/mixins/attachments.js index 063a76e6b..5a2961175 100644 --- a/packages/pdfkit/src/mixins/attachments.js +++ b/packages/pdfkit/src/mixins/attachments.js @@ -1,4 +1,5 @@ import fs from 'fs'; +import { fromBase64 } from '../binary'; import { md5Hex } from '../crypto/md5'; export default { @@ -28,17 +29,17 @@ export default { if (!src) { throw new Error('No src specified'); } - if (Buffer.isBuffer(src)) { + if (src instanceof Uint8Array) { data = src; } else if (src instanceof ArrayBuffer) { - data = Buffer.from(new Uint8Array(src)); + data = new Uint8Array(src); } else { const match = /^data:(.*?);base64,(.*)$/.exec(src); if (match) { if (match[1]) { refBody.Subtype = match[1].replace('/', '#2F'); } - data = Buffer.from(match[2], 'base64'); + data = fromBase64(match[2]); } else { data = fs.readFileSync(src); if (!data) { diff --git a/packages/pdfkit/src/mixins/metadata.js b/packages/pdfkit/src/mixins/metadata.js index 92edb7c20..cc2708a28 100644 --- a/packages/pdfkit/src/mixins/metadata.js +++ b/packages/pdfkit/src/mixins/metadata.js @@ -1,3 +1,4 @@ +import { fromUtf8String } from '../binary'; import PDFMetadata from '../metadata'; export default { @@ -93,7 +94,7 @@ export default { Subtype: 'XML', }); this.metadataRef.compress = false; - this.metadataRef.write(Buffer.from(this.metadata.getXML(), 'utf-8')); + this.metadataRef.write(fromUtf8String(this.metadata.getXML())); this.metadataRef.end(); this._root.data.Metadata = this.metadataRef; } diff --git a/packages/pdfkit/src/object.js b/packages/pdfkit/src/object.js index 24a86e4c7..745123528 100644 --- a/packages/pdfkit/src/object.js +++ b/packages/pdfkit/src/object.js @@ -5,6 +5,12 @@ By Devon Govett import PDFReference from './reference'; import PDFNameTree from './name_tree'; +import { + fromBinaryString, + fromUtf16BEWithBOM, + toBinaryString, + toHex, +} from './binary'; const pad = (str, length) => (Array(length + 1).join('0') + str).slice(-length); @@ -20,22 +26,6 @@ const escapable = { ')': '\\)' }; -// Convert little endian UTF-16 to big endian -const swapBytes = function (buff) { - const l = buff.length; - if (l & 0x01) { - throw new Error('Buffer length must be even'); - } else { - for (let i = 0, end = l - 1; i < end; i += 2) { - const a = buff[i]; - buff[i] = buff[i + 1]; - buff[i + 1] = a; - } - } - - return buff; -}; - class PDFObject { static convert(object, encryptFn = null) { // String literals are converted to the PDF name type @@ -45,7 +35,7 @@ class PDFObject { // String objects are converted to PDF strings (UTF-16) if (object instanceof String) { - let string = object; + const string = object; // Detect if this is a unicode string let isUnicode = false; for (let i = 0, end = string.length; i < end; i++) { @@ -55,31 +45,26 @@ class PDFObject { } } - // If so, encode it as big endian UTF-16 - let stringBuffer; - if (isUnicode) { - stringBuffer = swapBytes(Buffer.from(`\ufeff${string}`, 'utf16le')); - } else { - stringBuffer = Buffer.from(string.valueOf(), 'ascii'); - } + let bytes = isUnicode + ? fromUtf16BEWithBOM(string.valueOf()) + : fromBinaryString(string.valueOf()); - // Encrypt the string when necessary if (encryptFn) { - string = encryptFn(stringBuffer).toString('binary'); - } else { - string = stringBuffer.toString('binary'); + bytes = encryptFn(bytes); } // Escape characters as required by the spec - string = string.replace(escapableRe, (c) => escapable[c]); - - return `(${string})`; + const escaped = toBinaryString(bytes).replace( + escapableRe, + (c) => escapable[c], + ); - // Buffers are converted to PDF hex strings + return `(${escaped})`; } - if (Buffer.isBuffer(object)) { - return `<${object.toString('hex')}>`; + // Byte arrays are converted to PDF hex strings + if (object instanceof Uint8Array) { + return `<${toHex(object)}>`; } if (object instanceof PDFReference || object instanceof PDFNameTree) { @@ -98,7 +83,7 @@ class PDFObject { // Encrypt the string when necessary if (encryptFn) { - string = encryptFn(Buffer.from(string, 'ascii')).toString('binary'); + string = toBinaryString(encryptFn(fromBinaryString(string))); string = string.replace(escapableRe, (c) => escapable[c]); } @@ -106,7 +91,7 @@ class PDFObject { } if (Array.isArray(object)) { - const items = Array.from(object) + const items = object .map((e) => PDFObject.convert(e, encryptFn)) .join(' '); return `[${items}]`; diff --git a/packages/pdfkit/src/reference.js b/packages/pdfkit/src/reference.js index ade58fa4c..358713aa0 100644 --- a/packages/pdfkit/src/reference.js +++ b/packages/pdfkit/src/reference.js @@ -3,15 +3,12 @@ PDFReference - represents a reference to another object in the PDF object heirar By Devon Govett */ -import zlib from 'zlib'; -import stream from 'stream'; +import pako from 'pako'; +import { concat, fromBinaryString } from './binary'; import PDFObject from './object'; -class PDFReference extends stream.Writable { +class PDFReference { constructor(document, id, data) { - super({ decodeStrings: false }); - - this.finalize = this.finalize.bind(this); this.document = document; this.id = id; if (data == null) { @@ -20,27 +17,14 @@ class PDFReference extends stream.Writable { this.data = data; this.gen = 0; - this.deflate = null; this.compress = this.document.compress && !this.data.Filter; this.uncompressedLength = 0; this.chunks = []; } - initDeflate() { - this.data.Filter = 'FlateDecode'; - - this.deflate = zlib.createDeflate(); - this.deflate.on('data', (chunk) => { - this.chunks.push(chunk); - return (this.data.Length += chunk.length); - }); - - return this.deflate.on('end', this.finalize); - } - - _write(chunk, encoding, callback) { + write(chunk) { if (!(chunk instanceof Uint8Array)) { - chunk = Buffer.from(chunk + '\n', 'binary'); + chunk = fromBinaryString(chunk + '\n'); } this.uncompressedLength += chunk.length; @@ -48,26 +32,12 @@ class PDFReference extends stream.Writable { this.data.Length = 0; } - if (this.compress) { - if (!this.deflate) { - this.initDeflate(); - } - this.deflate.write(chunk); - } else { - this.chunks.push(chunk); - this.data.Length += chunk.length; - } - - return callback(); + this.chunks.push(chunk); + this.data.Length += chunk.length; } - end() { - super.end(...arguments); - - if (this.deflate) { - return this.deflate.end(); - } - + end(chunk) { + if (chunk != null) this.write(chunk); return this.finalize(); } @@ -79,7 +49,12 @@ class PDFReference extends stream.Writable { : null; if (this.chunks.length) { - let buffer = Buffer.concat(this.chunks); + let buffer = concat(this.chunks); + + if (this.compress) { + this.data.Filter = 'FlateDecode'; + buffer = pako.deflate(buffer); + } if (encryptFn) { buffer = encryptFn(buffer); diff --git a/packages/pdfkit/src/security.js b/packages/pdfkit/src/security.js index d6639a424..66c51554b 100644 --- a/packages/pdfkit/src/security.js +++ b/packages/pdfkit/src/security.js @@ -33,7 +33,7 @@ class PDFSecurity { infoStr += `${key}: ${info[key].valueOf()}\n`; } - return Buffer.from(md5Hash(infoStr)); + return md5Hash(infoStr); } static generateRandomWordArray(bytes) { @@ -157,8 +157,8 @@ class PDFSecurity { encDict.StrF = 'StdCF'; } encDict.R = r; - encDict.O = Buffer.from(ownerPasswordEntry); - encDict.U = Buffer.from(userPasswordEntry); + encDict.O = ownerPasswordEntry; + encDict.U = userPasswordEntry; encDict.P = permissions; } @@ -214,12 +214,12 @@ class PDFSecurity { encDict.StmF = 'StdCF'; encDict.StrF = 'StdCF'; encDict.R = 5; - encDict.O = Buffer.from(ownerPasswordEntry); - encDict.OE = Buffer.from(ownerEncryptionKeyEntry); - encDict.U = Buffer.from(userPasswordEntry); - encDict.UE = Buffer.from(userEncryptionKeyEntry); + encDict.O = ownerPasswordEntry; + encDict.OE = ownerEncryptionKeyEntry; + encDict.U = userPasswordEntry; + encDict.UE = userEncryptionKeyEntry; encDict.P = permissions; - encDict.Perms = Buffer.from(permsEntry); + encDict.Perms = permsEntry; } getEncryptFn(obj, gen) { @@ -240,7 +240,7 @@ class PDFSecurity { let key = md5Hash(digest); const keyLen = Math.min(16, this.keyBits / 8 + 5); key = key.slice(0, keyLen); - return (buffer) => Buffer.from(rc4(new Uint8Array(buffer), key)); + return (buffer) => rc4(buffer, key); } let key; @@ -255,8 +255,8 @@ class PDFSecurity { const iv = PDFSecurity.generateRandomWordArray(16); return (buffer) => { - const encrypted = aesCbcEncrypt(new Uint8Array(buffer), key, iv, true); - return Buffer.from(concatBytes(iv, encrypted)); + const encrypted = aesCbcEncrypt(buffer, key, iv, true); + return concatBytes(iv, encrypted); }; } diff --git a/yarn.lock b/yarn.lock index a8b2cd153..e7f63fb10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -752,14 +752,8 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-react-jsx-development@^7.18.6": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz#ed3e7dadde046cce761a8e3cf003a13d1a7972d9" - integrity sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-react-jsx-self@^7.23.3": +"@babel/plugin-transform-react-jsx-development@^7.18.6", "@babel/plugin-transform-react-jsx-self@^7.23.3": + name "@babel/plugin-transform-react-jsx-development" version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz#ed3e7dadde046cce761a8e3cf003a13d1a7972d9" integrity sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ== @@ -8473,6 +8467,11 @@ pako@^0.2.5: resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" integrity sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU= +pako@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -10128,16 +10127,7 @@ string-argv@0.3.1: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -10264,14 +10254,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -11021,15 +11004,6 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" -vite-compatible-readable-stream@^3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/vite-compatible-readable-stream/-/vite-compatible-readable-stream-3.6.1.tgz#27267aebbdc9893c0ddf65a421279cbb1e31d8cd" - integrity sha512-t20zYkrSf868+j/p31cRIGN28Phrjm3nRSLR2fyc2tiWi4cZGVdv68yNlwnIINTkMTmPoMiSlc0OadaO7DXZaQ== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - vite-node@1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-1.6.1.tgz#fff3ef309296ea03ceaa6ca4bb660922f5416c57" @@ -11317,7 +11291,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -11335,15 +11309,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"