Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

wash

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

wash - npm Package Compare versions

Comparing version 0.0.4 to 0.0.5

test.js

4

lib/builtins.js

@@ -107,6 +107,4 @@ var _ = require('underscore');

builtins.prototype.slice = function(x, start, stop) {
if(_.isArray(x)) {
if(_.isArray(x) || _.isString(x)) {
return x.slice(start, stop);
} else if(_.isString(x)) {
return x.split('').slice(start, stop).join('');
} else {

@@ -113,0 +111,0 @@ return '';

@@ -9,5 +9,9 @@ var builtins = require('./builtins');

var _func = new Function('__ctx', '__builtin', this.code);
return _func(context, builtins);
try {
return _func(context, builtins);
} catch(err) {
throw err;
}
};
exports = module.exports = Precompiled;

@@ -13,6 +13,12 @@ var _ = require('underscore'),

var evalRegex = /\{\{.*?\}\}/;
var tagRegex = /\{%.*?%\}/;
var captureRegex = new RegExp('('+evalRegex.source+'|'+tagRegex.source+')', 'gm');
var evalOpenTag = '{{';
var evalCloseTag = '}}';
var actionOpenTag = '{%';
var actionCloseTag = '%}';
var evalTagRegex = new RegExp(escapeRegex(evalOpenTag) + '(.*?)' + escapeRegex(evalCloseTag));
var actionTagRegex = new RegExp(escapeRegex(actionOpenTag) + '(.*?)' + escapeRegex(actionCloseTag));
var tagCaptureRegex = new RegExp('('+escapeRegex(evalOpenTag) + '.*?' + escapeRegex(evalCloseTag)
+'|'+escapeRegex(actionOpenTag) + '.*?' + escapeRegex(actionCloseTag)+')', 'gm');
var operators = ['+', '-', '*', '/', '==', '!=', '>=', '<=', '>', '<', '||', '&&', '!'];

@@ -48,51 +54,31 @@

var temp = expr[0];
var validTest = '(';
_.each(expr, function(e, i) {
var p = expr.slice(0, i+1);
validTest += '__ctx.' + p.join('.') + ' !== undefined';
if(i < expr.length - 1) { validTest += ' && '; }
});
validTest += ')';
function _safe(ctx) {
var c = ctx + temp;
var m = expr;
var build = '(typeof ' + c + ' !== "undefined"';
_.each(m, function (v, i) {
if(i > 0) {
build += ' && ' + c + '.' + v + ' !== undefined';
c += '.' + v;
}
});
return '((' + validTest + ')?(__ctx.' + expr.join('.') + '):"")';
}
return build + ')';
function findSub(tokens, openIdx, openChar, closeChar) {
if(tokens[openIdx] !== openChar) {
throw new Error('opening character mismatch: ' + openChar);
}
return '((' + _safe('__ctx.') + ')?(__ctx.' + expr.join('.') + '):"")';
}
function findSub(tokens, idx, openStr, closeStr, nested) {
nested = (typeof nested === 'undefined') ? true : nested;
var len = tokens.length;
if(idx + 2 >= len) {
return -1;
} else {
// next token must be 'openStr' anyway
if(tokens[idx+1] !== openStr) {
return -1;
}
var level = 1;
for(var j=idx+2; j<len; ++j) {
if(tokens[j] == openStr) {
if(!nested) {
return -1;
}
level += 1;
} else if(tokens[j] == closeStr) {
level -= 1;
if(level == 0) {
return j;
}
var level = 1;
for(var j=openIdx+1, len=tokens.length; j<len; ++j) {
if(tokens[j] == openChar) {
level += 1;
} else if(tokens[j] == closeChar) {
level -= 1;
if(level == 0) {
return j;
}
}
}
return -1;
}
return -1;
}

@@ -113,24 +99,16 @@

if(_.contains(operators, token) || /^\".*\"$|^true$|^false$|^-?\d*\.?\d+$/.test(token)) {
// operators, string literal, true, false, number literals, comman
if(_.contains(operators, token) || /^\".*\"$|^true$|^false$|^-?\d*\.?\d+$|^\,$/.test(token)) {
outs.push(token);
} else if(builtins.__containsName(token)) {
} else if(token === '(') {
var closeIdx = findSub(tokens, i, '(', ')');
if(closeIdx <= i) {
throw new Error('invalid form of built-in: ' + token);
throw new Error('closing parenthesis not found: ' + tokens.join(' '));
}
outs.push('__builtin.' + token + '(' + this._evalTokens(tokens.slice(i+2, closeIdx)) + ')');
outs.push('(' + this._evalTokens(tokens.slice(i+1, closeIdx)) + ')');
i = closeIdx;
} else if(token === '(' || token === ')' || token === ',') {
if(token === '(' && tokens[i+1] === ')') {
// empty (); ignore it
i = i + 1;
} else {
outs.push(token);
}
} else if(builtins.__containsName(token)) {
outs.push('__builtin.' + token);
} else {
if(i+1 < len && tokens[i+1] == '(') {
throw new Error('undefined function: ' + token);
}
var first;

@@ -164,3 +142,3 @@ var dot = token.indexOf('.');

this._code.push('var __cnt_' + loopId + '=0;\n');
this._code.push('var __iterable_' + loopId + '=' + iterable + ';\n');
this._code.push('var __iterable_' + loopId + '=(' + iterable + ');\n');
this._code.push('var __obj_' + loopId + '=__builtin.isArray(__iterable_' + loopId + ')?__builtin.__toObject(__iterable_' + loopId + '):__iterable_' + loopId + ';\n');

@@ -218,5 +196,7 @@ this._code.push('for(var __key_' + loopId + ' in __obj_' + loopId + '){\n');

Wash.prototype.precompile = function() {
var tokens = this.source.split(captureRegex);
var tokens = this.source.split(tagCaptureRegex);
this._code.push('__out="";\n');
this._code.push('"use strict";\n');
this._code.push('try {\n');
this._code.push('var __out="";\n');

@@ -228,21 +208,23 @@ for(var i=0,len=tokens.length; i<len; ++i) {

if(evalRegex.test(token)) {
var expr = token.slice(2, -2);
if(expr) {
var match;
if((match = evalTagRegex.exec(token))) {
var expr = match[1].trim();
if(expr.length) {
var output = this._evalTokens(tokenize(expr));
if(output) {
this._code.push('__out+=' + output + ';\n');
if(output.length) {
this._code.push('__out+=(' + output + ');\n');
}
}
} else if(tagRegex.test(token)) {
var expr = token.slice(2, -2);
if(expr) {
} else if((match = actionTagRegex.exec(token))) {
var expr = match[1].trim();
if(expr.length) {
this._parseTag(tokenize(expr));
}
} else {
this._code.push('__out+="'+escapeStr(token)+'";\n');
this._code.push('__out+="' + escapeStr(token) + '";\n');
}
}
this._code.push('return __out;');
this._code.push('return __out;\n');
this._code.push('} catch(__err) { return ""; }\n');

@@ -249,0 +231,0 @@ return new precompiled(this._code.join(''));

{
"name": "wash",
"description": "a safe template rendering engine",
"version": "0.0.4",
"version": "0.0.5",
"main": "index",

@@ -6,0 +6,0 @@ "author": {

@@ -121,4 +121,4 @@ var t = require('../lib/index'),

expect(t.render('{{}}', ctx)).to.equal('');
expect(t.render('{{ () }}', ctx)).to.equal('');
expect(t.render('{{ ( ) }}', ctx)).to.equal('');
expect(t.render('{{ }}', ctx)).to.equal('');
expect(t.render('{{\t}}', ctx)).to.equal('');
});

@@ -149,2 +149,6 @@

});
it('syntax-errors', function() {
expect(function() { t.render('{{ ( ) }}', ctx) }).to.throwError();
});
});

@@ -226,2 +230,7 @@

it('cannot access global', function() {
expect(t.render('{{ Math.E }}', ctx)).to.equal('');
expect(t.render('{{ JSON }}', ctx)).to.equal('');
});
it('dots', function() {

@@ -232,5 +241,5 @@ expect(t.render('{{ comp.a }}', ctx)).to.equal('123');

expect(t.render('{{ comp.heck }}', ctx)).to.equal('');
expect(t.render('{{ comp.c.heck }}', ctx)).to.equal('');
expect(t.render('{{ comp.heck.heck }}', ctx)).to.equal('');
expect(t.render('{{ comp.notDefined }}', ctx)).to.equal('');
expect(t.render('{{ comp.c.notDefined }}', ctx)).to.equal('');
expect(t.render('{{ comp.notDefined.notDefined }}', ctx)).to.equal('');
});

@@ -317,6 +326,7 @@ });

it('function calls', function() {
expect(function() { t.render('{{ fx1() }}')}).to.throwError();
expect(function() { t.render('{{ fx2(10) }}')}).to.throwError();
expect(function() { t.render('{{ comp.c.fx() }}')}).to.throwError();
expect(function() { t.render('{{ (fx1( )) }}')}).to.throwError();
expect(t.render('{{ fx1() }}')).to.equal('');
expect(t.render('{{ fx2(10) }}')).to.equal('');
expect(t.render('{{ comp.c.fx() }}')).to.equal('');
expect(t.render('{{ (fx1( )) }}')).to.equal('');
expect(t.render('{{ Math.abs(-123) }}')).to.equal('');
});

@@ -323,0 +333,0 @@ });

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc