Skip to content

Commit

Permalink
Refactored opts-in-data passing, cleaner util method
Browse files Browse the repository at this point in the history
  • Loading branch information
mde committed Dec 5, 2016
1 parent 54f7653 commit 3a534a9
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 38 deletions.
48 changes: 11 additions & 37 deletions lib/ejs.js
Original file line number Diff line number Diff line change
Expand Up @@ -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/;

/**
Expand Down Expand Up @@ -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');
}
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
25 changes: 24 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down

0 comments on commit 3a534a9

Please sign in to comment.