Skip to content

Commit

Permalink
Add bin/without_eval utility
Browse files Browse the repository at this point in the history
  • Loading branch information
marijnh committed Sep 12, 2014
1 parent 10553cb commit 91911bc
Show file tree
Hide file tree
Showing 3 changed files with 235 additions and 143 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,20 @@ console.log(escodegen.generate(ast, {comment: true}));

[escodegen]: https://github.com/Constellation/escodegen

#### Using Acorn in an environment with a Content Security Policy

Some contexts, such as Chrome Web Apps, disallow run-time code evaluation.
Acorn uses `new Function` to generate fast functions that test whether
a word is in a given set, and will trigger a security error when used
in a context with such a
[Content Security Policy](http://www.html5rocks.com/en/tutorials/security/content-security-policy/#eval-too)
(see [#90](https://github.com/marijnh/acorn/issues/90) and
[#123](https://github.com/marijnh/acorn/issues/123)).

The `bin/without_eval` script can be used to generate a version of
`acorn.js` that has the generated code inlined, and can thus run
without evaluating anything.

### acorn_loose.js ###

This file implements an error-tolerant parser. It exposes a single
Expand Down
48 changes: 48 additions & 0 deletions bin/without_eval
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env node

var fs = require("fs");

var acornSrc = fs.readFileSync(require.resolve("../acorn"), "utf8");
var acorn = require("../acorn"), walk = require("../util/walk");

var ast = acorn.parse(acornSrc);
var touchups = [];
var uses = [], declaration;

walk.simple(ast, {
FunctionDeclaration: function(node) {
if (node.id.name == "makePredicate") {
touchups.push({text: "// Removed to create an eval-free library", from: node.start, to: node.end});
declaration = node;
}
},
VariableDeclaration: function(node) {
node.declarations.forEach(function(decl) {
if (decl.init && decl.init.type == "CallExpression" &&
decl.init.callee.name == "makePredicate")
uses.push(decl);
});
}
});

var results = Object.create(null);
var functions = new Function("predicates", acornSrc.replace(
/\}\);\s*$/, uses.map(function(decl) {
return "predicates[" + JSON.stringify(decl.id.name) + "] = " + decl.id.name + ";";
}).join("") + "});"))(results);

uses.forEach(function(decl) {
touchups.push({text: results[decl.id.name].toString(),
from: decl.init.start, to: decl.init.end});
});

var result = "", pos = 0;
touchups.sort(function(a, b) { return a.from - b.from; });
touchups.forEach(function(touchup) {
result += acornSrc.slice(pos, touchup.from);
result += touchup.text;
pos = touchup.to;
});
result += acornSrc.slice(pos);

process.stdout.write(result);
Loading

0 comments on commit 91911bc

Please sign in to comment.