You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							104 lines
						
					
					
						
							3.3 KiB
						
					
					
				
			
		
		
	
	
							104 lines
						
					
					
						
							3.3 KiB
						
					
					
				var defaults = require('./defaults.js');
 | 
						|
var underscore = require('./underscore.js');
 | 
						|
require('./templateSettings.js');
 | 
						|
 | 
						|
// When customizing `_.templateSettings`, if you don't want to define an
 | 
						|
// interpolation, evaluation or escaping regex, we need one that is
 | 
						|
// guaranteed not to match.
 | 
						|
var noMatch = /(.)^/;
 | 
						|
 | 
						|
// Certain characters need to be escaped so that they can be put into a
 | 
						|
// string literal.
 | 
						|
var escapes = {
 | 
						|
  "'": "'",
 | 
						|
  '\\': '\\',
 | 
						|
  '\r': 'r',
 | 
						|
  '\n': 'n',
 | 
						|
  '\u2028': 'u2028',
 | 
						|
  '\u2029': 'u2029'
 | 
						|
};
 | 
						|
 | 
						|
var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
 | 
						|
 | 
						|
function escapeChar(match) {
 | 
						|
  return '\\' + escapes[match];
 | 
						|
}
 | 
						|
 | 
						|
// In order to prevent third-party code injection through
 | 
						|
// `_.templateSettings.variable`, we test it against the following regular
 | 
						|
// expression. It is intentionally a bit more liberal than just matching valid
 | 
						|
// identifiers, but still prevents possible loopholes through defaults or
 | 
						|
// destructuring assignment.
 | 
						|
var bareIdentifier = /^\s*(\w|\$)+\s*$/;
 | 
						|
 | 
						|
// JavaScript micro-templating, similar to John Resig's implementation.
 | 
						|
// Underscore templating handles arbitrary delimiters, preserves whitespace,
 | 
						|
// and correctly escapes quotes within interpolated code.
 | 
						|
// NB: `oldSettings` only exists for backwards compatibility.
 | 
						|
function template(text, settings, oldSettings) {
 | 
						|
  if (!settings && oldSettings) settings = oldSettings;
 | 
						|
  settings = defaults({}, settings, underscore.templateSettings);
 | 
						|
 | 
						|
  // Combine delimiters into one regular expression via alternation.
 | 
						|
  var matcher = RegExp([
 | 
						|
    (settings.escape || noMatch).source,
 | 
						|
    (settings.interpolate || noMatch).source,
 | 
						|
    (settings.evaluate || noMatch).source
 | 
						|
  ].join('|') + '|$', 'g');
 | 
						|
 | 
						|
  // Compile the template source, escaping string literals appropriately.
 | 
						|
  var index = 0;
 | 
						|
  var source = "__p+='";
 | 
						|
  text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
 | 
						|
    source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
 | 
						|
    index = offset + match.length;
 | 
						|
 | 
						|
    if (escape) {
 | 
						|
      source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
 | 
						|
    } else if (interpolate) {
 | 
						|
      source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
 | 
						|
    } else if (evaluate) {
 | 
						|
      source += "';\n" + evaluate + "\n__p+='";
 | 
						|
    }
 | 
						|
 | 
						|
    // Adobe VMs need the match returned to produce the correct offset.
 | 
						|
    return match;
 | 
						|
  });
 | 
						|
  source += "';\n";
 | 
						|
 | 
						|
  var argument = settings.variable;
 | 
						|
  if (argument) {
 | 
						|
    // Insure against third-party code injection. (CVE-2021-23358)
 | 
						|
    if (!bareIdentifier.test(argument)) throw new Error(
 | 
						|
      'variable is not a bare identifier: ' + argument
 | 
						|
    );
 | 
						|
  } else {
 | 
						|
    // If a variable is not specified, place data values in local scope.
 | 
						|
    source = 'with(obj||{}){\n' + source + '}\n';
 | 
						|
    argument = 'obj';
 | 
						|
  }
 | 
						|
 | 
						|
  source = "var __t,__p='',__j=Array.prototype.join," +
 | 
						|
    "print=function(){__p+=__j.call(arguments,'');};\n" +
 | 
						|
    source + 'return __p;\n';
 | 
						|
 | 
						|
  var render;
 | 
						|
  try {
 | 
						|
    render = new Function(argument, '_', source);
 | 
						|
  } catch (e) {
 | 
						|
    e.source = source;
 | 
						|
    throw e;
 | 
						|
  }
 | 
						|
 | 
						|
  var template = function(data) {
 | 
						|
    return render.call(this, data, underscore);
 | 
						|
  };
 | 
						|
 | 
						|
  // Provide the compiled source as a convenience for precompilation.
 | 
						|
  template.source = 'function(' + argument + '){\n' + source + '}';
 | 
						|
 | 
						|
  return template;
 | 
						|
}
 | 
						|
 | 
						|
module.exports = template;
 |