From ab41f93ef43bdaa3e7d2683a86d02b26270eba4e Mon Sep 17 00:00:00 2001 From: "C. Scott Ananian" Date: Thu, 18 Apr 2013 19:00:21 -0400 Subject: [PATCH] Only invoke String.replace() once during decode. (fixes gh #8) --- index.js | 14 ++++++++++---- test/test.js | 29 ++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 9f09edb3..b2a74e92 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ -var re_hex = /&#x[\da-f]+;?/gi, +var re_hex = /&#[xX][\da-fA-F]+;?/g, re_strictHex = /&#x[\da-f]+;/gi, re_charCode = /&#\d+;?/g, re_strictCharCode = /&#\d+;/g, @@ -16,9 +16,17 @@ var fetch = function(filename, inherits){ if(inherits) for(var name in inherits) obj[name] = inherits[name]; var re = Object.keys(obj).sort().join("|").replace(/(\w+)\|\1;/g, "$1;?"); + // add regex for hex and char codes + re += '|' + re_hex.source.substr(1) + '|' + re_charCode.source.substr(1); return { func: function(name){ + if (name.charAt(1) === '#') { + if (name.charAt(2).toLowerCase() === 'x') { + return hex_func(name); + } + return num_func(name); + } return obj[name.substr(1)]; }, re: new RegExp("&(?:" +re +")", "g"), @@ -62,9 +70,7 @@ modes.forEach(function(name){ module.exports["decode" +name] = function(data){ return data - .replace(regex, func) - .replace(re_hex, hex_func) - .replace(re_charCode, num_func); + .replace(regex, func); }; var reverse = getReverse(obj.obj), diff --git a/test/test.js b/test/test.js index f3b0bd98..c73d0ed6 100644 --- a/test/test.js +++ b/test/test.js @@ -1,7 +1,7 @@ var assert = require('assert'); var entities = require('../'); -describe("Encode/decode test", function() { +describe("Encode->decode test", function() { var testcases = [ { input: "asdf & ÿ ü '", xml: "asdf & ÿ ü '", @@ -36,3 +36,30 @@ describe("Encode/decode test", function() { }); }); }); + +describe("Decode test", function() { + var testcases = [ + { input: '&', output: '&' }, + { input: '&', output: '&' }, + { input: '&', output: '&' }, + { input: '&', output: '&' }, + { input: '&', output: '&' }, + { input: '&', output: '&' }, + { input: '&', output: '&' }, + { input: ':', output: ':' }, + { input: ':', output: ':' }, + { input: ':', output: ':' }, + { input: ':', output: ':' } + ]; + testcases.forEach(function(tc) { + it('should XML decode '+tc.input, function() { + assert.equal(entities.decodeXML(tc.input), tc.output); + }); + it('should HTML4 decode '+tc.input, function() { + assert.equal(entities.decodeHTML4(tc.input), tc.output); + }); + it('should HTML5 decode '+tc.input, function() { + assert.equal(entities.decodeHTML5(tc.input), tc.output); + }); + }); +});