Merge pull request #19577 from Snuffleupagus/isValidExplicitDest-reuse
Re-use the `isValidExplicitDest` helper function in the worker/viewer
This commit is contained in:
commit
be6ef64a2c
@ -14,15 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
collectActions,
|
_isValidExplicitDest,
|
||||||
isNumberArray,
|
|
||||||
MissingDataException,
|
|
||||||
PDF_VERSION_REGEXP,
|
|
||||||
recoverJsURL,
|
|
||||||
toRomanNumerals,
|
|
||||||
XRefEntryException,
|
|
||||||
} from "./core_utils.js";
|
|
||||||
import {
|
|
||||||
createValidAbsoluteUrl,
|
createValidAbsoluteUrl,
|
||||||
DocumentActionEventType,
|
DocumentActionEventType,
|
||||||
FormatError,
|
FormatError,
|
||||||
@ -34,6 +26,15 @@ import {
|
|||||||
stringToUTF8String,
|
stringToUTF8String,
|
||||||
warn,
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
|
import {
|
||||||
|
collectActions,
|
||||||
|
isNumberArray,
|
||||||
|
MissingDataException,
|
||||||
|
PDF_VERSION_REGEXP,
|
||||||
|
recoverJsURL,
|
||||||
|
toRomanNumerals,
|
||||||
|
XRefEntryException,
|
||||||
|
} from "./core_utils.js";
|
||||||
import {
|
import {
|
||||||
Dict,
|
Dict,
|
||||||
isDict,
|
isDict,
|
||||||
@ -53,52 +54,13 @@ import { FileSpec } from "./file_spec.js";
|
|||||||
import { MetadataParser } from "./metadata_parser.js";
|
import { MetadataParser } from "./metadata_parser.js";
|
||||||
import { StructTreeRoot } from "./struct_tree.js";
|
import { StructTreeRoot } from "./struct_tree.js";
|
||||||
|
|
||||||
function isValidExplicitDest(dest) {
|
const isRef = v => v instanceof Ref;
|
||||||
if (!Array.isArray(dest) || dest.length < 2) {
|
|
||||||
return false;
|
const isValidExplicitDest = _isValidExplicitDest.bind(
|
||||||
}
|
null,
|
||||||
const [page, zoom, ...args] = dest;
|
/* validRef = */ isRef,
|
||||||
if (!(page instanceof Ref) && !Number.isInteger(page)) {
|
/* validName = */ isName
|
||||||
return false;
|
);
|
||||||
}
|
|
||||||
if (!(zoom instanceof Name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const argsLen = args.length;
|
|
||||||
let allowNull = true;
|
|
||||||
switch (zoom.name) {
|
|
||||||
case "XYZ":
|
|
||||||
if (argsLen < 2 || argsLen > 3) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "Fit":
|
|
||||||
case "FitB":
|
|
||||||
return argsLen === 0;
|
|
||||||
case "FitH":
|
|
||||||
case "FitBH":
|
|
||||||
case "FitV":
|
|
||||||
case "FitBV":
|
|
||||||
if (argsLen > 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "FitR":
|
|
||||||
if (argsLen !== 4) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
allowNull = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (const arg of args) {
|
|
||||||
if (!(typeof arg === "number" || (allowNull && arg === null))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetchDest(dest) {
|
function fetchDest(dest) {
|
||||||
if (dest instanceof Dict) {
|
if (dest instanceof Dict) {
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
_isValidExplicitDest,
|
||||||
AbortException,
|
AbortException,
|
||||||
AnnotationMode,
|
AnnotationMode,
|
||||||
assert,
|
assert,
|
||||||
@ -595,15 +596,20 @@ function getFactoryUrlProp(val) {
|
|||||||
throw new Error(`Invalid factory url: "${val}" must include trailing slash.`);
|
throw new Error(`Invalid factory url: "${val}" must include trailing slash.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isRefProxy(ref) {
|
const isRefProxy = v =>
|
||||||
return (
|
typeof v === "object" &&
|
||||||
typeof ref === "object" &&
|
Number.isInteger(v?.num) &&
|
||||||
Number.isInteger(ref?.num) &&
|
v.num >= 0 &&
|
||||||
ref.num >= 0 &&
|
Number.isInteger(v?.gen) &&
|
||||||
Number.isInteger(ref?.gen) &&
|
v.gen >= 0;
|
||||||
ref.gen >= 0
|
|
||||||
);
|
const isNameProxy = v => typeof v === "object" && typeof v?.name === "string";
|
||||||
}
|
|
||||||
|
const isValidExplicitDest = _isValidExplicitDest.bind(
|
||||||
|
null,
|
||||||
|
/* validRef = */ isRefProxy,
|
||||||
|
/* validName = */ isNameProxy
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} OnProgressParameters
|
* @typedef {Object} OnProgressParameters
|
||||||
@ -3485,6 +3491,7 @@ const build =
|
|||||||
export {
|
export {
|
||||||
build,
|
build,
|
||||||
getDocument,
|
getDocument,
|
||||||
|
isValidExplicitDest,
|
||||||
LoopbackPort,
|
LoopbackPort,
|
||||||
PDFDataRangeTransport,
|
PDFDataRangeTransport,
|
||||||
PDFDocumentLoadingTask,
|
PDFDocumentLoadingTask,
|
||||||
|
|||||||
@ -45,6 +45,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
build,
|
build,
|
||||||
getDocument,
|
getDocument,
|
||||||
|
isValidExplicitDest,
|
||||||
PDFDataRangeTransport,
|
PDFDataRangeTransport,
|
||||||
PDFWorker,
|
PDFWorker,
|
||||||
version,
|
version,
|
||||||
@ -117,6 +118,7 @@ export {
|
|||||||
InvalidPDFException,
|
InvalidPDFException,
|
||||||
isDataScheme,
|
isDataScheme,
|
||||||
isPdfFile,
|
isPdfFile,
|
||||||
|
isValidExplicitDest,
|
||||||
noContextMenu,
|
noContextMenu,
|
||||||
normalizeUnicode,
|
normalizeUnicode,
|
||||||
OPS,
|
OPS,
|
||||||
|
|||||||
@ -1080,6 +1080,54 @@ function getUuid() {
|
|||||||
|
|
||||||
const AnnotationPrefix = "pdfjs_internal_id_";
|
const AnnotationPrefix = "pdfjs_internal_id_";
|
||||||
|
|
||||||
|
function _isValidExplicitDest(validRef, validName, dest) {
|
||||||
|
if (!Array.isArray(dest) || dest.length < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const [page, zoom, ...args] = dest;
|
||||||
|
if (!validRef(page) && !Number.isInteger(page)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!validName(zoom)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const argsLen = args.length;
|
||||||
|
let allowNull = true;
|
||||||
|
switch (zoom.name) {
|
||||||
|
case "XYZ":
|
||||||
|
if (argsLen < 2 || argsLen > 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Fit":
|
||||||
|
case "FitB":
|
||||||
|
return argsLen === 0;
|
||||||
|
case "FitH":
|
||||||
|
case "FitBH":
|
||||||
|
case "FitV":
|
||||||
|
case "FitBV":
|
||||||
|
if (argsLen > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "FitR":
|
||||||
|
if (argsLen !== 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
allowNull = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (const arg of args) {
|
||||||
|
if (typeof arg === "number" || (allowNull && arg === null)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Remove this once `Uint8Array.prototype.toHex` is generally available.
|
// TODO: Remove this once `Uint8Array.prototype.toHex` is generally available.
|
||||||
function toHexUtil(arr) {
|
function toHexUtil(arr) {
|
||||||
if (Uint8Array.prototype.toHex) {
|
if (Uint8Array.prototype.toHex) {
|
||||||
@ -1119,6 +1167,7 @@ if (
|
|||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
_isValidExplicitDest,
|
||||||
AbortException,
|
AbortException,
|
||||||
AnnotationActionEventType,
|
AnnotationActionEventType,
|
||||||
AnnotationBorderStyleType,
|
AnnotationBorderStyleType,
|
||||||
|
|||||||
@ -36,6 +36,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
build,
|
build,
|
||||||
getDocument,
|
getDocument,
|
||||||
|
isValidExplicitDest,
|
||||||
PDFDataRangeTransport,
|
PDFDataRangeTransport,
|
||||||
PDFWorker,
|
PDFWorker,
|
||||||
version,
|
version,
|
||||||
@ -94,6 +95,7 @@ const expectedAPI = Object.freeze({
|
|||||||
InvalidPDFException,
|
InvalidPDFException,
|
||||||
isDataScheme,
|
isDataScheme,
|
||||||
isPdfFile,
|
isPdfFile,
|
||||||
|
isValidExplicitDest,
|
||||||
noContextMenu,
|
noContextMenu,
|
||||||
normalizeUnicode,
|
normalizeUnicode,
|
||||||
OPS,
|
OPS,
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
/** @typedef {import("./event_utils").EventBus} EventBus */
|
/** @typedef {import("./event_utils").EventBus} EventBus */
|
||||||
/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
|
/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
|
||||||
|
|
||||||
|
import { isValidExplicitDest } from "pdfjs-lib";
|
||||||
import { parseQueryString } from "./ui_utils.js";
|
import { parseQueryString } from "./ui_utils.js";
|
||||||
|
|
||||||
const DEFAULT_LINK_REL = "noopener noreferrer nofollow";
|
const DEFAULT_LINK_REL = "noopener noreferrer nofollow";
|
||||||
@ -415,7 +416,7 @@ class PDFLinkService {
|
|||||||
}
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|
||||||
if (typeof dest === "string" || PDFLinkService.#isValidExplicitDest(dest)) {
|
if (typeof dest === "string" || isValidExplicitDest(dest)) {
|
||||||
this.goToDestination(dest);
|
this.goToDestination(dest);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -486,60 +487,6 @@ class PDFLinkService {
|
|||||||
optionalContentConfig
|
optionalContentConfig
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static #isValidExplicitDest(dest) {
|
|
||||||
if (!Array.isArray(dest) || dest.length < 2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const [page, zoom, ...args] = dest;
|
|
||||||
if (
|
|
||||||
!(
|
|
||||||
typeof page === "object" &&
|
|
||||||
Number.isInteger(page?.num) &&
|
|
||||||
Number.isInteger(page?.gen)
|
|
||||||
) &&
|
|
||||||
!Number.isInteger(page)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(typeof zoom === "object" && typeof zoom?.name === "string")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const argsLen = args.length;
|
|
||||||
let allowNull = true;
|
|
||||||
switch (zoom.name) {
|
|
||||||
case "XYZ":
|
|
||||||
if (argsLen < 2 || argsLen > 3) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "Fit":
|
|
||||||
case "FitB":
|
|
||||||
return argsLen === 0;
|
|
||||||
case "FitH":
|
|
||||||
case "FitBH":
|
|
||||||
case "FitV":
|
|
||||||
case "FitBV":
|
|
||||||
if (argsLen > 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "FitR":
|
|
||||||
if (argsLen !== 4) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
allowNull = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (const arg of args) {
|
|
||||||
if (!(typeof arg === "number" || (allowNull && arg === null))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -39,6 +39,7 @@ const {
|
|||||||
InvalidPDFException,
|
InvalidPDFException,
|
||||||
isDataScheme,
|
isDataScheme,
|
||||||
isPdfFile,
|
isPdfFile,
|
||||||
|
isValidExplicitDest,
|
||||||
noContextMenu,
|
noContextMenu,
|
||||||
normalizeUnicode,
|
normalizeUnicode,
|
||||||
OPS,
|
OPS,
|
||||||
@ -90,6 +91,7 @@ export {
|
|||||||
InvalidPDFException,
|
InvalidPDFException,
|
||||||
isDataScheme,
|
isDataScheme,
|
||||||
isPdfFile,
|
isPdfFile,
|
||||||
|
isValidExplicitDest,
|
||||||
noContextMenu,
|
noContextMenu,
|
||||||
normalizeUnicode,
|
normalizeUnicode,
|
||||||
OPS,
|
OPS,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user