From 8eee92d41af2a737b8fb8d4ddd907f8b0b7f492e Mon Sep 17 00:00:00 2001 From: yokobond Date: Fri, 25 Jan 2019 10:31:33 +0900 Subject: [PATCH] Escape variable name in XML --- src/engine/variable.js | 3 +- test/unit/engine_variable.js | 110 +++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 test/unit/engine_variable.js diff --git a/src/engine/variable.js b/src/engine/variable.js index 1fb61d7b5..7617f9551 100644 --- a/src/engine/variable.js +++ b/src/engine/variable.js @@ -4,6 +4,7 @@ */ const uid = require('../util/uid'); +const xmlEscape = require('../util/xml-escape'); class Variable { /** @@ -36,7 +37,7 @@ class Variable { toXML (isLocal) { isLocal = (isLocal === true); return `${this.name}`; + }" iscloud="${this.isCloud}">${xmlEscape(this.name)}`; } /** diff --git a/test/unit/engine_variable.js b/test/unit/engine_variable.js new file mode 100644 index 000000000..f3212cc72 --- /dev/null +++ b/test/unit/engine_variable.js @@ -0,0 +1,110 @@ +const test = require('tap').test; +const Variable = require('../../src/engine/variable'); +const htmlparser = require('htmlparser2'); + +test('spec', t => { + t.type(typeof Variable.SCALAR_TYPE, typeof Variable.LIST_TYPE); + t.type(typeof Variable.SCALAR_TYPE, typeof Variable.BROADCAST_MESSAGE_TYPE); + + const varId = 'varId'; + const varName = 'varName'; + const varIsCloud = false; + let v = new Variable( + varId, + varName, + Variable.SCALAR_TYPE, + varIsCloud + ); + + t.type(Variable, 'function'); + t.type(v, 'object'); + t.ok(v instanceof Variable); + + t.equal(v.id, varId); + t.equal(v.name, varName); + t.equal(v.type, Variable.SCALAR_TYPE); + t.type(v.value, 'number'); + t.equal(v.isCloud, varIsCloud); + + t.type(v.toXML, 'function'); + + v = new Variable( + varId, + varName, + Variable.LIST_TYPE, + varIsCloud + ); + t.ok(Array.isArray(v.value)); + + v = new Variable( + varId, + varName, + Variable.BROADCAST_MESSAGE_TYPE, + varIsCloud + ); + t.equal(v.value, 'varName'); + + t.end(); +}); + +test('toXML', t => { + const varId = 'varId'; + const varName = 'varName'; + const varIsCloud = false; + const varIsLocal = false; + const v = new Variable( + varId, + varName, + Variable.SCALAR_TYPE, + varIsCloud + ); + + const parser = new htmlparser.Parser({ + onopentag: function (name, attribs){ + if (name === 'variable'){ + t.equal(attribs.type, Variable.SCALAR_TYPE); + t.equal(attribs.id, varId); + t.equal(attribs.iscloud, varIsCloud.toString()); + t.equal(attribs.islocal, varIsLocal.toString()); + } + }, + ontext: function (text){ + t.equal(text, varName); + } + }, {decodeEntities: false}); + parser.write(v.toXML(false)); + parser.end(); + + t.end(); +}); + +test('escape variable name for XML', t => { + const varId = 'varId'; + const varName = '<>&\'"'; + const varIsCloud = false; + const varIsLocal = false; + const v = new Variable( + varId, + varName, + Variable.SCALAR_TYPE, + varIsCloud + ); + + const parser = new htmlparser.Parser({ + onopentag: function (name, attribs){ + if (name === 'variable'){ + t.equal(attribs.type, Variable.SCALAR_TYPE); + t.equal(attribs.id, varId); + t.equal(attribs.iscloud, varIsCloud.toString()); + t.equal(attribs.islocal, varIsLocal.toString()); + } + }, + ontext: function (text){ + t.equal(text, '<>&'"'); + } + }, {decodeEntities: false}); + parser.write(v.toXML(false)); + parser.end(); + + t.end(); +});