UNPKG

twing

Version:

First-class Twig engine for Node.js

94 lines (93 loc) 3.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createSandboxNodeVisitor = void 0; const node_1 = require("../node"); const check_security_1 = require("../node/check-security"); const check_to_string_1 = require("../node/check-to-string"); const node_visitor_1 = require("../node-visitor"); const createSandboxNodeVisitor = () => { let tags; let filters; let functions; let shouldWrap = true; const enterNode = (node) => { if (node.type === "template") { tags = new Map(); filters = new Map(); functions = new Map(); return node; } else { // look for tags const { tag } = node; if (tag && !(tags.has(tag))) { tags.set(tag, node); } // look for filters if (node.type === "filter") { const { operatorName } = node.attributes; if (!filters.has(operatorName)) { filters.set(operatorName, node); } } // look for functions if (node.type === "function") { const { operatorName } = node.attributes; if (!functions.has(operatorName)) { functions.set(operatorName, node); } } // the .. operator is equivalent to the range() function if (node.type === "range" && !(functions.has('range'))) { functions.set('range', node); } if (node.type === "print") { shouldWrap = true; wrapNode(node, "expression"); } if (node.type === "set") { shouldWrap = true; } if (shouldWrap) { if (node.type === "concatenate") { wrapNode(node, "left"); wrapNode(node, "right"); } if (node.type === "filter") { wrapNode(node, "operand"); wrapArrayNode(node, "arguments"); } if (node.type === "function") { wrapArrayNode(node, "arguments"); } if (node.type === "escape") { wrapNode(node, "body"); } } } return node; }; const leaveNode = (node) => { if (node.type === "template") { node.children.securityCheck = (0, check_security_1.createCheckSecurityNode)(filters, tags, functions, node.line, node.column); } else if (node.type === "print" || node.type === "set") { shouldWrap = false; } return node; }; const wrapNode = (node, name) => { const expression = node.children[name]; if (expression.type === "name" || expression.type === "attribute_accessor") { node.children[name] = (0, check_to_string_1.createCheckToStringNode)(expression, expression.line, expression.column); } }; const wrapArrayNode = (node, name) => { const args = node.children[name]; // todo: check with TS team with we have to cast children as any for (const [name] of (0, node_1.getChildren)(args)) { wrapNode(args, name); } }; return (0, node_visitor_1.createNodeVisitor)(enterNode, leaveNode); }; exports.createSandboxNodeVisitor = createSandboxNodeVisitor;