Complete switch over to pegjs

This commit is contained in:
Jeremy Ruston 2011-12-28 22:07:17 +00:00
parent b27a99a7fb
commit ed2e2ab14c
10 changed files with 34 additions and 23 deletions

View File

@ -16,8 +16,10 @@ Options and their defaults are:
noNames: false,
cascadeDefaults: false,
allowEval: true
sandbox: null
globals: null
`sandbox` is the sandbox object used to evaluate JavaScript parameters
`globals` is the global variable object provided to evaluated parameters
\*/
@ -26,9 +28,8 @@ Options and their defaults are:
/*jslint node: true */
"use strict";
var sandbox = require("./Sandbox.js").sandbox;
var ArgParser = function(argString,options) {
options = options || {};
var parseToken = function(match,p) {
var n;
if(match[p]) { // Double quoted
@ -38,7 +39,7 @@ var ArgParser = function(argString,options) {
} else if(match[p+2]) { // Double-square-bracket quoted
n = match[p+2];
} else if(match[p+3]) { // Double-brace quoted
n = options.allowEval === false ? match[p+3] : sandbox(match[p+3],options.globals);
n = options.allowEval === false ? match[p+3] : options.sandbox.execute(match[p+3],options.globals);
} else if(match[p+4]) { // Unquoted
n = match[p+4];
} else if(match[p+5]) { // empty quote

View File

@ -14,6 +14,7 @@ var WikiStore = require("./WikiStore.js").WikiStore,
tiddlerInput = require("./TiddlerInput.js"),
tiddlerOutput = require("./TiddlerOutput.js"),
WikiTextProcessor = require("./WikiTextProcessor.js").WikiTextProcessor,
Sandbox = require("./Sandbox.js").Sandbox,
Navigators = require("./Navigators.js").Navigators,
StoryNavigator = require("./StoryNavigator.js").StoryNavigator;
@ -58,6 +59,9 @@ for(t=0; t<tiddlers.length; t++) {
store.addTiddler(new Tiddler(tiddlers[t]));
}
// Set up the sandbox for evaluated macro parameters
store.sandbox = new Sandbox(store.getTiddlerText("javascript.pegjs"));
// Install the standard navigators
var navigators = new Navigators({
document: document,

View File

@ -57,7 +57,7 @@ var Recipe = function(options,callback) {
this.recipeQueue = async.queue(function(task,callback) {
retrieveFile(task.filepath,task.contextPath,function(err,data) {
if(err) {
callback(err);
me.callback(err);
} else {
me.processRecipeFile(task.recipe,data.text,data.path);
callback(null);
@ -342,7 +342,7 @@ Recipe.prototype.cookRss = function()
getRssTiddlers = function(sortField,excludeTag) {
var r = [];
me.store.forEachTiddler(sortField,excludeTag,function(title,tiddler) {
if(!tiddler.hasTag(excludeTag)) {
if(!tiddler.hasTag(excludeTag) && tiddler.fields.modified !== undefined) {
r.push(tiddler);
}
});

View File

@ -9,9 +9,13 @@ Execute a fragment of JavaScript in a sandbox
/*jslint evil: true, node: true */
"use strict";
var uglify = require("uglify-js");
var pegjs = require("pegjs");
var sandbox = function(code,globals) {
var Sandbox = function(parserText) {
this.parser = pegjs.buildParser(parserText);
};
Sandbox.prototype.execute = function(code,globals) {
var globalNames = [],
globalValues = [],
collectGlobals = function(globals) {
@ -36,20 +40,20 @@ var sandbox = function(code,globals) {
out.push(code);
out.push(";})");
// Parse the code
var tree = uglify.parser.parse(out.join(""));
var code = out.join(""),
tree = this.parser.parse(out.join(""));
// XXX: Sanitise the code by checking for references to globals, stripping out eval()
// Recompile the code
var compiledCode = uglify.uglify.gen_code(tree);
console.log(tree);
// Execute it
var result;
try {
result = eval(compiledCode).apply(null,globalValues);
result = eval(code).apply(null,globalValues);
} catch(err) {
result = "{{** Evaluation error: " + err + " **}}";
}
return result;
};
exports.sandbox = sandbox;
exports.Sandbox = Sandbox;
})();

View File

@ -21,6 +21,7 @@ var WikiStore = function WikiStore(options) {
this.textProcessors = {};
this.tiddlerSerializers = {};
this.tiddlerDeserializers = {};
this.sandbox = options.sandbox;
this.shadows = options.shadowStore !== undefined ? options.shadowStore : new WikiStore({
shadowStore: null
});

View File

@ -134,7 +134,8 @@ WikiTextRenderer.prototype.executeMacro = function(macroNode,title) {
var argOptions = {
globals: {
title: title
}
},
sandbox: this.store.sandbox
};
for(var g in macroInfo.argOptions) {
argOptions[g] = macroInfo.argOptions[g];

3
parsers/split.recipe Normal file
View File

@ -0,0 +1,3 @@
tiddler: javascript.pegjs
title: javascript.pegjs
type: text/x-tiddlywiki-parser

View File

@ -107,8 +107,8 @@ var commandLineSwitches = {
recipe = new Recipe({
filepath: args[0],
store: store
},function() {
callback(null);
},function(err) {
callback(err);
});
}
}

View File

@ -10,3 +10,5 @@ TiddlyWiki5 gains new capabilities through a [[completely rebuilt architecture|T
TiddlyWiki5 also functions as the build system for earlier versions of TiddlyWiki, replacing the elderly Cook and Ginsu tools (see https://github.com/TiddlyWiki/cooker for details). See the CommandLineInterface for details.
<<list all>>
<<echo {{2+2}}>>

View File

@ -3,6 +3,7 @@ copyright: ../copyright.txt
style: styles.css
recipe: tiddlers/split.recipe
recipe: ../parsers/split.recipe
jslib: ../test/tiddlywiki.2.6.5/source/tiddlywiki/jquery/jquery.js
@ -22,14 +23,8 @@ jsmodule: ../js/Navigators.js
jsmodule: ../js/StoryNavigator.js
jsmodule: ../js/Main.js
jsmodule: ../node_modules/uglify-js/lib/parse-js.js
title: lib/parse-js
jsmodule: ../node_modules/uglify-js/lib/process.js
title: lib/process
jsmodule: ../node_modules/uglify-js/lib/squeeze-more.js
title: lib/squeeze-more
jsmodule: ../node_modules/uglify-js/uglify-js.js
title: uglify-js
jsmodule: ../node_modules/pegjs/lib/peg.js
title: pegjs
jsbootstart: BootStart.js
jsbootend: BootLoader.js