pdfmake 0.3.5 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.6 - 2026-03-10
4
+
5
+ - Added `setUrlAccessPolicy()` for defining a custom access policy for external URLs before download
6
+ (addresses a potential server vulnerability **CVE-2026-26801**)
7
+
8
+ Example:
9
+ ```js
10
+ pdfmake.setUrlAccessPolicy((url) => {
11
+ // check allowed domain
12
+ return url.startsWith("https://example.com/");
13
+ });
14
+ ```
15
+ For details see [documentation](https://pdfmake.github.io/docs/0.3/getting-started/server-side/methods/#url-access-policy)
16
+ - Added validation for image height and width values
17
+
3
18
  ## 0.3.5 - 2026-02-22
4
19
 
5
20
  - Added `snakingColumns` property for columns to enable newspaper-like column flow
package/build/pdfmake.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! pdfmake v0.3.5, @license MIT, @link http://pdfmake.org */
1
+ /*! pdfmake v0.3.6, @license MIT, @link http://pdfmake.org */
2
2
  (function webpackUniversalModuleDefinition(root, factory) {
3
3
  if(typeof exports === 'object' && typeof module === 'object')
4
4
  module.exports = factory();
@@ -23,7 +23,7 @@ __webpack_require__.d(__webpack_exports__, {
23
23
  });
24
24
 
25
25
  // EXTERNAL MODULE: ./node_modules/pdfkit/js/pdfkit.es.js
26
- var pdfkit_es = __webpack_require__(3801);
26
+ var pdfkit_es = __webpack_require__(1254);
27
27
  ;// ./src/PDFDocument.js
28
28
  /* provided dependency */ var Buffer = __webpack_require__(783)["Buffer"];
29
29
 
@@ -3650,9 +3650,11 @@ class DocMeasure {
3650
3650
  node._width = node._minWidth = node._maxWidth = node.cover.width;
3651
3651
  node._height = node._minHeight = node._maxHeight = node.cover.height;
3652
3652
  } else {
3653
+ let nodeWidth = isNumber(node.width) ? node.width : undefined;
3654
+ let nodeHeight = isNumber(node.height) ? node.height : undefined;
3653
3655
  let ratio = dimensions.width / dimensions.height;
3654
- node._width = node._minWidth = node._maxWidth = node.width || (node.height ? node.height * ratio : dimensions.width);
3655
- node._height = node.height || (node.width ? node.width / ratio : dimensions.height);
3656
+ node._width = node._minWidth = node._maxWidth = nodeWidth || (nodeHeight ? nodeHeight * ratio : dimensions.width);
3657
+ node._height = nodeHeight || (nodeWidth ? nodeWidth / ratio : dimensions.height);
3656
3658
  if (isNumber(node.maxWidth) && node.maxWidth < node._width) {
3657
3659
  node._width = node._minWidth = node._maxWidth = node.maxWidth;
3658
3660
  node._height = node._width * dimensions.height / dimensions.width;
@@ -8183,22 +8185,6 @@ class Renderer {
8183
8185
 
8184
8186
 
8185
8187
 
8186
-
8187
- /**
8188
- * Printer which turns document definition into a pdf
8189
- *
8190
- * @example
8191
- * var fontDescriptors = {
8192
- * Roboto: {
8193
- * normal: 'fonts/Roboto-Regular.ttf',
8194
- * bold: 'fonts/Roboto-Medium.ttf',
8195
- * italics: 'fonts/Roboto-Italic.ttf',
8196
- * bolditalics: 'fonts/Roboto-MediumItalic.ttf'
8197
- * }
8198
- * };
8199
- *
8200
- * var printer = new PdfPrinter(fontDescriptors);
8201
- */
8202
8188
  class PdfPrinter {
8203
8189
  /**
8204
8190
  * @param {object} fontDescriptors font definition dictionary
@@ -8206,12 +8192,6 @@ class PdfPrinter {
8206
8192
  * @param {object} urlResolver
8207
8193
  */
8208
8194
  constructor(fontDescriptors, virtualfs, urlResolver) {
8209
- if (virtualfs === void 0) {
8210
- virtualfs = null;
8211
- }
8212
- if (urlResolver === void 0) {
8213
- urlResolver = null;
8214
- }
8215
8195
  this.fontDescriptors = fontDescriptors;
8216
8196
  this.virtualfs = virtualfs;
8217
8197
  this.urlResolver = urlResolver;
@@ -8308,9 +8288,6 @@ class PdfPrinter {
8308
8288
  headers: {}
8309
8289
  };
8310
8290
  };
8311
- if (this.urlResolver === null) {
8312
- return;
8313
- }
8314
8291
  for (let font in this.fontDescriptors) {
8315
8292
  if (this.fontDescriptors.hasOwnProperty(font)) {
8316
8293
  if (this.fontDescriptors[font].normal) {
@@ -8470,7 +8447,68 @@ function calculatePageHeight(page, margins) {
8470
8447
  /* harmony default export */ const Printer = (PdfPrinter);
8471
8448
  // EXTERNAL MODULE: ./src/virtual-fs.js
8472
8449
  var virtual_fs = __webpack_require__(6811);
8450
+ ;// ./src/URLResolver.js
8451
+ async function fetchUrl(url, headers) {
8452
+ if (headers === void 0) {
8453
+ headers = {};
8454
+ }
8455
+ try {
8456
+ const response = await fetch(url, {
8457
+ headers
8458
+ });
8459
+ if (!response.ok) {
8460
+ throw new Error(`Failed to fetch (status code: ${response.status}, url: "${url}")`);
8461
+ }
8462
+ return await response.arrayBuffer();
8463
+ } catch (error) {
8464
+ throw new Error(`Network request failed (url: "${url}", error: ${error.message})`, {
8465
+ cause: error
8466
+ });
8467
+ }
8468
+ }
8469
+ class URLResolver {
8470
+ constructor(fs) {
8471
+ this.fs = fs;
8472
+ this.resolving = {};
8473
+ this.urlAccessPolicy = undefined;
8474
+ }
8475
+
8476
+ /**
8477
+ * @param {(url: string) => boolean} callback
8478
+ */
8479
+ setUrlAccessPolicy(callback) {
8480
+ this.urlAccessPolicy = callback;
8481
+ }
8482
+ resolve(url, headers) {
8483
+ if (headers === void 0) {
8484
+ headers = {};
8485
+ }
8486
+ const resolveUrlInternal = async () => {
8487
+ if (url.toLowerCase().startsWith('https://') || url.toLowerCase().startsWith('http://')) {
8488
+ if (this.fs.existsSync(url)) {
8489
+ return; // url was downloaded earlier
8490
+ }
8491
+ if (typeof this.urlAccessPolicy !== 'undefined' && this.urlAccessPolicy(url) !== true) {
8492
+ throw new Error(`Access to URL denied by resource access policy: ${url}`);
8493
+ }
8494
+ const buffer = await fetchUrl(url, headers);
8495
+ this.fs.writeFileSync(url, buffer);
8496
+ }
8497
+ // else cannot be resolved
8498
+ };
8499
+ if (!this.resolving[url]) {
8500
+ this.resolving[url] = resolveUrlInternal();
8501
+ }
8502
+ return this.resolving[url];
8503
+ }
8504
+ resolved() {
8505
+ return Promise.all(Object.values(this.resolving));
8506
+ }
8507
+ }
8508
+ /* harmony default export */ const src_URLResolver = (URLResolver);
8473
8509
  ;// ./src/base.js
8510
+ /* provided dependency */ var process = __webpack_require__(9964);
8511
+
8474
8512
 
8475
8513
 
8476
8514
 
@@ -8478,7 +8516,7 @@ var virtual_fs = __webpack_require__(6811);
8478
8516
  class pdfmake {
8479
8517
  constructor() {
8480
8518
  this.virtualfs = virtual_fs["default"];
8481
- this.urlResolver = null;
8519
+ this.urlAccessPolicy = undefined;
8482
8520
  }
8483
8521
 
8484
8522
  /**
@@ -8498,10 +8536,26 @@ class pdfmake {
8498
8536
  }
8499
8537
  options.progressCallback = this.progressCallback;
8500
8538
  options.tableLayouts = this.tableLayouts;
8501
- let printer = new Printer(this.fonts, this.virtualfs, this.urlResolver());
8539
+ const isServer = typeof process !== 'undefined' && process?.versions?.node;
8540
+ if (typeof this.urlAccessPolicy === 'undefined' && isServer) {
8541
+ console.warn('No URL access policy defined. Consider using setUrlAccessPolicy() to restrict external resource downloads.');
8542
+ }
8543
+ let urlResolver = new src_URLResolver(this.virtualfs);
8544
+ urlResolver.setUrlAccessPolicy(this.urlAccessPolicy);
8545
+ let printer = new Printer(this.fonts, this.virtualfs, urlResolver);
8502
8546
  const pdfDocumentPromise = printer.createPdfKitDocument(docDefinition, options);
8503
8547
  return this._transformToDocument(pdfDocumentPromise);
8504
8548
  }
8549
+
8550
+ /**
8551
+ * @param {(url: string) => boolean} callback
8552
+ */
8553
+ setUrlAccessPolicy(callback) {
8554
+ if (callback !== undefined && typeof callback !== 'function') {
8555
+ throw new Error("Parameter 'callback' has an invalid type. Function or undefined expected.");
8556
+ }
8557
+ this.urlAccessPolicy = callback;
8558
+ }
8505
8559
  setProgressCallback(callback) {
8506
8560
  this.progressCallback = callback;
8507
8561
  }
@@ -8591,7 +8645,7 @@ class OutputDocument {
8591
8645
  }
8592
8646
  /* harmony default export */ const src_OutputDocument = (OutputDocument);
8593
8647
  // EXTERNAL MODULE: ./node_modules/file-saver/dist/FileSaver.min.js
8594
- var FileSaver_min = __webpack_require__(656);
8648
+ var FileSaver_min = __webpack_require__(8667);
8595
8649
  ;// ./src/browser-extensions/OutputDocumentBrowser.js
8596
8650
 
8597
8651
 
@@ -8680,54 +8734,6 @@ class OutputDocumentBrowser extends src_OutputDocument {
8680
8734
  }
8681
8735
  }
8682
8736
  /* harmony default export */ const browser_extensions_OutputDocumentBrowser = (OutputDocumentBrowser);
8683
- ;// ./src/URLResolver.js
8684
- async function fetchUrl(url, headers) {
8685
- if (headers === void 0) {
8686
- headers = {};
8687
- }
8688
- try {
8689
- const response = await fetch(url, {
8690
- headers
8691
- });
8692
- if (!response.ok) {
8693
- throw new Error(`Failed to fetch (status code: ${response.status}, url: "${url}")`);
8694
- }
8695
- return await response.arrayBuffer();
8696
- } catch (error) {
8697
- throw new Error(`Network request failed (url: "${url}", error: ${error.message})`, {
8698
- cause: error
8699
- });
8700
- }
8701
- }
8702
- class URLResolver {
8703
- constructor(fs) {
8704
- this.fs = fs;
8705
- this.resolving = {};
8706
- }
8707
- resolve(url, headers) {
8708
- if (headers === void 0) {
8709
- headers = {};
8710
- }
8711
- const resolveUrlInternal = async () => {
8712
- if (url.toLowerCase().startsWith('https://') || url.toLowerCase().startsWith('http://')) {
8713
- if (this.fs.existsSync(url)) {
8714
- return; // url was downloaded earlier
8715
- }
8716
- const buffer = await fetchUrl(url, headers);
8717
- this.fs.writeFileSync(url, buffer);
8718
- }
8719
- // else cannot be resolved
8720
- };
8721
- if (!this.resolving[url]) {
8722
- this.resolving[url] = resolveUrlInternal();
8723
- }
8724
- return this.resolving[url];
8725
- }
8726
- resolved() {
8727
- return Promise.all(Object.values(this.resolving));
8728
- }
8729
- }
8730
- /* harmony default export */ const src_URLResolver = (URLResolver);
8731
8737
  // EXTERNAL MODULE: ./src/browser-extensions/virtual-fs-cjs.js
8732
8738
  var virtual_fs_cjs = __webpack_require__(2416);
8733
8739
  var virtual_fs_cjs_default = /*#__PURE__*/__webpack_require__.n(virtual_fs_cjs);
@@ -8740,7 +8746,6 @@ var configurator_default = /*#__PURE__*/__webpack_require__.n(configurator);
8740
8746
 
8741
8747
 
8742
8748
 
8743
-
8744
8749
  // core-js: Polyfills will be used only if natives completely unavailable.
8745
8750
  configurator_default()({
8746
8751
  useNative: ['Promise']
@@ -8756,7 +8761,6 @@ let defaultClientFonts = {
8756
8761
  class browser_extensions_pdfmake extends base {
8757
8762
  constructor() {
8758
8763
  super();
8759
- this.urlResolver = () => new src_URLResolver(this.virtualfs);
8760
8764
  this.fonts = defaultClientFonts;
8761
8765
  }
8762
8766
  addFontContainer(fontContainer) {
@@ -22031,7 +22035,7 @@ module.exports = {
22031
22035
 
22032
22036
  /***/ },
22033
22037
 
22034
- /***/ 3801
22038
+ /***/ 1254
22035
22039
  (__unused_webpack_module, exports, __webpack_require__) {
22036
22040
 
22037
22041
  "use strict";
@@ -42631,6 +42635,9 @@ module.exports = function regexTester(regex) {
42631
42635
  parser.opt = opt || {}
42632
42636
  parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags
42633
42637
  parser.looseCase = parser.opt.lowercase ? 'toLowerCase' : 'toUpperCase'
42638
+ parser.opt.maxEntityCount = parser.opt.maxEntityCount || 512
42639
+ parser.opt.maxEntityDepth = parser.opt.maxEntityDepth || 4
42640
+ parser.entityCount = parser.entityDepth = 0
42634
42641
  parser.tags = []
42635
42642
  parser.closed = parser.closedRoot = parser.sawRoot = false
42636
42643
  parser.tag = parser.error = null
@@ -44176,9 +44183,24 @@ module.exports = function regexTester(regex) {
44176
44183
  parser.opt.unparsedEntities &&
44177
44184
  !Object.values(sax.XML_ENTITIES).includes(parsedEntity)
44178
44185
  ) {
44186
+ if ((parser.entityCount += 1) > parser.opt.maxEntityCount) {
44187
+ error(
44188
+ parser,
44189
+ 'Parsed entity count exceeds max entity count'
44190
+ )
44191
+ }
44192
+
44193
+ if ((parser.entityDepth += 1) > parser.opt.maxEntityDepth) {
44194
+ error(
44195
+ parser,
44196
+ 'Parsed entity depth exceeds max entity depth'
44197
+ )
44198
+ }
44199
+
44179
44200
  parser.entity = ''
44180
44201
  parser.state = returnState
44181
44202
  parser.write(parsedEntity)
44203
+ parser.entityDepth -= 1
44182
44204
  } else {
44183
44205
  parser[buffer] += parsedEntity
44184
44206
  parser.entity = ''
@@ -49142,7 +49164,7 @@ module.exports = function whichTypedArray(value) {
49142
49164
 
49143
49165
  /***/ },
49144
49166
 
49145
- /***/ 656
49167
+ /***/ 8667
49146
49168
  (module, exports, __webpack_require__) {
49147
49169
 
49148
49170
  var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(a,b){if(true)!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (b),