From 31576f8f55e6b9db1924a3ebfcf3cfea2ea01abb Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Sat, 13 Jul 2019 22:50:53 -0700 Subject: [PATCH] #847 Removing in text --- src/config.js | 6 +++ src/diagrams/flowchart/flowDb.js | 20 +++++++- src/diagrams/flowchart/parser/flow.spec.js | 21 +++++--- src/diagrams/gantt/ganttDb.js | 7 +++ src/diagrams/gantt/parser/gantt.js | 57 ++++++++++++---------- src/mermaidAPI.js | 8 ++- 6 files changed, 82 insertions(+), 37 deletions(-) create mode 100644 src/config.js diff --git a/src/config.js b/src/config.js new file mode 100644 index 000000000..edd94edac --- /dev/null +++ b/src/config.js @@ -0,0 +1,6 @@ +let config + +export const setConfig = conf => { + config = conf +} +export const getConfig = () => config diff --git a/src/diagrams/flowchart/flowDb.js b/src/diagrams/flowchart/flowDb.js index 5f236ce26..3ac27f3c8 100644 --- a/src/diagrams/flowchart/flowDb.js +++ b/src/diagrams/flowchart/flowDb.js @@ -2,7 +2,9 @@ import * as d3 from 'd3' import { logger } from '../../logger' import utils from '../../utils' +import { getConfig } from '../../config' +const config = getConfig() let vertices = {} let edges = [] let classes = [] @@ -13,6 +15,16 @@ let subCount = 0 let direction // Functions to be run after graph rendering let funs = [] + +const sanitize = text => { + let txt = text + txt = txt.replace(/
/g, '#br#') + txt = txt.replace(//g, '#br#') + txt = txt.replace(//g, '>') + txt = txt.replace(/#br#/g, '
') + return txt +} + /** * Function called by parser when a node definition has been found * @param id @@ -35,7 +47,7 @@ export const addVertex = function (id, text, type, style, classes) { vertices[id] = { id: id, styles: [], classes: [] } } if (typeof text !== 'undefined') { - txt = text.trim() + txt = sanitize(text.trim()) // strip quotes if string starts and exnds with a quote if (txt[0] === '"' && txt[txt.length - 1] === '"') { @@ -76,7 +88,7 @@ export const addLink = function (start, end, type, linktext) { linktext = type.text if (typeof linktext !== 'undefined') { - edge.text = linktext.trim() + edge.text = sanitize(linktext.trim()) // strip quotes if string starts and exnds with a quote if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') { @@ -172,6 +184,9 @@ const setTooltip = function (ids, tooltip) { } const setClickFun = function (id, functionName) { + if (config.strictSecurity) { + return + } if (typeof functionName === 'undefined') { return } @@ -335,6 +350,7 @@ export const addSubGraph = function (id, list, title) { id = id || ('subGraph' + subCount) title = title || '' + title = sanitize(title) subCount = subCount + 1 const subGraph = { id: id, nodes: nodeList, title: title.trim(), classes: [] } subGraphs.push(subGraph) diff --git a/src/diagrams/flowchart/parser/flow.spec.js b/src/diagrams/flowchart/parser/flow.spec.js index 31ed24a6e..d352a9205 100644 --- a/src/diagrams/flowchart/parser/flow.spec.js +++ b/src/diagrams/flowchart/parser/flow.spec.js @@ -1333,7 +1333,7 @@ describe('when parsing ', function () { const edges = flow.parser.yy.getEdges() expect(vert['C'].type).toBe('round') - expect(vert['C'].text).toBe('Chimpansen hoppar åäö
- ÅÄÖ') + expect(vert['C'].text).toBe('Chimpansen hoppar åäö
- ÅÄÖ') }) // xit('it should handle åäö, minus and space and br',function(){ // const res = flow.parser.parse('graph TD; A[Object(foo,bar)]-->B(Thing);'); @@ -1460,7 +1460,7 @@ describe('when parsing ', function () { expect(edges.length).toBe(0) expect(vert['a'].type).toBe('diamond') - expect(vert['a'].text).toBe('A
end') + expect(vert['a'].text).toBe('A
end') }) it('should handle a single round node with html in it', function () { // Silly but syntactically correct @@ -1471,7 +1471,7 @@ describe('when parsing ', function () { expect(edges.length).toBe(0) expect(vert['a'].type).toBe('round') - expect(vert['a'].text).toBe('A
end') + expect(vert['a'].text).toBe('A
end') }) it('should handle a single node with alphanumerics starting on a char', function () { // Silly but syntactically correct @@ -1573,7 +1573,7 @@ describe('when parsing ', function () { }) describe('special characters should be be handled.', function () { - const charTest = function (char) { + const charTest = function (char, result) { const res = flow.parser.parse('graph TD;A(' + char + ')-->B;') const vert = flow.parser.yy.getVertices() @@ -1581,7 +1581,11 @@ describe('when parsing ', function () { expect(vert['A'].id).toBe('A') expect(vert['B'].id).toBe('B') - expect(vert['A'].text).toBe(char) + if(result){ + expect(vert['A'].text).toBe(result) + }else{ + expect(vert['A'].text).toBe(char) + } } it('it should be able to parse a \'.\'', function () { @@ -1614,16 +1618,19 @@ describe('when parsing ', function () { }) it('it should be able to parse a \'<\'', function () { - charTest('<') + charTest('<','<') }) it('it should be able to parse a \'>\'', function () { - charTest('>') + charTest('>','>') }) it('it should be able to parse a \'=\'', function () { charTest('=') }) + it('it should be able to parse a \'&\'', function () { + charTest('&') + }) }) it('should be possible to declare a class', function () { diff --git a/src/diagrams/gantt/ganttDb.js b/src/diagrams/gantt/ganttDb.js index c2a9f82b5..a6dadd4d7 100644 --- a/src/diagrams/gantt/ganttDb.js +++ b/src/diagrams/gantt/ganttDb.js @@ -1,7 +1,9 @@ import moment from 'moment-mini' import { logger } from '../../logger' import * as d3 from 'd3' +import { getConfig } from '../../config' +const config = getConfig() let dateFormat = '' let axisFormat = '' let excludes = [] @@ -62,10 +64,12 @@ export const getExcludes = function () { } export const setTitle = function (txt) { + console.log('Setting title ', txt) title = txt } export const getTitle = function () { + console.log('Title is ', title) return title } @@ -451,6 +455,9 @@ export const setClass = function (ids, className) { } const setClickFun = function (id, functionName, functionArgs) { + if (config.strictSecurity) { + return + } if (typeof functionName === 'undefined') { return } diff --git a/src/diagrams/gantt/parser/gantt.js b/src/diagrams/gantt/parser/gantt.js index 44fcbecb6..6f2d5f4db 100644 --- a/src/diagrams/gantt/parser/gantt.js +++ b/src/diagrams/gantt/parser/gantt.js @@ -71,7 +71,7 @@ recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) } */ -var gantt = (function(){ +var parser = (function(){ var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[6,8,10,11,12,13,14,15,16,18,20],$V1=[1,9],$V2=[1,10],$V3=[1,11],$V4=[1,12],$V5=[1,13],$V6=[1,14],$V7=[1,16],$V8=[1,17]; var parser = {trace: function trace () { }, yy: {}, @@ -191,15 +191,18 @@ parse: function parse(input) { vstack.length = vstack.length - n; lstack.length = lstack.length - n; } - _token_stack: - var lex = function () { + function lex() { var token; - token = lexer.lex() || EOF; + token = tstack.pop() || lexer.lex() || EOF; if (typeof token !== 'number') { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } token = self.symbols_[token] || token; } return token; - }; + } var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; while (true) { state = stack[stack.length - 1]; @@ -211,27 +214,27 @@ parse: function parse(input) { } action = table[state] && table[state][symbol]; } - if (typeof action === 'undefined' || !action.length || !action[0]) { - var errStr = ''; - expected = []; - for (p in table[state]) { - if (this.terminals_[p] && p > TERROR) { - expected.push('\'' + this.terminals_[p] + '\''); - } + if (typeof action === 'undefined' || !action.length || !action[0]) { + var errStr = ''; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push('\'' + this.terminals_[p] + '\''); } - if (lexer.showPosition) { - errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; - } else { - errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); - } - this.parseError(errStr, { - text: lexer.match, - token: this.terminals_[symbol] || symbol, - line: lexer.yylineno, - loc: yyloc, - expected: expected - }); } + if (lexer.showPosition) { + errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; + } else { + errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); + } + this.parseError(errStr, { + text: lexer.match, + token: this.terminals_[symbol] || symbol, + line: lexer.yylineno, + loc: yyloc, + expected: expected + }); + } if (action[0] instanceof Array && action.length > 1) { throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); } @@ -703,9 +706,9 @@ return new Parser; if (typeof require !== 'undefined' && typeof exports !== 'undefined') { -exports.parser = gantt; -exports.Parser = gantt.Parser; -exports.parse = function () { return gantt.parse.apply(gantt, arguments); }; +exports.parser = parser; +exports.Parser = parser.Parser; +exports.parse = function () { return parser.parse.apply(parser, arguments); }; exports.main = function commonjsMain (args) { if (!args[1]) { console.log('Usage: '+args[0]+' FILE'); diff --git a/src/mermaidAPI.js b/src/mermaidAPI.js index c737f451c..1beba6b06 100644 --- a/src/mermaidAPI.js +++ b/src/mermaidAPI.js @@ -14,7 +14,7 @@ import * as d3 from 'd3' import scope from 'scope-css' import pkg from '../package.json' - +import { setConfig } from './config' import { logger, setLogLevel } from './logger' import utils from './utils' import flowRenderer from './diagrams/flowchart/flowRenderer' @@ -77,6 +77,11 @@ const config = { */ logLevel: 5, + /** + * **strictSecurity** A boolean flag setting the level of trust to be used on the parsed diagrams. When set to true the click functionality is disabled. + */ + strictSecurity: false, + /** * **startOnLoad** - This options controls whether or mermaid starts when the page loads */ @@ -240,6 +245,7 @@ const config = { } setLogLevel(config.logLevel) +setConfig(config) function parse (text) { const graphType = utils.detectType(text)