From 3a534a965f0f7bfc6c287a376d2a40a7abcbdeb5 Mon Sep 17 00:00:00 2001 From: mde Date: Mon, 5 Dec 2016 11:42:40 -0800 Subject: [PATCH] Refactored opts-in-data passing, cleaner util method --- lib/ejs.js | 48 +++++++++++------------------------------------- lib/utils.js | 25 ++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/lib/ejs.js b/lib/ejs.js index b243fa76..02f56035 100644 --- a/lib/ejs.js +++ b/lib/ejs.js @@ -54,15 +54,8 @@ var _DEFAULT_DELIMITER = '%'; var _DEFAULT_LOCALS_NAME = 'locals'; var _NAME = 'ejs'; var _REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)'; -var _OPTS = [ 'cache', 'filename', 'delimiter', 'scope', 'context', - 'debug', 'compileDebug', 'client', '_with', 'root', 'rmWhitespace', - 'strict', 'localsName']; -var _OPTS_IN_DATA_BLACKLIST = { - cache: true, - filename: true, - root: true, - localsName: true - }; +var _OPTS = ['delimiter', 'scope', 'context', 'debug', 'compileDebug', + 'client', '_with', 'rmWhitespace', 'strict']; var _BOM = /^\uFEFF/; /** @@ -260,31 +253,6 @@ function rethrow(err, str, filename, lineno){ throw err; } -/** - * Copy properties in data object that are recognized as options to an - * options object. - * - * This is used for compatibility with earlier versions of EJS and Express.js. - * - * @memberof module:ejs-internal - * @param {Object} data data object - * @param {Options} opts options object - * @static - */ - -function cpOptsInData(data, opts) { - _OPTS.forEach(function (p) { - if (typeof data[p] != 'undefined') { - // Disallow passing potentially dangerous opts in the data - // These opts should not be settable via a `render` call - if (_OPTS_IN_DATA_BLACKLIST[p]) { - return; - } - opts[p] = data[p]; - } - }); -} - function stripSemi(str) { return str.replace(/;(\s*$)/, '$1'); } @@ -341,7 +309,7 @@ exports.render = function (template, d, o) { // No options object -- if there are optiony names // in the data, copy them to options if (arguments.length == 2) { - cpOptsInData(data, opts); + utils.shallowCopyFromList(opts, data, _OPTS); } return handleCache(opts, template)(data); @@ -366,21 +334,27 @@ exports.renderFile = function () { var cb = args.pop(); var data = args.shift() || {}; var opts = args.pop() || {}; + var optsKeys =_OPTS.slice(); var result; // Don't pollute passed in opts obj with new vals opts = utils.shallowCopy({}, opts); + // We don't allow 'cache' option to be passed in the data obj + // for the normal `render` call, but this is where Expres puts it + // so we make an exception for `renderFile` + optsKeys.push('cache'); + // No options object -- if there are optiony names // in the data, copy them to options if (arguments.length == 3) { // Express 4 if (data.settings && data.settings['view options']) { - cpOptsInData(data.settings['view options'], opts); + utils.shallowCopyFromList(opts, data.settings['view options'], optsKeys); } // Express 3 and lower else { - cpOptsInData(data, opts); + utils.shallowCopyFromList(opts, data, optsKeys); } } opts.filename = filename; diff --git a/lib/utils.js b/lib/utils.js index 06bf6d45..ce41f7aa 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -102,7 +102,9 @@ exports.escapeXML.toString = function () { }; /** - * Copy all properties from one object to another, in a shallow fashion. + * Naive copy of properties from one object to another. + * Does not recurse into non-scalar properties + * Does not check to see if the property has a value before copying * * @param {Object} to Destination object * @param {Object} from Source object @@ -118,6 +120,27 @@ exports.shallowCopy = function (to, from) { return to; }; +/** + * Naive copy of a list of key names, from one object to another. + * Only copies property if it is actually defined + * Does not recurse into non-scalar properties + * + * @param {Object} to Destination object + * @param {Object} from Source object + * @param {Array} list List of properties to copy + * @return {Object} Destination object + * @static + * @private + */ +exports.shallowCopyFromList = function (to, from, list) { + list.forEach(function (p) { + if (typeof from[p] != 'undefined') { + to[p] = from[p]; + } + }); + return to; +} + /** * Simple in-process cache implementation. Does not implement limits of any * sort.