From 7861c8ede853f7a8fcc50b01011c2d3a0edfa4ba Mon Sep 17 00:00:00 2001 From: Michael Shanks Date: Tue, 11 Aug 2020 14:12:05 +0100 Subject: [PATCH] bindings... allowing unescaped urls, but not html tags --- packages/client/src/api/workflow/index.js | 4 ++-- .../client/src/render/prepareRenderComponent.js | 4 ++-- .../client/src/state/renderTemplateString.js | 17 +++++++++++++++++ packages/client/src/state/stateManager.js | 7 ++++--- 4 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 packages/client/src/state/renderTemplateString.js diff --git a/packages/client/src/api/workflow/index.js b/packages/client/src/api/workflow/index.js index f01a0fe62c..4a15d04772 100644 --- a/packages/client/src/api/workflow/index.js +++ b/packages/client/src/api/workflow/index.js @@ -1,4 +1,4 @@ -import mustache from "mustache" +import renderTemplateString from "../../state/renderTemplateString" import appStore from "../../state/store" import Orchestrator from "./orchestrator" import clientActions from "./actions" @@ -17,7 +17,7 @@ export const clientStrategy = ({ api }) => ({ if (typeof argValue !== "string") continue // Render the string with values from the workflow context and state - mappedArgs[arg] = mustache.render(argValue, { + mappedArgs[arg] = renderTemplateString(argValue, { context: this.context, state: appStore.get(), }) diff --git a/packages/client/src/render/prepareRenderComponent.js b/packages/client/src/render/prepareRenderComponent.js index 045de897f6..5d0d34d003 100644 --- a/packages/client/src/render/prepareRenderComponent.js +++ b/packages/client/src/render/prepareRenderComponent.js @@ -1,4 +1,4 @@ -import mustache from "mustache" +import renderTemplateString from "../state/renderTemplateString" import appStore from "../state/store" import hasBinding from "../state/hasBinding" @@ -46,7 +46,7 @@ export const prepareRenderComponent = ({ const toSet = {} for (let prop of storeBoundProps) { const propValue = initialProps._bb.props[prop] - toSet[prop] = mustache.render(propValue, state) + toSet[prop] = renderTemplateString(propValue, state) } thisNode.component.$set(toSet) } diff --git a/packages/client/src/state/renderTemplateString.js b/packages/client/src/state/renderTemplateString.js new file mode 100644 index 0000000000..c872bffc63 --- /dev/null +++ b/packages/client/src/state/renderTemplateString.js @@ -0,0 +1,17 @@ +import mustache from "mustache" + +// this is a much more liberal version of mustache's escape function +// ...just ignoring < and > to prevent tags from user input +// original version here https://github.com/janl/mustache.js/blob/4b7908f5c9fec469a11cfaed2f2bed23c84e1c5c/mustache.js#L78 + +const entityMap = { + "<": "<", + ">": ">", +} + +mustache.escape = text => + String(text).replace(/[&<>"'`=/]/g, function fromEntityMap(s) { + return entityMap[s] + }) + +export default mustache.render diff --git a/packages/client/src/state/stateManager.js b/packages/client/src/state/stateManager.js index 778d028305..fbfb39b7a4 100644 --- a/packages/client/src/state/stateManager.js +++ b/packages/client/src/state/stateManager.js @@ -4,7 +4,7 @@ import { EVENT_TYPE_MEMBER_NAME, } from "./eventHandlers" import { bbFactory } from "./bbComponentApi" -import mustache from "mustache" +import renderTemplateString from "./renderTemplateString" import appStore from "./store" import hasBinding from "./hasBinding" @@ -64,7 +64,7 @@ const _setup = ({ handlerTypes, getCurrentState, bb }) => node => { if (isBound) { const state = appStore.getState(node.contextStoreKey) - initialProps[propName] = mustache.render(propValue, state) + initialProps[propName] = renderTemplateString(propValue, state) if (!node.stateBound) { node.stateBound = true @@ -83,7 +83,8 @@ const _setup = ({ handlerTypes, getCurrentState, bb }) => node => { const resolvedParams = {} for (let paramName in handlerInfo.parameters) { const paramValue = handlerInfo.parameters[paramName] - resolvedParams[paramName] = () => mustache.render(paramValue, state) + resolvedParams[paramName] = () => + renderTemplateString(paramValue, state) } handlerInfo.parameters = resolvedParams