#847 Removing </> in text

This commit is contained in:
Knut Sveidqvist
2019-07-13 22:50:53 -07:00
parent 31a2b2ca3c
commit 31576f8f55
6 changed files with 82 additions and 37 deletions

6
src/config.js Normal file
View File

@@ -0,0 +1,6 @@
let config
export const setConfig = conf => {
config = conf
}
export const getConfig = () => config

View File

@@ -2,7 +2,9 @@ import * as d3 from 'd3'
import { logger } from '../../logger' import { logger } from '../../logger'
import utils from '../../utils' import utils from '../../utils'
import { getConfig } from '../../config'
const config = getConfig()
let vertices = {} let vertices = {}
let edges = [] let edges = []
let classes = [] let classes = []
@@ -13,6 +15,16 @@ let subCount = 0
let direction let direction
// Functions to be run after graph rendering // Functions to be run after graph rendering
let funs = [] let funs = []
const sanitize = text => {
let txt = text
txt = txt.replace(/<br>/g, '#br#')
txt = txt.replace(/<br\S*\/>/g, '#br#')
txt = txt.replace(/</g, '&lt;').replace(/>/g, '&gt;')
txt = txt.replace(/#br#/g, '<br/>')
return txt
}
/** /**
* Function called by parser when a node definition has been found * Function called by parser when a node definition has been found
* @param id * @param id
@@ -35,7 +47,7 @@ export const addVertex = function (id, text, type, style, classes) {
vertices[id] = { id: id, styles: [], classes: [] } vertices[id] = { id: id, styles: [], classes: [] }
} }
if (typeof text !== 'undefined') { if (typeof text !== 'undefined') {
txt = text.trim() txt = sanitize(text.trim())
// strip quotes if string starts and exnds with a quote // strip quotes if string starts and exnds with a quote
if (txt[0] === '"' && txt[txt.length - 1] === '"') { if (txt[0] === '"' && txt[txt.length - 1] === '"') {
@@ -76,7 +88,7 @@ export const addLink = function (start, end, type, linktext) {
linktext = type.text linktext = type.text
if (typeof linktext !== 'undefined') { if (typeof linktext !== 'undefined') {
edge.text = linktext.trim() edge.text = sanitize(linktext.trim())
// strip quotes if string starts and exnds with a quote // strip quotes if string starts and exnds with a quote
if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') { if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') {
@@ -172,6 +184,9 @@ const setTooltip = function (ids, tooltip) {
} }
const setClickFun = function (id, functionName) { const setClickFun = function (id, functionName) {
if (config.strictSecurity) {
return
}
if (typeof functionName === 'undefined') { if (typeof functionName === 'undefined') {
return return
} }
@@ -335,6 +350,7 @@ export const addSubGraph = function (id, list, title) {
id = id || ('subGraph' + subCount) id = id || ('subGraph' + subCount)
title = title || '' title = title || ''
title = sanitize(title)
subCount = subCount + 1 subCount = subCount + 1
const subGraph = { id: id, nodes: nodeList, title: title.trim(), classes: [] } const subGraph = { id: id, nodes: nodeList, title: title.trim(), classes: [] }
subGraphs.push(subGraph) subGraphs.push(subGraph)

View File

@@ -1333,7 +1333,7 @@ describe('when parsing ', function () {
const edges = flow.parser.yy.getEdges() const edges = flow.parser.yy.getEdges()
expect(vert['C'].type).toBe('round') expect(vert['C'].type).toBe('round')
expect(vert['C'].text).toBe('Chimpansen hoppar åäö <br> - ÅÄÖ') expect(vert['C'].text).toBe('Chimpansen hoppar åäö <br/> - ÅÄÖ')
}) })
// xit('it should handle åäö, minus and space and br',function(){ // xit('it should handle åäö, minus and space and br',function(){
// const res = flow.parser.parse('graph TD; A[Object&#40;foo,bar&#41;]-->B(Thing);'); // const res = flow.parser.parse('graph TD; A[Object&#40;foo,bar&#41;]-->B(Thing);');
@@ -1460,7 +1460,7 @@ describe('when parsing ', function () {
expect(edges.length).toBe(0) expect(edges.length).toBe(0)
expect(vert['a'].type).toBe('diamond') expect(vert['a'].type).toBe('diamond')
expect(vert['a'].text).toBe('A <br> end') expect(vert['a'].text).toBe('A <br/> end')
}) })
it('should handle a single round node with html in it', function () { it('should handle a single round node with html in it', function () {
// Silly but syntactically correct // Silly but syntactically correct
@@ -1471,7 +1471,7 @@ describe('when parsing ', function () {
expect(edges.length).toBe(0) expect(edges.length).toBe(0)
expect(vert['a'].type).toBe('round') expect(vert['a'].type).toBe('round')
expect(vert['a'].text).toBe('A <br> end') expect(vert['a'].text).toBe('A <br/> end')
}) })
it('should handle a single node with alphanumerics starting on a char', function () { it('should handle a single node with alphanumerics starting on a char', function () {
// Silly but syntactically correct // Silly but syntactically correct
@@ -1573,7 +1573,7 @@ describe('when parsing ', function () {
}) })
describe('special characters should be be handled.', 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 res = flow.parser.parse('graph TD;A(' + char + ')-->B;')
const vert = flow.parser.yy.getVertices() const vert = flow.parser.yy.getVertices()
@@ -1581,7 +1581,11 @@ describe('when parsing ', function () {
expect(vert['A'].id).toBe('A') expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B') 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 () { 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 () { it('it should be able to parse a \'<\'', function () {
charTest('<') charTest('<','&lt;')
}) })
it('it should be able to parse a \'>\'', function () { it('it should be able to parse a \'>\'', function () {
charTest('>') charTest('>','&gt;')
}) })
it('it should be able to parse a \'=\'', function () { it('it should be able to parse a \'=\'', function () {
charTest('=') charTest('=')
}) })
it('it should be able to parse a \'&\'', function () {
charTest('&')
})
}) })
it('should be possible to declare a class', function () { it('should be possible to declare a class', function () {

View File

@@ -1,7 +1,9 @@
import moment from 'moment-mini' import moment from 'moment-mini'
import { logger } from '../../logger' import { logger } from '../../logger'
import * as d3 from 'd3' import * as d3 from 'd3'
import { getConfig } from '../../config'
const config = getConfig()
let dateFormat = '' let dateFormat = ''
let axisFormat = '' let axisFormat = ''
let excludes = [] let excludes = []
@@ -62,10 +64,12 @@ export const getExcludes = function () {
} }
export const setTitle = function (txt) { export const setTitle = function (txt) {
console.log('Setting title ', txt)
title = txt title = txt
} }
export const getTitle = function () { export const getTitle = function () {
console.log('Title is ', title)
return title return title
} }
@@ -451,6 +455,9 @@ export const setClass = function (ids, className) {
} }
const setClickFun = function (id, functionName, functionArgs) { const setClickFun = function (id, functionName, functionArgs) {
if (config.strictSecurity) {
return
}
if (typeof functionName === 'undefined') { if (typeof functionName === 'undefined') {
return return
} }

View File

@@ -71,7 +71,7 @@
recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) 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 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 () { }, var parser = {trace: function trace () { },
yy: {}, yy: {},
@@ -191,15 +191,18 @@ parse: function parse(input) {
vstack.length = vstack.length - n; vstack.length = vstack.length - n;
lstack.length = lstack.length - n; lstack.length = lstack.length - n;
} }
_token_stack: function lex() {
var lex = function () {
var token; var token;
token = lexer.lex() || EOF; token = tstack.pop() || lexer.lex() || EOF;
if (typeof token !== 'number') { if (typeof token !== 'number') {
if (token instanceof Array) {
tstack = token;
token = tstack.pop();
}
token = self.symbols_[token] || token; token = self.symbols_[token] || token;
} }
return token; return token;
}; }
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
while (true) { while (true) {
state = stack[stack.length - 1]; state = stack[stack.length - 1];
@@ -211,27 +214,27 @@ parse: function parse(input) {
} }
action = table[state] && table[state][symbol]; action = table[state] && table[state][symbol];
} }
if (typeof action === 'undefined' || !action.length || !action[0]) { if (typeof action === 'undefined' || !action.length || !action[0]) {
var errStr = ''; var errStr = '';
expected = []; expected = [];
for (p in table[state]) { for (p in table[state]) {
if (this.terminals_[p] && p > TERROR) { if (this.terminals_[p] && p > TERROR) {
expected.push('\'' + this.terminals_[p] + '\''); 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) { if (action[0] instanceof Array && action.length > 1) {
throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); 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') { if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
exports.parser = gantt; exports.parser = parser;
exports.Parser = gantt.Parser; exports.Parser = parser.Parser;
exports.parse = function () { return gantt.parse.apply(gantt, arguments); }; exports.parse = function () { return parser.parse.apply(parser, arguments); };
exports.main = function commonjsMain (args) { exports.main = function commonjsMain (args) {
if (!args[1]) { if (!args[1]) {
console.log('Usage: '+args[0]+' FILE'); console.log('Usage: '+args[0]+' FILE');

View File

@@ -14,7 +14,7 @@
import * as d3 from 'd3' import * as d3 from 'd3'
import scope from 'scope-css' import scope from 'scope-css'
import pkg from '../package.json' import pkg from '../package.json'
import { setConfig } from './config'
import { logger, setLogLevel } from './logger' import { logger, setLogLevel } from './logger'
import utils from './utils' import utils from './utils'
import flowRenderer from './diagrams/flowchart/flowRenderer' import flowRenderer from './diagrams/flowchart/flowRenderer'
@@ -77,6 +77,11 @@ const config = {
*/ */
logLevel: 5, 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 * **startOnLoad** - This options controls whether or mermaid starts when the page loads
*/ */
@@ -240,6 +245,7 @@ const config = {
} }
setLogLevel(config.logLevel) setLogLevel(config.logLevel)
setConfig(config)
function parse (text) { function parse (text) {
const graphType = utils.detectType(text) const graphType = utils.detectType(text)