123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
- From: Shelley Vohr <[email protected]>
- Date: Mon, 17 Jan 2022 23:47:54 +0100
- Subject: fix: crash when saving edited PDF files
- This commit fixes a crash that persists any time a user attempts to
- download an edited PDF. This was happening because the logic flow for
- downloading of any edited PDF triggers a call to
- chrome.fileSystem.chooseEntry, which we do not support and which
- therefore causes unmapped page access crashes.
- This patch can be removed should we choose to support chrome.fileSystem
- or support it enough to fix the crash.
- diff --git a/chrome/browser/resources/pdf/pdf_viewer.ts b/chrome/browser/resources/pdf/pdf_viewer.ts
- index 4f83c769386ab3f8b9e62ecf82964a3b85b06625..c86ac99a1ad70eddb34cdfa65e2e3fab546c4c83 100644
- --- a/chrome/browser/resources/pdf/pdf_viewer.ts
- +++ b/chrome/browser/resources/pdf/pdf_viewer.ts
- @@ -1051,28 +1051,27 @@ export class PdfViewerElement extends PdfViewerBaseElement {
- dataArray = [result.dataToSave];
- }
-
- - const blob = new Blob(dataArray);
- const fileName = this.attachments_[index].name;
- - chrome.fileSystem.chooseEntry(
- - {type: 'saveFile', suggestedName: fileName},
- - (entry?: FileSystemFileEntry) => {
- - if (chrome.runtime.lastError) {
- - if (chrome.runtime.lastError.message !== 'User cancelled') {
- - console.error(
- - 'chrome.fileSystem.chooseEntry failed: ' +
- - chrome.runtime.lastError.message);
- - }
- - return;
- - }
- - entry!.createWriter((writer: FileWriter) => {
- - writer.write(blob);
- - // <if expr="enable_ink">
- - // Unblock closing the window now that the user has saved
- - // successfully.
- - this.setShowBeforeUnloadDialog_(false);
- - // </if>
- - });
- - });
- + const blob = new Blob(dataArray);
- +
- + try {
- + const fileHandle = await window.showSaveFilePicker({
- + suggestedName: fileName,
- + });
- +
- + const writable = await fileHandle.createWritable();
- + await writable.write(blob);
- + await writable.close();
- + // <if expr="enable_ink">
- + // Unblock closing the window now that the user has saved
- + // successfully.
- + this.setShowBeforeUnloadDialog_(false);
- + // </if>
- + } catch (error: any) {
- + if (error.name !== 'AbortError') {
- + console.error('window.showSaveFilePicker failed: ' + error);
- + }
- + }
- }
-
- /**
- @@ -1256,36 +1255,33 @@ export class PdfViewerElement extends PdfViewerBaseElement {
- fileName = fileName + '.pdf';
- }
-
- - // Create blob before callback to avoid race condition.
- const blob = new Blob([result.dataToSave], {type: 'application/pdf'});
- - chrome.fileSystem.chooseEntry(
- - {
- - type: 'saveFile',
- - accepts: [{description: '*.pdf', extensions: ['pdf']}],
- - suggestedName: fileName,
- - },
- - (entry?: FileSystemFileEntry) => {
- - if (chrome.runtime.lastError) {
- - if (chrome.runtime.lastError.message !== 'User cancelled') {
- - console.error(
- - 'chrome.fileSystem.chooseEntry failed: ' +
- - chrome.runtime.lastError.message);
- - }
- - return;
- - }
- - entry!.createWriter((writer: FileWriter) => {
- - writer.write(blob);
- - // <if expr="enable_ink or enable_pdf_ink2">
- - // Unblock closing the window now that the user has saved
- - // successfully.
- - this.setShowBeforeUnloadDialog_(false);
- - // </if>
- - // <if expr="enable_pdf_ink2">
- - this.hasSavedEdits_ =
- - this.hasSavedEdits_ || requestType === SaveRequestType.EDITED;
- - // </if>
- - });
- - });
- + try {
- + const fileHandle = await window.showSaveFilePicker({
- + suggestedName: fileName,
- + types: [{
- + description: 'PDF Files',
- + accept: { 'application/pdf': ['.pdf'] },
- + }],
- + });
- +
- + const writable = await fileHandle.createWritable();
- + await writable.write(blob);
- + await writable.close();
- + // <if expr="enable_ink or enable_pdf_ink2">
- + // Unblock closing the window now that the user has saved
- + // successfully.
- + this.setShowBeforeUnloadDialog_(false);
- + // </if>
- + // <if expr="enable_pdf_ink2">
- + this.hasSavedEdits_ =
- + this.hasSavedEdits_ || requestType === SaveRequestType.EDITED;
- + // </if>
- + } catch (error: any) {
- + if (error.name !== 'AbortError') {
- + console.error('window.showSaveFilePicker failed: ' + error);
- + }
- + }
-
- // <if expr="enable_pdf_ink2">
- // Ink2 doesn't need to exit annotation mode after save.
- @@ -1421,6 +1417,9 @@ declare global {
- interface HTMLElementTagNameMap {
- 'pdf-viewer': PdfViewerElement;
- }
- + interface Window {
- + showSaveFilePicker(opts: unknown): Promise<FileSystemFileHandle>;
- + }
- }
-
- customElements.define(PdfViewerElement.is, PdfViewerElement);
|