Merge pull request #14548 from Snuffleupagus/bug-1754421

[api-minor] Ensure that the `PDFDocumentLoadingTask`-promise is rejected when cancelling the PasswordPrompt (bug 1754421)
This commit is contained in:
Tim van der Meij 2022-02-09 19:41:22 +01:00 committed by GitHub
commit d3d63cb471
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 9 deletions

View File

@ -2644,9 +2644,11 @@ class WorkerTransport {
if (loadingTask.onPassword) { if (loadingTask.onPassword) {
const updatePassword = password => { const updatePassword = password => {
this._passwordCapability.resolve({ if (password instanceof Error) {
password, this._passwordCapability.reject(password);
}); } else {
this._passwordCapability.resolve({ password });
}
}; };
try { try {
loadingTask.onPassword(updatePassword, exception.code); loadingTask.onPassword(updatePassword, exception.code);

View File

@ -239,7 +239,7 @@ describe("api", function () {
const passwordNeededCapability = createPromiseCapability(); const passwordNeededCapability = createPromiseCapability();
const passwordIncorrectCapability = createPromiseCapability(); const passwordIncorrectCapability = createPromiseCapability();
// Attach the callback that is used to request a password; // Attach the callback that is used to request a password;
// similarly to how viewer.js handles passwords. // similarly to how the default viewer handles passwords.
loadingTask.onPassword = function (updatePassword, reason) { loadingTask.onPassword = function (updatePassword, reason) {
if ( if (
reason === PasswordResponses.NEED_PASSWORD && reason === PasswordResponses.NEED_PASSWORD &&
@ -405,6 +405,38 @@ describe("api", function () {
} }
); );
it(
"creates pdf doc from password protected PDF file and passes an Error " +
"(asynchronously) to the onPassword callback (bug 1754421)",
async function () {
const loadingTask = getDocument(
buildGetDocumentParams("issue3371.pdf")
);
expect(loadingTask instanceof PDFDocumentLoadingTask).toEqual(true);
// Attach the callback that is used to request a password;
// similarly to how the default viewer handles passwords.
loadingTask.onPassword = function (updatePassword, reason) {
waitSome(() => {
updatePassword(new Error("Should reject the loadingTask."));
});
};
await loadingTask.promise.then(
function () {
// Shouldn't get here.
expect(false).toEqual(true);
},
function (reason) {
expect(reason instanceof PasswordException).toEqual(true);
expect(reason.code).toEqual(PasswordResponses.NEED_PASSWORD);
}
);
await loadingTask.destroy();
}
);
it("creates pdf doc from empty typed array", async function () { it("creates pdf doc from empty typed array", async function () {
const loadingTask = getDocument(new Uint8Array(0)); const loadingTask = getDocument(new Uint8Array(0));
expect(loadingTask instanceof PDFDocumentLoadingTask).toEqual(true); expect(loadingTask instanceof PDFDocumentLoadingTask).toEqual(true);

View File

@ -51,18 +51,18 @@ class PasswordPrompt {
this.reason = null; this.reason = null;
// Attach the event listeners. // Attach the event listeners.
this.submitButton.addEventListener("click", this.verify.bind(this)); this.submitButton.addEventListener("click", this.#verify.bind(this));
this.cancelButton.addEventListener("click", this.close.bind(this)); this.cancelButton.addEventListener("click", this.#cancel.bind(this));
this.input.addEventListener("keydown", e => { this.input.addEventListener("keydown", e => {
if (e.keyCode === /* Enter = */ 13) { if (e.keyCode === /* Enter = */ 13) {
this.verify(); this.#verify();
} }
}); });
this.overlayManager.register( this.overlayManager.register(
this.overlayName, this.overlayName,
this.container, this.container,
this.close.bind(this), this.#cancel.bind(this),
true true
); );
} }
@ -87,7 +87,7 @@ class PasswordPrompt {
}); });
} }
verify() { #verify() {
const password = this.input.value; const password = this.input.value;
if (password?.length > 0) { if (password?.length > 0) {
this.close(); this.close();
@ -95,6 +95,11 @@ class PasswordPrompt {
} }
} }
#cancel() {
this.close();
this.updateCallback(new Error("PasswordPrompt cancelled."));
}
setUpdateCallback(updateCallback, reason) { setUpdateCallback(updateCallback, reason) {
this.updateCallback = updateCallback; this.updateCallback = updateCallback;
this.reason = reason; this.reason = reason;