jade: avoid using eval once compiled

Use of eval is handy when we need to automatically reload a
template. However, in production, this is slow and unsafe. Moreover,
when using CSP, we have to use 'unsafe-eval' which brings shame to
most of us. It appears use of eval() is not needed because the
template has already been translated to Javascript. We just need to
bind "jade" to its local scope.

So, we add an additional wrapper function binding "jade" to the local
scope. Moreover, when compiling the template, we add a flag to the
function to know it has already been compiled. In this case, we
execute it with "jade" in its scope. Otherwise, we keep using eval.

Quickly tested in both situations. Seem to work.

Fix #274.
This commit is contained in:
Vincent Bernat 2018-04-17 22:32:16 +02:00
parent 47b14ab0c8
commit 9618c0f3a3
2 changed files with 9 additions and 2 deletions

View File

@ -7,6 +7,9 @@ define(["libjs-jade-runtime", "app/utils", "jade!app/text/postbox", "jade!app/te
var load = function(name, js) { var load = function(name, js) {
templates[name] = (function(jade) { templates[name] = (function(jade) {
var fn; var fn;
if (js.compiled) {
return js(jade);
}
eval("fn = " + js); eval("fn = " + js);
return fn; return fn;
})(runtime); })(runtime);

View File

@ -49,8 +49,12 @@ define(function() {
write: function(plugin, name, write) { write: function(plugin, name, write) {
if (builds.hasOwnProperty(name)) { if (builds.hasOwnProperty(name)) {
write("define('" + plugin + "!" + name +"', function () {" + write("define('" + plugin + "!" + name +"', function () {" +
" var wfn = function (jade) {" +
" var fn = " + builds[name] + ";" + " var fn = " + builds[name] + ";" +
" return fn;" + " return fn;" +
" };" +
"wfn.compiled = true;" +
"return wfn;" +
"});\n"); "});\n");
} }
} }