diff --git a/src/core/catalog.js b/src/core/catalog.js index 7081d1c53fd43..55d0e13c51d4c 100644 --- a/src/core/catalog.js +++ b/src/core/catalog.js @@ -1568,9 +1568,13 @@ class Catalog { case "GoToR": const urlDict = action.get("F"); if (urlDict instanceof Dict) { - // We assume that we found a FileSpec dictionary - // and fetch the URL without checking any further. - url = urlDict.get("F") || null; + const fs = new FileSpec( + urlDict, + /* xref = */ null, + /* skipContent = */ true + ); + const { filename } = fs.serializable; + url = filename; } else if (typeof urlDict === "string") { url = urlDict; } diff --git a/src/core/file_spec.js b/src/core/file_spec.js index da85e90465266..8ce91c35275e6 100644 --- a/src/core/file_spec.js +++ b/src/core/file_spec.js @@ -42,7 +42,9 @@ function pickPlatformItem(dict) { * collections attributes and related files (/RF) */ class FileSpec { - constructor(root, xref) { + #contentAvailable = false; + + constructor(root, xref, skipContent = false) { if (!(root instanceof Dict)) { return; } @@ -57,10 +59,12 @@ class FileSpec { if (root.has("RF")) { warn("Related file specifications are not supported"); } - this.contentAvailable = true; - if (!root.has("EF")) { - this.contentAvailable = false; - warn("Non-embedded file specifications are not supported"); + if (!skipContent) { + if (root.has("EF")) { + this.#contentAvailable = true; + } else { + warn("Non-embedded file specifications are not supported"); + } } } @@ -76,7 +80,7 @@ class FileSpec { } get content() { - if (!this.contentAvailable) { + if (!this.#contentAvailable) { return null; } if (!this.contentRef && this.root) { diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index be38029c585c5..29b737b578782 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -63,6 +63,7 @@ !issue7507.pdf !issue6931_reduced.pdf !issue14847.pdf +!issue17846.pdf !doc_actions.pdf !issue7580.pdf !issue7598.pdf diff --git a/test/pdfs/issue17846.pdf b/test/pdfs/issue17846.pdf new file mode 100644 index 0000000000000..407a3ee6a8bf6 Binary files /dev/null and b/test/pdfs/issue17846.pdf differ diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index 6870ddb8bf238..d9cbdfa463fa0 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -2926,6 +2926,26 @@ describe("api", function () { await loadingTask.destroy(); }); + it("gets annotations containing /Launch action with /FileSpec dictionary (issue 17846)", async function () { + const loadingTask = getDocument(buildGetDocumentParams("issue17846.pdf")); + const pdfDoc = await loadingTask.promise; + const pdfPage = await pdfDoc.getPage(1); + + const annotations = await pdfPage.getAnnotations(); + expect(annotations.length).toEqual(1); + + const { annotationType, url, unsafeUrl, newWindow } = annotations[0]; + expect(annotationType).toEqual(AnnotationType.LINK); + + expect(url).toBeUndefined(); + expect(unsafeUrl).toEqual( + "对不起/没关系/1_1_模块1行政文件和药品信息目录.pdf" + ); + expect(newWindow).toEqual(true); + + await loadingTask.destroy(); + }); + it("gets text content", async function () { const { items, styles } = await page.getTextContent();