single-file-core 1.5.106 → 1.5.107

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "single-file-core",
3
- "version": "1.5.106",
3
+ "version": "1.5.107",
4
4
  "description": "SingleFile Core",
5
5
  "author": "Gildas Lormeau",
6
6
  "license": "AGPL-3.0-or-later",
@@ -89,6 +89,9 @@ async function extract(content, { password, prompt = () => { }, zipOptions = { u
89
89
  zipReader = new zip.ZipReader(reader);
90
90
  entries = await zipReader.getEntries();
91
91
  }
92
+ // page.pdf data lies in the HTML head, outside the zip region recovered in
93
+ // universal mode, and is never referenced by the displayed page
94
+ entries = entries.filter(entry => entry.filename != "page.pdf");
92
95
  if (aliases) {
93
96
  const allEntries = entries;
94
97
  entries = entries.map(entry => {
@@ -84,6 +84,7 @@ const CRC32_TABLE = new Uint32Array(256).map((_, indexTable) => {
84
84
  return crc;
85
85
  });
86
86
  const PNG_IEND_LENGTH = 12;
87
+ const PNG_CHUNK_CRC_LENGTH = 4;
87
88
  const PNG_SIGNATURE_LENGTH = 8;
88
89
  const PNG_IHDR_LENGTH = 25;
89
90
  const PDF_ENTRY_FILENAME = "page.pdf";
@@ -135,9 +136,9 @@ async function createArchive(pageData, options, script, writeEntries, lastModDat
135
136
  // the htmlArray starts after the 4-byte length and the 8-byte type of the tEXt chunk
136
137
  pdfEntry.offset += zipDataWriter.offset + 12;
137
138
  }
138
- const hmtlData = new Uint8Array([...getLength(htmlArray.length + 4), ...[0x74, 0x45, 0x58, 0x74, 0x50, 0x4e, 0x47, 0], ...htmlArray]);
139
- await writeData(zipDataWriter.writable, hmtlData);
140
- await writeData(zipDataWriter.writable, getCRC32(hmtlData, 4));
139
+ const htmlData = new Uint8Array([...getLength(htmlArray.length + 4), ...[0x74, 0x45, 0x58, 0x74, 0x50, 0x4e, 0x47, 0], ...htmlArray]);
140
+ await writeData(zipDataWriter.writable, htmlData);
141
+ await writeData(zipDataWriter.writable, getCRC32(htmlData, 4));
141
142
  } else if (options.embeddedPdf) {
142
143
  const data = new Uint8Array([...getLength(options.embeddedPdf.length + 4), ...[0x74, 0x45, 0x58, 0x74, 0x50, 0x44, 0x46, 0], ...new Uint8Array(options.embeddedPdf)]);
143
144
  await writeData(zipDataWriter.writable, data);
@@ -230,7 +231,10 @@ async function createArchive(pageData, options, script, writeEntries, lastModDat
230
231
  payload[2] = lfCodes.length;
231
232
  lfCodes.forEach((lfCode, indexLFCode) => payload[3 + (indexLFCode >> 4)] |= lfCode << ((indexLFCode & 15) * 2));
232
233
  extraData = "<sfz-extra-data>" + base64Encode(deflateRaw(new Uint8Array(payload.buffer))) + "</sfz-extra-data>";
233
- if (options.preventAppendedData || extraData.length > 65535 - endTags.length - (options.embeddedImage ? PNG_IEND_LENGTH : 0)) {
234
+ // the bytes appended after the EOCD record (wrapper end tag, extra data, end tags
235
+ // and, with an embedded image, the tEXt CRC and IEND chunk) must fit the 65535-byte
236
+ // window readers scan backward to find the EOCD record
237
+ if (options.preventAppendedData || extraData.length > 65535 - pageContent.length - endTags.length - (options.embeddedImage ? PNG_IEND_LENGTH + PNG_CHUNK_CRC_LENGTH : 0)) {
234
238
  if (!options.extraDataSize) {
235
239
  options.extraDataSize = Math.floor(extraData.length * 1.001);
236
240
  return createArchive(pageData, options, script, writeEntries, lastModDate);
@@ -627,18 +631,24 @@ async function getContent() {
627
631
  };
628
632
  xhr.send();
629
633
  xhr.onreadystatechange = () => {
630
- if (xhr.readyState === 2 && xhr.status === 200 && !aborted) {
631
- aborted = true;
632
- const httpRangeSupport = xhr.getResponseHeader("Accept-Ranges") === "bytes";
633
- xhr.abort();
634
- displayMessage("sfz-wait-message", 2);
635
- if (httpRangeSupport) {
636
- resolve(new zip.HttpRangeReader(location.href, {
637
- useXHR: true,
638
- combineSizeEocd: true
639
- }));
634
+ if (xhr.readyState === 2 && !aborted) {
635
+ if (xhr.status === 200) {
636
+ aborted = true;
637
+ const httpRangeSupport = xhr.getResponseHeader("Accept-Ranges") === "bytes";
638
+ xhr.abort();
639
+ displayMessage("sfz-wait-message", 2);
640
+ if (httpRangeSupport) {
641
+ resolve(new zip.HttpRangeReader(location.href, {
642
+ useXHR: true,
643
+ combineSizeEocd: true
644
+ }));
645
+ } else {
646
+ getPageData();
647
+ }
640
648
  } else {
641
- getPageData();
649
+ // an HTTP error status fires no error event; fall back like a network failure
650
+ xhr.abort();
651
+ extractDataFromDocument();
642
652
  }
643
653
  }
644
654
  };
@@ -728,7 +738,7 @@ async function getContent() {
728
738
  offset++;
729
739
  }
730
740
  }
731
- throw new Error("Extra zip data data not found");
741
+ throw new Error("Extra zip data not found");
732
742
  }
733
743
 
734
744
  function base64Decode(b64) {
package/vendor/zip/zip.js CHANGED
@@ -6647,6 +6647,13 @@ async function addFile(zipWriter, name, reader, options) {
6647
6647
  const { comment } = metadataInfo;
6648
6648
  const extraField = options[PROPERTY_NAME_EXTRA_FIELD];
6649
6649
  zipWriter.fileEntries.set(name, UNDEFINED_VALUE);
6650
+ const previousFileEntry = zipWriter.lastFileEntry;
6651
+ const pendingFileEntry = {};
6652
+ let releaseLockFileEntry;
6653
+ if (metadataInfo.resolvedOptions.keepOrder) {
6654
+ pendingFileEntry.lockFileEntry = new Promise(resolve => releaseLockFileEntry = resolve);
6655
+ }
6656
+ zipWriter.lastFileEntry = pendingFileEntry;
6650
6657
  let fileEntry;
6651
6658
  try {
6652
6659
  const { resolvedOptions } = metadataInfo;
@@ -6668,10 +6675,21 @@ async function addFile(zipWriter, name, reader, options) {
6668
6675
  const headerInfo = getHeaderInfo(options);
6669
6676
  const dataDescriptorInfo = getDataDescriptorInfo(options);
6670
6677
  const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
6671
- fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
6678
+ fileEntry = await getFileEntry(zipWriter, name, reader, {
6679
+ headerInfo,
6680
+ dataDescriptorInfo,
6681
+ metadataSize,
6682
+ fileEntry: pendingFileEntry,
6683
+ previousFileEntry,
6684
+ releaseLockFileEntry
6685
+ }, options);
6672
6686
  } catch (error) {
6673
6687
  zipWriter.fileEntries.delete(name);
6674
6688
  throw error;
6689
+ } finally {
6690
+ if (releaseLockFileEntry) {
6691
+ releaseLockFileEntry(previousFileEntry && previousFileEntry.lockFileEntry);
6692
+ }
6675
6693
  }
6676
6694
  Object.assign(fileEntry, {
6677
6695
  name,
@@ -7057,27 +7075,23 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
7057
7075
  signal
7058
7076
  } = options;
7059
7077
  const {
7060
- headerInfo
7078
+ headerInfo,
7079
+ fileEntry: pendingFileEntry,
7080
+ previousFileEntry,
7081
+ releaseLockFileEntry
7061
7082
  } = entryInfo;
7062
7083
  const usdz = zipWriter.options[OPTION_USDZ];
7063
- const previousFileEntry = zipWriter.lastFileEntry;
7064
- let fileEntry = {};
7084
+ let fileEntry = pendingFileEntry;
7065
7085
  let bufferedWrite;
7066
7086
  let releaseLockWriter;
7067
- let releaseLockCurrentFileEntry;
7068
7087
  let writingBufferedEntryData;
7069
7088
  let writingEntryData;
7070
7089
  let writerSizeBeforeEntry;
7071
7090
  let flushedBufferedSize = 0;
7072
7091
  let fileWriter;
7092
+ const lockPreviousFileEntry = keepOrder && previousFileEntry ? previousFileEntry.lockFileEntry : UNDEFINED_VALUE;
7073
7093
  fileEntries.set(name, fileEntry);
7074
- zipWriter.lastFileEntry = fileEntry;
7075
7094
  try {
7076
- let lockPreviousFileEntry;
7077
- if (keepOrder) {
7078
- lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
7079
- requestLockCurrentFileEntry();
7080
- }
7081
7095
  if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || (!dataDescriptor && !emptyEntry)) {
7082
7096
  bufferedWrite = true;
7083
7097
  zipWriter.bufferedWrites++;
@@ -7090,6 +7104,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
7090
7104
  await initStream(writer);
7091
7105
  } else {
7092
7106
  fileWriter = writer;
7107
+ await lockPreviousFileEntry;
7093
7108
  await requestLockWriter();
7094
7109
  }
7095
7110
  await initStream(fileWriter);
@@ -7102,7 +7117,6 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
7102
7117
  }
7103
7118
  const { localHeaderArray } = headerInfo;
7104
7119
  if (!bufferedWrite) {
7105
- await lockPreviousFileEntry;
7106
7120
  await skipDiskIfNeeded();
7107
7121
  }
7108
7122
  const diskNumberStart = getDiskNumber(writer);
@@ -7167,8 +7181,8 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
7167
7181
  if (bufferedWrite) {
7168
7182
  zipWriter.bufferedWrites--;
7169
7183
  }
7170
- if (releaseLockCurrentFileEntry) {
7171
- releaseLockCurrentFileEntry();
7184
+ if (releaseLockFileEntry) {
7185
+ releaseLockFileEntry(lockPreviousFileEntry);
7172
7186
  }
7173
7187
  if (releaseLockWriter) {
7174
7188
  releaseLockWriter();
@@ -7182,10 +7196,6 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
7182
7196
  }
7183
7197
  }
7184
7198
 
7185
- function requestLockCurrentFileEntry() {
7186
- fileEntry.lockFileEntry = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
7187
- }
7188
-
7189
7199
  async function requestLockWriter() {
7190
7200
  zipWriter.writerLocked = true;
7191
7201
  const { lockWriter } = zipWriter;
@@ -8505,7 +8515,7 @@ function formatSupported(StreamClass, format) {
8505
8515
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8506
8516
  */
8507
8517
 
8508
- const VERSION = "2.8.60";
8518
+ const VERSION = "2.8.61";
8509
8519
 
8510
8520
  /*
8511
8521
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -7,7 +7,7 @@
7
7
  "name": "single-file-core-zip-build",
8
8
  "devDependencies": {
9
9
  "@rollup/plugin-terser": "1.0.0",
10
- "@zip.js/zip.js": "2.8.60",
10
+ "@zip.js/zip.js": "2.8.61",
11
11
  "rollup": "4.62.4",
12
12
  "terser": "5.50.0"
13
13
  }
@@ -502,9 +502,9 @@
502
502
  "license": "MIT"
503
503
  },
504
504
  "node_modules/@zip.js/zip.js": {
505
- "version": "2.8.60",
506
- "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.60.tgz",
507
- "integrity": "sha512-pULv0waMlnKAUUxrsuAOa0ADONGRuhdHORtuXVgClNlScDB5YjImCV8DZrE1SicaROyE6MwGkH8CLJ+o4Nx07g==",
505
+ "version": "2.8.61",
506
+ "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.61.tgz",
507
+ "integrity": "sha512-F9RnQJXgvCSdAJfMtSrH5Uh/LcLg8fZlg5ARC4u5N4w9v/DG27cN3C/ngUrY1JdJGX2LRv5DDViXeZJgbcppWA==",
508
508
  "dev": true,
509
509
  "license": "BSD-3-Clause",
510
510
  "engines": {
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "devDependencies": {
10
10
  "@rollup/plugin-terser": "1.0.0",
11
- "@zip.js/zip.js": "2.8.60",
11
+ "@zip.js/zip.js": "2.8.61",
12
12
  "rollup": "4.62.4",
13
13
  "terser": "5.50.0"
14
14
  }