Compare commits

..

No commits in common. "702d60aa18412d07940798fe02d36bdafea96cdb" and "e86e9d9465404c6816939dac65ede0e63321ecb9" have entirely different histories.

18 changed files with 224 additions and 384 deletions

View File

@ -18,13 +18,13 @@ This tutorial shows how PDF.js can be used as a library in a web browser.
The object structure of PDF.js loosely follows the structure of an actual PDF. At the top level there is a document object. From the document, more information and individual pages can be fetched. To get the document:
```js
pdfjsLib.getDocument({ url: "helloworld.pdf" })
pdfjsLib.getDocument('helloworld.pdf')
```
Remember though that PDF.js uses promises, and the above will return a `PDFDocumentLoadingTask` instance that has a `promise` property which is resolved with the document object.
```js
var loadingTask = pdfjsLib.getDocument({ url: "helloworld.pdf" });
var loadingTask = pdfjsLib.getDocument('helloworld.pdf');
loadingTask.promise.then(function(pdf) {
// you can now use *pdf* here
});
@ -48,8 +48,8 @@ var viewport = page.getViewport({ scale: scale, });
// Support HiDPI-screens.
var outputScale = window.devicePixelRatio || 1;
var canvas = document.getElementById("the-canvas");
var context = canvas.getContext("2d");
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.width = Math.floor(viewport.width * outputScale);
canvas.height = Math.floor(viewport.height * outputScale);

View File

@ -26,7 +26,7 @@
//
// Asynchronous download PDF
//
const loadingTask = pdfjsLib.getDocument({ url });
const loadingTask = pdfjsLib.getDocument(url);
const pdf = await loadingTask.promise;
//
// Fetch the first page

View File

@ -123,7 +123,7 @@
/**
* Asynchronously downloads PDF.
*/
var loadingTask = pdfjsLib.getDocument({ url });
var loadingTask = pdfjsLib.getDocument(url);
pdfDoc = await loadingTask.promise;
document.getElementById("page_count").textContent = pdfDoc.numPages;

View File

@ -14,7 +14,7 @@ const pdfPath =
// Will be using promises to load document, pages and misc data instead of
// callback.
const loadingTask = getDocument({ url: pdfPath });
const loadingTask = getDocument(pdfPath);
loadingTask.promise
.then(function (doc) {
const numPages = doc.numPages;

37
package-lock.json generated
View File

@ -1003,9 +1003,9 @@
}
},
"node_modules/@babel/plugin-transform-modules-systemjs": {
"version": "7.29.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz",
"integrity": "sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==",
"version": "7.29.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz",
"integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -6009,9 +6009,9 @@
"license": "MIT"
},
"node_modules/fast-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
"integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
"integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
"dev": true,
"funding": [
{
@ -6026,9 +6026,9 @@
"license": "BSD-3-Clause"
},
"node_modules/fast-xml-builder": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz",
"integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==",
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz",
"integrity": "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==",
"dev": true,
"funding": [
{
@ -6038,8 +6038,7 @@
],
"license": "MIT",
"dependencies": {
"path-expression-matcher": "^1.5.0",
"xml-naming": "^0.1.0"
"path-expression-matcher": "^1.1.3"
}
},
"node_modules/fast-xml-parser": {
@ -12688,22 +12687,6 @@
}
}
},
"node_modules/xml-naming": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz",
"integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
}
],
"license": "MIT",
"engines": {
"node": ">=16.0.0"
}
},
"node_modules/xmlcreate": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",

View File

@ -982,8 +982,7 @@ class PartialEvaluator {
patternDict,
operatorList,
task,
localTilingPatternCache,
seenRefs
localTilingPatternCache
) {
// Create an IR of the pattern code.
const tilingOpList = new CheckedOperatorList();
@ -999,7 +998,6 @@ class PartialEvaluator {
task,
resources: patternResources,
operatorList: tilingOpList,
prevRefs: seenRefs,
})
.then(function () {
const operatorListIR = tilingOpList.getIR();
@ -1043,8 +1041,7 @@ class PartialEvaluator {
task,
state,
fallbackFontDict = null,
cssFontInfo = null,
seenRefs = null
cssFontInfo = null
) {
const fontName = fontArgs?.[0] instanceof Name ? fontArgs[0].name : null;
@ -1054,8 +1051,7 @@ class PartialEvaluator {
resources,
task,
fallbackFontDict,
cssFontInfo,
seenRefs
cssFontInfo
);
if (translated.font.isType3Font) {
@ -1156,10 +1152,7 @@ class PartialEvaluator {
value[0],
operatorList,
task,
stateManager.state,
/* fallbackFontDict = */ null,
/* cssFontInfo = */ null,
seenRefs
stateManager.state
).then(function (loadedName) {
operatorList.addDependency(loadedName);
gStateObj.push([key, [loadedName, value[1]]]);
@ -1237,8 +1230,7 @@ class PartialEvaluator {
resources,
task,
fallbackFontDict = null,
cssFontInfo = null,
seenRefs = null
cssFontInfo = null
) {
const errorFont = async () =>
new TranslatedFont({
@ -1374,7 +1366,7 @@ class PartialEvaluator {
if (translatedFont.isType3Font) {
try {
await translated.loadType3Data(this, resources, task, seenRefs);
await translated.loadType3Data(this, resources, task);
} catch (reason) {
throw new Error(`Type3 font load error: ${reason}`);
}
@ -1585,8 +1577,7 @@ class PartialEvaluator {
task,
localColorSpaceCache,
localTilingPatternCache,
localShadingPatternCache,
seenRefs
localShadingPatternCache
) {
// compile tiling patterns
const patternName = args.pop();
@ -1628,8 +1619,7 @@ class PartialEvaluator {
dict,
operatorList,
task,
localTilingPatternCache,
seenRefs
localTilingPatternCache
);
} else if (typeNum === PatternType.SHADING) {
const shading = dict.get("Shading");
@ -1944,9 +1934,7 @@ class PartialEvaluator {
operatorList,
task,
stateManager.state,
fallbackFontDict,
/* cssFontInfo = */ null,
seenRefs
fallbackFontDict
)
.then(function (loadedName) {
operatorList.addDependency(loadedName);
@ -2124,8 +2112,7 @@ class PartialEvaluator {
task,
localColorSpaceCache,
localTilingPatternCache,
localShadingPatternCache,
seenRefs
localShadingPatternCache
)
);
return;
@ -2157,8 +2144,7 @@ class PartialEvaluator {
task,
localColorSpaceCache,
localTilingPatternCache,
localShadingPatternCache,
seenRefs
localShadingPatternCache
)
);
return;
@ -2745,10 +2731,7 @@ class PartialEvaluator {
fontName,
fontRef,
resources,
task,
/* fallbackFontDict = */ null,
/* cssFontInfo = */ null,
seenRefs
task
);
textState.loadedName = translated.loadedName;
@ -4910,7 +4893,7 @@ class TranslatedFont {
);
}
loadType3Data(evaluator, resources, task, seenRefs = null) {
loadType3Data(evaluator, resources, task) {
if (this.#type3Loaded) {
return this.#type3Loaded;
}
@ -4948,7 +4931,6 @@ class TranslatedFont {
task,
resources: fontResources,
operatorList,
prevRefs: seenRefs,
})
.then(() => {
// According to the PDF specification, section "9.6.5 Type 3 Fonts"

View File

@ -46,8 +46,8 @@ class NameOrNumberTree {
processed.put(this.root);
}
const queue = [this.root];
for (const node of queue) {
const obj = xref.fetchIfRef(node);
while (queue.length > 0) {
const obj = xref.fetchIfRef(queue.shift());
if (!(obj instanceof Dict)) {
continue;
}

View File

@ -221,10 +221,19 @@ const RENDERING_CANCELLED_TIMEOUT = 100; // ms
* XHR as fallback) is used, which means it must follow same origin rules,
* e.g. no cross-domain requests without CORS.
*
* @param {DocumentInitParameters} src - Parameter object.
* @param {string | URL | TypedArray | ArrayBuffer | DocumentInitParameters}
* src - Can be a URL where a PDF file is located, a typed array (Uint8Array)
* already populated with data, or a parameter object.
* @returns {PDFDocumentLoadingTask}
*/
function getDocument(src = {}) {
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
if (typeof src === "string" || src instanceof URL) {
src = { url: src };
} else if (src instanceof ArrayBuffer || ArrayBuffer.isView(src)) {
src = { data: src };
}
}
const task = new PDFDocumentLoadingTask();
const { docId } = task;
@ -1026,6 +1035,13 @@ class PDFDocumentProxy {
return this._transport.startCleanup(keepLoadedFonts || this.isPureXfa);
}
/**
* Destroys the current document instance and terminates the worker.
*/
destroy() {
return this.loadingTask.destroy();
}
/**
* @param {RefProxy} ref - The page reference.
* @returns {number | null} The page number, if it's cached.

View File

@ -1279,20 +1279,13 @@ class CanvasGraphics {
const useLayerSize =
layerW * layerH < SMASK_LAYER_TO_MASK_AREA_RATIO * maskArea;
// Bundle the filter URL with the spec needed for the pixel-buffer
// fallback (see _bakeSMaskCanvas). subtype + transferMap let the
// fallback reproduce the SVG filter without an extra round-trip
// through the filter factory.
const filterSpec = hasFilter
? {
url:
subtype === "Alpha"
? this.filterFactory.addAlphaFilter(transferMap)
: this.filterFactory.addLuminosityFilter(transferMap),
subtype,
transferMap,
}
: null;
let filterUrl = null;
if (hasFilter) {
filterUrl =
subtype === "Alpha"
? this.filterFactory.addAlphaFilter(transferMap)
: this.filterFactory.addLuminosityFilter(transferMap);
}
// Alpha SMasks must not bake /BC into the prepared canvas (see
// filteredOOBAlpha comment above).
@ -1307,7 +1300,7 @@ class CanvasGraphics {
layerW,
layerH,
bakedBackdrop,
filterSpec
filterUrl
);
offsetX = 0;
offsetY = 0;
@ -1319,7 +1312,7 @@ class CanvasGraphics {
maskCanvas.width,
maskCanvas.height,
bakedBackdrop,
filterSpec
filterUrl
);
offsetX = smask.offsetX;
offsetY = smask.offsetY;
@ -1337,9 +1330,8 @@ class CanvasGraphics {
/**
* Bake the mask plus optional backdrop into a (w x h) canvas with the
* mask drawn at (drawX, drawY), then optionally pipe through the SVG
* filter described by `filterSpec`. Returns the prepared canvas-
* factory entry.
* mask drawn at (drawX, drawY), then optionally pipe through
* `filterUrl`. Returns the prepared canvas-factory entry.
*
* The backdrop fill uses destination-atop so transparent / partial-
* alpha pixels inside the mask see the backdrop *before* filtering
@ -1352,17 +1344,9 @@ class CanvasGraphics {
* transferMap[0], matching the spec's transparent extension of the
* mask group. No-backdrop mask-size prebakes have no OOB region;
* destination-in handles OOB at compose time.
*
* Some browsers (e.g. older Safari) silently ignore SVG `url(#id)`
* filters on a 2D canvas: the assignment is accepted but
* `ctx.filter` reads back as "none" and `drawImage` produces an
* unfiltered copy. We detect that and fall back to a pixel-buffer
* loop that reproduces the SVG filter exactly (matrix luminance and
* `feFuncA` transferMap, both with sRGB color-interpolation, i.e.
* straight on gamma-encoded byte values).
*/
_bakeSMaskCanvas(maskCanvas, drawX, drawY, w, h, backdrop, filterSpec) {
if (!backdrop && !filterSpec) {
_bakeSMaskCanvas(maskCanvas, drawX, drawY, w, h, backdrop, filterUrl) {
if (!backdrop && !filterUrl) {
// Caller (_prepareSMaskCanvas) gates on this; without either,
// the prebake would just be a wasted copy of the mask.
unreachable("_bakeSMaskCanvas with neither backdrop nor filter");
@ -1375,45 +1359,14 @@ class CanvasGraphics {
sCtx.fillStyle = backdrop;
sCtx.fillRect(0, 0, w, h);
}
if (!filterSpec) {
if (!filterUrl) {
return srcEntry;
}
const preparedEntry = this.canvasFactory.create(w, h);
const pCtx = preparedEntry.context;
// Pre-assign read: undefined means no canvas filter API (assigning
// would just set a JS property and post-assign read would lie).
// Post-assign "none"/"" means the URL was rejected (Firefox
// normalizes accepted url(#id) to an absolute URL).
const filterSupported = pCtx.filter !== undefined;
pCtx.filter = filterSpec.url;
const filterApplied =
filterSupported && pCtx.filter !== "none" && pCtx.filter !== "";
pCtx.filter = filterUrl;
pCtx.drawImage(srcEntry.canvas, 0, 0);
if (filterSupported) {
pCtx.filter = "none";
}
if (!filterApplied) {
const img = pCtx.getImageData(0, 0, w, h);
const { data } = img;
const { transferMap } = filterSpec;
if (filterSpec.subtype === "Luminosity") {
for (let i = 0, ii = data.length; i < ii; i += 4) {
// Match #addLuminosityConversion: a' = 0.3*R + 0.59*G + 0.11*B,
// RGB -> 0; then optional transferMap on alpha.
const a =
(0.3 * data[i] + 0.59 * data[i + 1] + 0.11 * data[i + 2] + 0.5) | 0;
data[i] = data[i + 1] = data[i + 2] = 0;
data[i + 3] = transferMap?.[a] ?? a;
}
} else {
// Alpha: transferMap is guaranteed by _prepareSMaskCanvas's
// hasFilter gate.
for (let i = 3, ii = data.length; i < ii; i += 4) {
data[i] = transferMap[data[i]];
}
}
pCtx.putImageData(img, 0, 0);
}
pCtx.filter = "none";
this.canvasFactory.destroy(srcEntry);
return preparedEntry;
}

View File

@ -866,7 +866,7 @@ class Driver {
await loadingTask.destroy();
delete task.annotationStorage;
return getDocument({ data }).promise;
return getDocument(data).promise;
});
}
@ -969,7 +969,7 @@ class Driver {
// Wipe out the link to the pdfdoc so it can be GC'ed.
for (const task of [this.currentTask, ...this.taskQueue]) {
if (task?.pdfDoc) {
destroyedPromises.push(task.pdfDoc.loadingTask.destroy());
destroyedPromises.push(task.pdfDoc.destroy());
delete task.pdfDoc;
}
}

View File

@ -912,4 +912,3 @@
!smask_alpha_oob_transfer.pdf
!smask_alpha_bc.pdf
!smask_luminosity_oob_transfer.pdf
!operator_list_cycle.pdf

View File

@ -1,98 +0,0 @@
%PDF-1.7
% ò¤ô
1 0 obj <<
/Kids [3 0 R]
/Type /Pages
/Count 1
>>
endobj
2 0 obj <<
/Type /Catalog
/Pages 1 0 R
>>
endobj
3 0 obj <<
/Resources 11 0 R
/Type /Page
/Contents 10 0 R
/Parent 1 0 R
>>
endobj
10 0 obj <<
>>
stream
1 0 0 1 315.779 733.039 cm
1 0 0 1 2.835 -173.614 cm
1.04704 0 0 1.04704 0 0 cm
/Im6 Do
endstream
endobj
11 0 obj <<
/XObject <<
/Im6 12 0 R
>>
>>
endobj
12 0 obj <<
/Subtype /Form
/Resources <<
/XObject <<
/x15 13 0 R
>>
>>
>>
stream
/x15 Do
endstream
endobj
13 0 obj <<
/Subtype /Form
/Resources <<
/Pattern <<
/p31 14 0 R
>>
>>
>>
stream
q /Pattern cs /p31 scn /a0 gs
0 0 224.720001 160.399994 re f
Q
endstream
endobj
14 0 obj <<
/PatternType 1
/BBox [0 0 225 161]
/Resources <<
/XObject <<
/x47 12 0 R
>>
>>
>>
stream
/x47 Do
endstream
endobj
xref
0 15
0000000000 65535 f
4294967295 00000 n
0000000078 00000 n
0000000131 00000 n
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000221 00000 n
0000000348 00000 n
0000000405 00000 n
0000000531 00000 n
0000000712 00000 n
trailer <<
/Root 2 0 R
/Size 110
>>
startxref
860
%%EOF

View File

@ -10,7 +10,7 @@ class MainTest {
}
loadPdf() {
this.task = getDocument({ url: "file://" + this.file });
this.task = getDocument("file://" + this.file);
return this.task.promise;
}
}

View File

@ -10,7 +10,7 @@ class MainTest {
}
loadPdf() {
this.task = getDocument({ url: "file://" + this.file });
this.task = getDocument("file://" + this.file);
return this.task.promise;
}
}

View File

@ -121,7 +121,7 @@ describe("api", function () {
describe("getDocument", function () {
it("creates pdf doc from URL-string", async function () {
const urlStr = TEST_PDFS_PATH + basicApiFileName;
const loadingTask = getDocument({ url: urlStr });
const loadingTask = getDocument(urlStr);
expect(loadingTask).toBeInstanceOf(PDFDocumentLoadingTask);
const pdfDocument = await loadingTask.promise;
@ -135,7 +135,7 @@ describe("api", function () {
it("creates pdf doc from URL-object", async function () {
const urlObj = TestPdfsServer.resolveURL(basicApiFileName);
const loadingTask = getDocument({ url: urlObj });
const loadingTask = getDocument(urlObj);
expect(loadingTask).toBeInstanceOf(PDFDocumentLoadingTask);
const pdfDocument = await loadingTask.promise;
@ -210,7 +210,7 @@ describe("api", function () {
expect(typedArrayPdf).toBeInstanceOf(Uint8Array);
expect(typedArrayPdf.length).toEqual(basicApiFileLength);
const loadingTask = getDocument({ data: typedArrayPdf });
const loadingTask = getDocument(typedArrayPdf);
expect(loadingTask).toBeInstanceOf(PDFDocumentLoadingTask);
const progressReportedCapability = Promise.withResolvers();
@ -245,7 +245,7 @@ describe("api", function () {
expect(arrayBufferPdf).toBeInstanceOf(ArrayBuffer);
expect(arrayBufferPdf.byteLength).toEqual(basicApiFileLength);
const loadingTask = getDocument({ data: arrayBufferPdf });
const loadingTask = getDocument(arrayBufferPdf);
expect(loadingTask).toBeInstanceOf(PDFDocumentLoadingTask);
const progressReportedCapability = Promise.withResolvers();
@ -516,7 +516,7 @@ describe("api", function () {
);
it("creates pdf doc from empty TypedArray", async function () {
const loadingTask = getDocument({ data: new Uint8Array(0) });
const loadingTask = getDocument(new Uint8Array(0));
expect(loadingTask).toBeInstanceOf(PDFDocumentLoadingTask);
try {
@ -850,7 +850,7 @@ describe("api", function () {
expect(typedArrayPdf).toBeInstanceOf(Uint8Array);
expect(typedArrayPdf.length).toEqual(1116);
const loadingTask = getDocument({ data: typedArrayPdf.slice() });
const loadingTask = getDocument(typedArrayPdf.slice());
expect(loadingTask).toBeInstanceOf(PDFDocumentLoadingTask);
let passwordData = null;
@ -2407,7 +2407,7 @@ describe("api", function () {
expect(typedArrayPdf).toBeInstanceOf(Uint8Array);
expect(typedArrayPdf.length).toEqual(10719);
const loadingTask = getDocument({ data: typedArrayPdf.slice() });
const loadingTask = getDocument(typedArrayPdf.slice());
const pdfDoc = await loadingTask.promise;
const page = await pdfDoc.getPage(1);
// Trigger parsing of the JPEG image.
@ -2463,7 +2463,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const pdfPage = await pdfDoc.getPage(1);
const annotations = await pdfPage.getAnnotations();
@ -2486,7 +2486,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const datasets = await pdfDoc.getXFADatasets();
@ -2522,7 +2522,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const datasets = await pdfDoc.getXFADatasets();
@ -2559,7 +2559,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
page = await pdfDoc.getPage(1);
const newStructTree = await page.getStructTree();
@ -2594,7 +2594,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const annotations = await pdfDoc.getAnnotArray(0);
@ -2673,7 +2673,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
// Ensure that the Annotation text-content was actually compressed.
typedArray = await pdfDoc.getData();
@ -2714,7 +2714,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const page = await pdfDoc.getPage(1);
const opList = await page.getOperatorList();
@ -2772,7 +2772,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const page = await pdfDoc.getPage(1);
const tree = await page.getStructTree();
@ -2867,7 +2867,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const page = await pdfDoc.getPage(1);
const tree = await page.getStructTree();
@ -2935,11 +2935,11 @@ describe("api", function () {
const blob = await getImageBlob("firefox_logo.png");
let loadingTask, pdfDoc;
let docParams = buildGetDocumentParams("empty.pdf");
let data = buildGetDocumentParams("empty.pdf");
for (let i = 1; i <= 2; i++) {
const bitmap = await createImageBitmap(blob);
loadingTask = getDocument(docParams);
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
pdfDoc.annotationStorage.setValue("pdfjs_internal_editor_0", {
annotationType: AnnotationEditorType.STAMP,
@ -2955,11 +2955,11 @@ describe("api", function () {
},
});
docParams = { data: await pdfDoc.saveDocument() };
data = await pdfDoc.saveDocument();
await loadingTask.destroy();
}
loadingTask = getDocument(docParams);
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const page = await pdfDoc.getPage(1);
const tree = await page.getStructTree();
@ -3018,7 +3018,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const page = await pdfDoc.getPage(1);
const tree = await page.getStructTree();
@ -3081,7 +3081,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const page = await pdfDoc.getPage(1);
const tree = await page.getStructTree();
@ -3119,7 +3119,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const page = await pdfDoc.getPage(1);
const annotations = await page.getAnnotations();
@ -3163,7 +3163,7 @@ describe("api", function () {
const data = await pdfDoc.saveDocument();
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const page = await pdfDoc.getPage(1);
const tree = await page.getStructTree();
@ -3203,7 +3203,7 @@ describe("api", function () {
params.url = url.href;
loadingTask = getDocument(params);
return loadingTask.promise
.then(() => loadingTask.destroy())
.then(pdf => pdf.destroy())
.then(
function () {
expect(expectSuccess).toEqual(true);
@ -4452,19 +4452,6 @@ have written that much by now. So, heres to squashing bugs.`);
}
);
it("gets operator list, from a PDF with a Form -> Form -> Pattern -> Form cycle", async function () {
const loadingTask = getDocument(
buildGetDocumentParams("operator_list_cycle.pdf")
);
const pdfDoc = await loadingTask.promise;
const pdfPage = await pdfDoc.getPage(1);
const operatorList = await pdfPage.getOperatorList();
expect(operatorList.lastChunk).toEqual(true);
await loadingTask.destroy();
});
it("gets operator list, containing Annotation-operatorLists", async function () {
const loadingTask = getDocument(
buildGetDocumentParams("annotation-line.pdf")
@ -5220,7 +5207,7 @@ have written that much by now. So, heres to squashing bugs.`);
describe("PDFDataRangeTransport", function () {
async function streamDelay() {
return new Promise(resolve => {
setTimeout(resolve, 100);
setTimeout(resolve, 250);
});
}
let dataPromise;
@ -5282,7 +5269,7 @@ have written that much by now. So, heres to squashing bugs.`);
expect(contentDispositionFilename).toEqual("aaa.pdf");
expect(contentLength).toEqual(dataLength);
expect(fetches).toEqual(5);
expect(fetches).toBeGreaterThan(4);
expect(initialProgress).toEqual({
loaded: initialDataLength,
@ -5441,7 +5428,7 @@ have written that much by now. So, heres to squashing bugs.`);
expect(contentDispositionFilename).toEqual(null);
expect(contentLength).toEqual(dataLength);
expect(fetches).toEqual(3);
expect(fetches).toBeGreaterThan(2);
expect(initialProgress.loaded).toBeGreaterThan(initialDataLength);
expect(initialProgress.total).toEqual(dataLength);
@ -5610,7 +5597,7 @@ small scripts as well as for`);
return;
}
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(expected.length);
@ -5644,7 +5631,7 @@ small scripts as well as for`);
{ document: pdfData2 },
{ document: pdfData3 },
]);
let newLoadingTask = getDocument({ data });
let newLoadingTask = getDocument(data);
let newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(9);
@ -5662,7 +5649,7 @@ small scripts as well as for`);
{ document: pdfData2 },
{ document: null },
]);
newLoadingTask = getDocument({ data });
newLoadingTask = getDocument(data);
newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(9);
for (let i = 1; i <= 9; i++) {
@ -5679,7 +5666,7 @@ small scripts as well as for`);
{ document: pdfData2, includePages: [0] },
{ document: pdfData3, includePages: [0] },
]);
newLoadingTask = getDocument({ data });
newLoadingTask = getDocument(data);
newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(3);
for (let i = 1; i <= 3; i++) {
@ -5694,7 +5681,7 @@ small scripts as well as for`);
{ document: pdfData2, excludePages: [0] },
{ document: pdfData3, excludePages: [0] },
]);
newLoadingTask = getDocument({ data });
newLoadingTask = getDocument(data);
newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(6);
for (let i = 1; i <= 6; i++) {
@ -5722,7 +5709,7 @@ small scripts as well as for`);
{ document: pdfData1, includePages: [[0, 0], 2] },
{ document: null, includePages: [[2, 4], 7] },
]);
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(6);
@ -5769,7 +5756,7 @@ small scripts as well as for`);
],
},
]);
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(6);
@ -5809,7 +5796,7 @@ small scripts as well as for`);
{ document: null, includePages: [0] },
{ document: pdfData1, password: "asdfasdf" },
]);
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(2);
@ -5858,7 +5845,7 @@ small scripts as well as for`);
includePages: [0, 1, 5, 7, 10],
});
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
const newPdfDoc = await loadingTask.promise;
labels = await newPdfDoc.getPageLabels();
expect(labels).toEqual(["i", "ii", "1", "a", "5"]);
@ -5882,7 +5869,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
destinations = await pdfDoc.getDestinations();
@ -5918,7 +5905,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(4);
@ -5945,7 +5932,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(8);
@ -5986,7 +5973,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(3);
@ -6023,7 +6010,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(4);
@ -6102,7 +6089,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(2);
@ -6205,7 +6192,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(3);
@ -6296,7 +6283,7 @@ small scripts as well as for`);
{ document: null, includePages: [1, 3, 5], pageIndices: [1, 2, 0] },
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(3);
@ -6378,7 +6365,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(2);
@ -6417,7 +6404,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(3);
@ -6462,7 +6449,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(6);
@ -6516,7 +6503,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(5);
@ -6546,7 +6533,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(3);
@ -6587,7 +6574,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const attachments = await pdfDoc.getAttachments();
@ -6614,7 +6601,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const attachments = await pdfDoc.getAttachments();
@ -6662,7 +6649,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(1);
@ -6714,7 +6701,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(2);
@ -6760,7 +6747,7 @@ small scripts as well as for`);
const data = await pdfDoc.extractPages([{ document: null }]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
const calculationOrder = await pdfDoc.getCalculationOrderIds();
@ -6791,7 +6778,7 @@ small scripts as well as for`);
expect(data).not.toBeNull();
await loadingTask.destroy();
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(2);
await newLoadingTask.destroy();
@ -6823,7 +6810,7 @@ small scripts as well as for`);
const data = await pdfDoc.extractPages([{ document: null }]);
await loadingTask.destroy();
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
const outline = await newPdfDoc.getOutline();
@ -6903,7 +6890,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
const outline = await newPdfDoc.getOutline();
@ -6941,7 +6928,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
const outline = await newPdfDoc.getOutline();
@ -7009,7 +6996,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(2);
@ -7069,7 +7056,7 @@ small scripts as well as for`);
const data = await pdfDoc.extractPages([{ document: null }]);
await loadingTask.destroy();
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
const outline = await newPdfDoc.getOutline();
@ -7097,7 +7084,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(2);
@ -7146,7 +7133,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(1);
@ -7178,7 +7165,7 @@ small scripts as well as for`);
const data = await pdfDoc.extractPages([{ document: null }]);
await loadingTask.destroy();
const newLoadingTask = getDocument({ data });
const newLoadingTask = getDocument(data);
const newPdfDoc = await newLoadingTask.promise;
expect(newPdfDoc.numPages).toEqual(1);
await newLoadingTask.destroy();
@ -7201,7 +7188,7 @@ small scripts as well as for`);
// Opening the result without a password must fail.
// Use a copy so the underlying ArrayBuffer is not detached before the
// second getDocument call below.
const passwordNeededLoadingTask = getDocument({ data: data.slice() });
const passwordNeededLoadingTask = getDocument(data.slice());
await passwordNeededLoadingTask.promise.then(
function () {
// Shouldn't get here.
@ -7240,7 +7227,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(3);
@ -7275,7 +7262,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(3);
@ -7309,7 +7296,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(23);
@ -7348,7 +7335,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(3);
@ -7381,7 +7368,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(4);
@ -7414,7 +7401,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(3);
@ -7446,7 +7433,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(3);
@ -7533,7 +7520,7 @@ small scripts as well as for`);
]);
await loadingTask.destroy();
loadingTask = getDocument({ data });
loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise;
expect(pdfDoc.numPages).toEqual(2);

View File

@ -35,36 +35,50 @@ import { calculateMD5 } from "../../src/core/calculate_md5.js";
import { calculateSHA256 } from "../../src/core/calculate_sha256.js";
describe("crypto", function () {
function hex2binary(s) {
const digits = "0123456789ABCDEF";
s = s.toUpperCase();
const n = s.length >> 1;
const result = new Uint8Array(n);
for (let i = 0, j = 0; i < n; ++i) {
const d1 = s.charAt(j++);
const d2 = s.charAt(j++);
const value = (digits.indexOf(d1) << 4) | digits.indexOf(d2);
result[i] = value;
}
return result;
}
// RFC 1321, A.5 Test suite
describe("calculateMD5", function () {
it("should pass RFC 1321 test #1", function () {
const input = stringToBytes("");
const result = calculateMD5(input, 0, input.length);
const expected = Uint8Array.fromHex("d41d8cd98f00b204e9800998ecf8427e");
const expected = hex2binary("d41d8cd98f00b204e9800998ecf8427e");
expect(result).toEqual(expected);
});
it("should pass RFC 1321 test #2", function () {
const input = stringToBytes("a");
const result = calculateMD5(input, 0, input.length);
const expected = Uint8Array.fromHex("0cc175b9c0f1b6a831c399e269772661");
const expected = hex2binary("0cc175b9c0f1b6a831c399e269772661");
expect(result).toEqual(expected);
});
it("should pass RFC 1321 test #3", function () {
const input = stringToBytes("abc");
const result = calculateMD5(input, 0, input.length);
const expected = Uint8Array.fromHex("900150983cd24fb0d6963f7d28e17f72");
const expected = hex2binary("900150983cd24fb0d6963f7d28e17f72");
expect(result).toEqual(expected);
});
it("should pass RFC 1321 test #4", function () {
const input = stringToBytes("message digest");
const result = calculateMD5(input, 0, input.length);
const expected = Uint8Array.fromHex("f96b697d7cb7938d525a2f31aaf161d0");
const expected = hex2binary("f96b697d7cb7938d525a2f31aaf161d0");
expect(result).toEqual(expected);
});
it("should pass RFC 1321 test #5", function () {
const input = stringToBytes("abcdefghijklmnopqrstuvwxyz");
const result = calculateMD5(input, 0, input.length);
const expected = Uint8Array.fromHex("c3fcd3d76192e4007dfb496cca67e13b");
const expected = hex2binary("c3fcd3d76192e4007dfb496cca67e13b");
expect(result).toEqual(expected);
});
it("should pass RFC 1321 test #6", function () {
@ -72,7 +86,7 @@ describe("crypto", function () {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
);
const result = calculateMD5(input, 0, input.length);
const expected = Uint8Array.fromHex("d174ab98d277d9f5a5611c2c9f419d9f");
const expected = hex2binary("d174ab98d277d9f5a5611c2c9f419d9f");
expect(result).toEqual(expected);
});
it("should pass RFC 1321 test #7", function () {
@ -81,7 +95,7 @@ describe("crypto", function () {
"90123456789012345678901234567890"
);
const result = calculateMD5(input, 0, input.length);
const expected = Uint8Array.fromHex("57edf4a22be3c955ac49da2e2107b67a");
const expected = hex2binary("57edf4a22be3c955ac49da2e2107b67a");
expect(result).toEqual(expected);
});
});
@ -89,40 +103,40 @@ describe("crypto", function () {
// http://www.freemedialibrary.com/index.php/RC4_test_vectors are used
describe("ARCFourCipher", function () {
it("should pass test #1", function () {
const key = Uint8Array.fromHex("0123456789abcdef");
const input = Uint8Array.fromHex("0123456789abcdef");
const key = hex2binary("0123456789abcdef");
const input = hex2binary("0123456789abcdef");
const cipher = new ARCFourCipher(key);
const result = cipher.encryptBlock(input);
const expected = Uint8Array.fromHex("75b7878099e0c596");
const expected = hex2binary("75b7878099e0c596");
expect(result).toEqual(expected);
});
it("should pass test #2", function () {
const key = Uint8Array.fromHex("0123456789abcdef");
const input = Uint8Array.fromHex("0000000000000000");
const key = hex2binary("0123456789abcdef");
const input = hex2binary("0000000000000000");
const cipher = new ARCFourCipher(key);
const result = cipher.encryptBlock(input);
const expected = Uint8Array.fromHex("7494c2e7104b0879");
const expected = hex2binary("7494c2e7104b0879");
expect(result).toEqual(expected);
});
it("should pass test #3", function () {
const key = Uint8Array.fromHex("0000000000000000");
const input = Uint8Array.fromHex("0000000000000000");
const key = hex2binary("0000000000000000");
const input = hex2binary("0000000000000000");
const cipher = new ARCFourCipher(key);
const result = cipher.encryptBlock(input);
const expected = Uint8Array.fromHex("de188941a3375d3a");
const expected = hex2binary("de188941a3375d3a");
expect(result).toEqual(expected);
});
it("should pass test #4", function () {
const key = Uint8Array.fromHex("ef012345");
const input = Uint8Array.fromHex("00000000000000000000");
const key = hex2binary("ef012345");
const input = hex2binary("00000000000000000000");
const cipher = new ARCFourCipher(key);
const result = cipher.encryptBlock(input);
const expected = Uint8Array.fromHex("d6a141a7ec3c38dfbd61");
const expected = hex2binary("d6a141a7ec3c38dfbd61");
expect(result).toEqual(expected);
});
it("should pass test #5", function () {
const key = Uint8Array.fromHex("0123456789abcdef");
const input = Uint8Array.fromHex(
const key = hex2binary("0123456789abcdef");
const input = hex2binary(
"010101010101010101010101010101010101010101010101010" +
"10101010101010101010101010101010101010101010101010101010101010101010" +
"10101010101010101010101010101010101010101010101010101010101010101010" +
@ -142,7 +156,7 @@ describe("crypto", function () {
);
const cipher = new ARCFourCipher(key);
const result = cipher.encryptBlock(input);
const expected = Uint8Array.fromHex(
const expected = hex2binary(
"7595c3e6114a09780c4ad452338e1ffd9a1be9498f813d76" +
"533449b6778dcad8c78a8d2ba9ac66085d0e53d59c26c2d1c490c1ebbe0ce66d1b6b" +
"1b13b6b919b847c25a91447a95e75e4ef16779cde8bf0a95850e32af9689444fd377" +
@ -163,15 +177,15 @@ describe("crypto", function () {
expect(result).toEqual(expected);
});
it("should pass test #6", function () {
const key = Uint8Array.fromHex("fb029e3031323334");
const input = Uint8Array.fromHex(
const key = hex2binary("fb029e3031323334");
const input = hex2binary(
"aaaa0300000008004500004e661a00008011be640a0001220af" +
"fffff00890089003a000080a601100001000000000000204543454a4548454346434" +
"550464545494546464343414341434143414341414100002000011bd0b604"
);
const cipher = new ARCFourCipher(key);
const result = cipher.encryptBlock(input);
const expected = Uint8Array.fromHex(
const expected = hex2binary(
"f69c5806bd6ce84626bcbefb9474650aad1f7909b0f64d5f" +
"58a503a258b7ed22eb0ea64930d3a056a55742fcce141d485f8aa836dea18df42c53" +
"80805ad0c61a5d6f58f41040b24b7d1a693856ed0d4398e7aee3bf0e2a2ca8f7"
@ -179,13 +193,13 @@ describe("crypto", function () {
expect(result).toEqual(expected);
});
it("should pass test #7", function () {
const key = Uint8Array.fromHex("0123456789abcdef");
const input = Uint8Array.fromHex(
const key = hex2binary("0123456789abcdef");
const input = hex2binary(
"123456789abcdef0123456789abcdef0123456789abcdef012345678"
);
const cipher = new ARCFourCipher(key);
const result = cipher.encryptBlock(input);
const expected = Uint8Array.fromHex(
const expected = hex2binary(
"66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf"
);
expect(result).toEqual(expected);
@ -196,7 +210,7 @@ describe("crypto", function () {
it("should properly hash abc", function () {
const input = stringToBytes("abc");
const result = calculateSHA256(input, 0, input.length);
const expected = Uint8Array.fromHex(
const expected = hex2binary(
"BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"
);
expect(result).toEqual(expected);
@ -206,7 +220,7 @@ describe("crypto", function () {
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
);
const result = calculateSHA256(input, 0, input.length);
const expected = Uint8Array.fromHex(
const expected = hex2binary(
"248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1"
);
expect(result).toEqual(expected);
@ -217,7 +231,7 @@ describe("crypto", function () {
it("should properly hash abc", function () {
const input = stringToBytes("abc");
const result = calculateSHA384(input, 0, input.length);
const expected = Uint8Array.fromHex(
const expected = hex2binary(
"CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED163" +
"1A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7"
);
@ -230,7 +244,7 @@ describe("crypto", function () {
"mnopqrstnopqrstu"
);
const result = calculateSHA384(input, 0, input.length);
const expected = Uint8Array.fromHex(
const expected = hex2binary(
"09330C33F71147E83D192FC782CD1B4753111B173B3B05D2" +
"2FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039"
);
@ -242,7 +256,7 @@ describe("crypto", function () {
it("should properly hash abc", function () {
const input = stringToBytes("abc");
const result = calculateSHA512(input, 0, input.length);
const expected = Uint8Array.fromHex(
const expected = hex2binary(
"DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2" +
"0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD" +
"454D4423643CE80E2A9AC94FA54CA49F"
@ -256,7 +270,7 @@ describe("crypto", function () {
"mnopqrstnopqrstu"
);
const result = calculateSHA512(input, 0, input.length);
const expected = Uint8Array.fromHex(
const expected = hex2binary(
"8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1" +
"7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A" +
"C7D329EEB6DD26545E96E55B874BE909"
@ -268,25 +282,26 @@ describe("crypto", function () {
describe("AES128", function () {
describe("Encryption", function () {
it("should be able to encrypt a block", function () {
const input = Uint8Array.fromHex("00112233445566778899aabbccddeeff");
const key = Uint8Array.fromHex("000102030405060708090a0b0c0d0e0f");
const iv = Uint8Array.fromHex("00000000000000000000000000000000");
const input = hex2binary("00112233445566778899aabbccddeeff");
const key = hex2binary("000102030405060708090a0b0c0d0e0f");
const iv = hex2binary("00000000000000000000000000000000");
const cipher = new AES128Cipher(key);
const result = cipher.encrypt(input, iv);
const expected = Uint8Array.fromHex("69c4e0d86a7b0430d8cdb78070b4c55a");
const expected = hex2binary("69c4e0d86a7b0430d8cdb78070b4c55a");
expect(result).toEqual(expected);
});
});
describe("Decryption", function () {
it("should be able to decrypt a block with IV in stream", function () {
const input = Uint8Array.fromHex(
"0000000000000000000000000000000069c4e0d86a7b0430d8cdb78070b4c55a"
const input = hex2binary(
"0000000000000000000000000000000069c4e0d86a7b0430d" +
"8cdb78070b4c55a"
);
const key = Uint8Array.fromHex("000102030405060708090a0b0c0d0e0f");
const key = hex2binary("000102030405060708090a0b0c0d0e0f");
const cipher = new AES128Cipher(key);
const result = cipher.decryptBlock(input);
const expected = Uint8Array.fromHex("00112233445566778899aabbccddeeff");
const expected = hex2binary("00112233445566778899aabbccddeeff");
expect(result).toEqual(expected);
});
});
@ -295,40 +310,44 @@ describe("crypto", function () {
describe("AES256", function () {
describe("Encryption", function () {
it("should be able to encrypt a block", function () {
const input = Uint8Array.fromHex("00112233445566778899aabbccddeeff");
const key = Uint8Array.fromHex(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
const input = hex2binary("00112233445566778899aabbccddeeff");
const key = hex2binary(
"000102030405060708090a0b0c0d0e0f101112131415161718" +
"191a1b1c1d1e1f"
);
const iv = Uint8Array.fromHex("00000000000000000000000000000000");
const iv = hex2binary("00000000000000000000000000000000");
const cipher = new AES256Cipher(key);
const result = cipher.encrypt(input, iv);
const expected = Uint8Array.fromHex("8ea2b7ca516745bfeafc49904b496089");
const expected = hex2binary("8ea2b7ca516745bfeafc49904b496089");
expect(result).toEqual(expected);
});
});
describe("Decryption", function () {
it("should be able to decrypt a block with specified iv", function () {
const input = Uint8Array.fromHex("8ea2b7ca516745bfeafc49904b496089");
const key = Uint8Array.fromHex(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
const input = hex2binary("8ea2b7ca516745bfeafc49904b496089");
const key = hex2binary(
"000102030405060708090a0b0c0d0e0f101112131415161718" +
"191a1b1c1d1e1f"
);
const iv = Uint8Array.fromHex("00000000000000000000000000000000");
const iv = hex2binary("00000000000000000000000000000000");
const cipher = new AES256Cipher(key);
const result = cipher.decryptBlock(input, false, iv);
const expected = Uint8Array.fromHex("00112233445566778899aabbccddeeff");
const expected = hex2binary("00112233445566778899aabbccddeeff");
expect(result).toEqual(expected);
});
it("should be able to decrypt a block with IV in stream", function () {
const input = Uint8Array.fromHex(
"000000000000000000000000000000008ea2b7ca516745bfeafc49904b496089"
const input = hex2binary(
"000000000000000000000000000000008ea2b7ca516745bf" +
"eafc49904b496089"
);
const key = Uint8Array.fromHex(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
const key = hex2binary(
"000102030405060708090a0b0c0d0e0f101112131415161718" +
"191a1b1c1d1e1f"
);
const cipher = new AES256Cipher(key);
const result = cipher.decryptBlock(input, false);
const expected = Uint8Array.fromHex("00112233445566778899aabbccddeeff");
const expected = hex2binary("00112233445566778899aabbccddeeff");
expect(result).toEqual(expected);
});
});

View File

@ -1220,12 +1220,11 @@ const PDFViewerApplication = {
const workerParams = AppOptions.getAll(OptionKind.WORKER);
Object.assign(GlobalWorkerOptions, workerParams);
if (args.data && isPdfFile(args.filename)) {
this._contentDispositionFilename = args.filename;
} else if (
(typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) &&
args.url
) {
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
if (args.data && isPdfFile(args.filename)) {
this._contentDispositionFilename = args.filename;
}
} else if (args.url) {
// The Firefox built-in viewer always calls `setTitleUsingUrl`, before
// `initPassiveLoading`, and it never provides an `originalUrl` here.
this.setTitleUsingUrl(

View File

@ -95,7 +95,7 @@ async function openDocument(source, name) {
if (pdfDoc) {
pageView.reset();
await pdfDoc.loadingTask.destroy();
await pdfDoc.destroy();
pdfDoc = null;
}