JS -- Actions must be evaluated in global scope

* All the public properties of doc are injected into globalThis, in order to make them available through `this`
 * Put event in the global scope too.
This commit is contained in:
Calixte Denizet 2020-12-16 14:04:22 +01:00
parent c366390f6b
commit 167ff1a7fc
7 changed files with 178 additions and 53 deletions

View file

@ -77,6 +77,8 @@ class Field extends PDFObject {
this._fillColor = data.fillColor || ["T"];
this._strokeColor = data.strokeColor || ["G", 0];
this._textColor = data.textColor || ["G", 0];
this._globalEval = data.globalEval;
}
get fillColor() {
@ -117,20 +119,6 @@ class Field extends PDFObject {
this._valueAsString = val ? val.toString() : "";
}
_getFunction(code, actionName) {
try {
// This eval is running in a sandbox so it's safe to use Function
// eslint-disable-next-line no-new-func
return Function("event", `with (this) {${code}}`).bind(this._document);
} catch (error) {
const value =
`"${error.toString()}" for action ` +
`"${actionName}" in object ${this._id}.`;
this._send({ command: "error", value });
}
return null;
}
setAction(cTrigger, cScript) {
if (typeof cTrigger !== "string" || typeof cScript !== "string") {
return;
@ -138,10 +126,7 @@ class Field extends PDFObject {
if (!(cTrigger in this._actions)) {
this._actions[cTrigger] = [];
}
const fun = this._getFunction(cScript, cTrigger);
if (fun) {
this._actions[cTrigger].push(fun);
}
this._actions[cTrigger].push(cScript);
}
setFocus() {
@ -152,12 +137,7 @@ class Field extends PDFObject {
const actionsMap = new Map();
if (actions) {
for (const [eventType, actionsForEvent] of Object.entries(actions)) {
const functions = actionsForEvent
.map(action => this._getFunction(action, eventType))
.filter(fun => !!fun);
if (functions.length > 0) {
actionsMap.set(eventType, functions);
}
actionsMap.set(eventType, actionsForEvent);
}
}
return actionsMap;
@ -176,7 +156,8 @@ class Field extends PDFObject {
const actions = this._actions.get(eventName);
try {
for (const action of actions) {
action(event);
// Action evaluation must happen in the global scope
this._globalEval(action);
}
} catch (error) {
event.rc = false;