From e0d23e3c5d9feb1fc4ff88fa923bb6d1fa1aae18 Mon Sep 17 00:00:00 2001 From: Chad Weider Date: Wed, 18 Jan 2012 03:58:13 -0800 Subject: [PATCH] Create and use the Security module. Use it to replace code on the client and server side. --- node/utils/ExportHtml.js | 25 +++---------------- node/utils/tar.json | 3 +++ static/js/ace2_common.js | 10 ++------ static/js/domline.js | 32 +++++------------------- static/js/pad_utils.js | 15 ++++------- static/js/security.js | 54 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 74 insertions(+), 65 deletions(-) create mode 100644 static/js/security.js diff --git a/node/utils/ExportHtml.js b/node/utils/ExportHtml.js index 7296012fc..afeafd3a9 100644 --- a/node/utils/ExportHtml.js +++ b/node/utils/ExportHtml.js @@ -19,6 +19,7 @@ var async = require("async"); var Changeset = CommonCode.require("/Changeset"); var padManager = require("../db/PadManager"); var ERR = require("async-stacktrace"); +var Security = CommonCode.require('/security'); function getPadPlainText(pad, revNum) { @@ -270,7 +271,7 @@ function getHTMLFromAtext(pad, atext) //from but they break the abiword parser and are completly useless s = s.replace(String.fromCharCode(12), ""); - assem.append(_escapeHTML(s)); + assem.append(_encodeWhitespace(Security.escapeHTML(s))); } // end iteration over spans in line var tags2close = []; @@ -293,7 +294,7 @@ function getHTMLFromAtext(pad, atext) var url = urlData[1]; var urlLength = url.length; processNextChars(startIndex - idx); - assem.append(''); + assem.append(''); processNextChars(urlLength); assem.append(''); }); @@ -494,25 +495,7 @@ exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback) }); } -function _escapeHTML(s) -{ - var re = /[&"<>]/g; - if (!re.MAP) - { - // persisted across function calls! - re.MAP = { - '&': '&', - '"': '"', - '<': '<', - '>': '>' - }; - } - - s = s.replace(re, function (c) - { - return re.MAP[c]; - }); - +function _encodeWhitespace(s) { return s.replace(/[^\x21-\x7E\s\t\n\r]/g, function(c) { return "&#" +c.charCodeAt(0) + ";" diff --git a/node/utils/tar.json b/node/utils/tar.json index 9bab03c07..e922dddeb 100644 --- a/node/utils/tar.json +++ b/node/utils/tar.json @@ -1,6 +1,7 @@ { "pad.js": [ "jquery.js" + , "security.js" , "pad.js" , "ace2_common.js" , "pad_utils.js" @@ -25,6 +26,7 @@ ] , "timeslider.js": [ "jquery.js" + , "security.js" , "plugins.js" , "undo-xpopup.js" , "json2.js" @@ -53,6 +55,7 @@ "ace2_common.js" , "AttributePoolFactory.js" , "Changeset.js" + , "security.js" , "skiplist.js" , "virtual_lines.js" , "cssmanager.js" diff --git a/static/js/ace2_common.js b/static/js/ace2_common.js index 1ce7810aa..b4c72a92f 100644 --- a/static/js/ace2_common.js +++ b/static/js/ace2_common.js @@ -20,6 +20,7 @@ * limitations under the License. */ +var Security = require('/security'); function isNodeText(node) { @@ -137,14 +138,7 @@ function binarySearchInfinite(expectedLength, func) function htmlPrettyEscape(str) { - return str.replace(/[&"<>]/g, function (c) { - return { - '&': '&', - '"': '"', - '<': '<', - '>': '>' - }[c] || c; - }).replace(/\r?\n/g, '\\n'); + return Security.escapeHTML(str).replace(/\r?\n/g, '\\n'); } exports.isNodeText = isNodeText; diff --git a/static/js/domline.js b/static/js/domline.js index 8d8c2ea9e..15528bf7a 100644 --- a/static/js/domline.js +++ b/static/js/domline.js @@ -26,6 +26,7 @@ // requires: plugins // requires: undefined +var Security = require('/security'); var plugins = require('/plugins').plugins; var map = require('/ace2_common').map; @@ -103,17 +104,17 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument) if (listType) { listType = listType[1]; - start = start?'start="'+start[1]+'"':''; + start = start?'start="'+Security.escapeHTMLAttribute(start[1])+'"':''; if (listType) { if(listType.indexOf("number") < 0) { - preHtml = '