mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-01-25 16:36:52 +00:00
Added protection against wikitext recursion
Now attempts to view a tiddler recursively fail gracefully
This commit is contained in:
parent
3bb0490bee
commit
a0524c2144
@ -39,7 +39,7 @@ MacroNode.prototype.cloneChildren = function() {
|
|||||||
return childClones;
|
return childClones;
|
||||||
};
|
};
|
||||||
|
|
||||||
MacroNode.prototype.execute = function(tiddler) {
|
MacroNode.prototype.execute = function(parents,tiddler) {
|
||||||
// Evaluate the macro parameters to get their values
|
// Evaluate the macro parameters to get their values
|
||||||
if(typeof this.paramFn === "object") {
|
if(typeof this.paramFn === "object") {
|
||||||
this.params = this.paramFn;
|
this.params = this.paramFn;
|
||||||
@ -48,6 +48,8 @@ MacroNode.prototype.execute = function(tiddler) {
|
|||||||
}
|
}
|
||||||
// Save the context tiddler
|
// Save the context tiddler
|
||||||
this.tiddlerTitle = tiddler.title;
|
this.tiddlerTitle = tiddler.title;
|
||||||
|
// Save a reference to the array of parents
|
||||||
|
this.parents = parents;
|
||||||
// Render the macro to get its content
|
// Render the macro to get its content
|
||||||
this.content = this.macro.execute(this,tiddler,this.store);
|
this.content = this.macro.execute(this,tiddler,this.store);
|
||||||
};
|
};
|
||||||
@ -92,7 +94,7 @@ MacroNode.prototype.refresh = function(changes) {
|
|||||||
if(this.dependencies.hasChanged(changes)) {
|
if(this.dependencies.hasChanged(changes)) {
|
||||||
// Re-execute the macro if so
|
// Re-execute the macro if so
|
||||||
var tiddler = this.store.getTiddler(this.tiddlerTitle);
|
var tiddler = this.store.getTiddler(this.tiddlerTitle);
|
||||||
this.execute(tiddler);
|
this.execute(this.parents,tiddler);
|
||||||
} else {
|
} else {
|
||||||
// Refresh any children
|
// Refresh any children
|
||||||
for(t=0; t<this.content.length; t++) {
|
for(t=0; t<this.content.length; t++) {
|
||||||
@ -115,7 +117,7 @@ MacroNode.prototype.refreshInDom = function(changes) {
|
|||||||
while(this.domNode.hasChildNodes()) {
|
while(this.domNode.hasChildNodes()) {
|
||||||
this.domNode.removeChild(this.domNode.firstChild);
|
this.domNode.removeChild(this.domNode.firstChild);
|
||||||
}
|
}
|
||||||
this.execute(tiddler);
|
this.execute(this.parents,tiddler);
|
||||||
for(t=0; t<this.content.length; t++) {
|
for(t=0; t<this.content.length; t++) {
|
||||||
this.content[t].renderInDom(this.domNode);
|
this.content[t].renderInDom(this.domNode);
|
||||||
}
|
}
|
||||||
@ -149,10 +151,10 @@ ElementNode.prototype.clone = function() {
|
|||||||
return new ElementNode(this.type,this.attributes,childClones);
|
return new ElementNode(this.type,this.attributes,childClones);
|
||||||
};
|
};
|
||||||
|
|
||||||
ElementNode.prototype.execute = function(tiddler) {
|
ElementNode.prototype.execute = function(parents,tiddler) {
|
||||||
if(this.children) {
|
if(this.children) {
|
||||||
for(var t=0; t<this.children.length; t++) {
|
for(var t=0; t<this.children.length; t++) {
|
||||||
this.children[t].execute(tiddler);
|
this.children[t].execute(parents,tiddler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -247,7 +249,7 @@ TextNode.prototype.clone = function() {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
TextNode.prototype.execute = function(tiddler) {
|
TextNode.prototype.execute = function(parents,tiddler) {
|
||||||
// Text nodes don't need executing
|
// Text nodes don't need executing
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -280,7 +282,7 @@ EntityNode.prototype.clone = function() {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
EntityNode.prototype.execute = function(tiddler) {
|
EntityNode.prototype.execute = function(parents,tiddler) {
|
||||||
// Entity nodes don't need executing
|
// Entity nodes don't need executing
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -313,7 +315,7 @@ RawNode.prototype.clone = function() {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
RawNode.prototype.execute = function(tiddler) {
|
RawNode.prototype.execute = function(parents,tiddler) {
|
||||||
// Raw nodes don't need executing
|
// Raw nodes don't need executing
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -381,7 +383,7 @@ var SliderNode = function(type,label,tooltip,isOpen,children) {
|
|||||||
attributes.alt = tooltip;
|
attributes.alt = tooltip;
|
||||||
attributes.title = tooltip;
|
attributes.title = tooltip;
|
||||||
}
|
}
|
||||||
return ElementNode("div",
|
return ElementNode("span",
|
||||||
attributes,
|
attributes,
|
||||||
[
|
[
|
||||||
ElementNode("a",
|
ElementNode("a",
|
||||||
@ -422,7 +424,7 @@ var Renderer = function(tiddlerTitle,templateTitle,store) {
|
|||||||
// Execute the macros in the root
|
// Execute the macros in the root
|
||||||
var tiddler = store.getTiddler(tiddlerTitle);
|
var tiddler = store.getTiddler(tiddlerTitle);
|
||||||
for(t=0; t<this.steps.length; t++) {
|
for(t=0; t<this.steps.length; t++) {
|
||||||
this.steps[t].execute(tiddler);
|
this.steps[t].execute([templateTitle],tiddler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ exports.macro = {
|
|||||||
"class": classes
|
"class": classes
|
||||||
},macroNode.cloneChildren())];
|
},macroNode.cloneChildren())];
|
||||||
for(var t=0; t<content.length; t++) {
|
for(var t=0; t<content.length; t++) {
|
||||||
content[t].execute(tiddler);
|
content[t].execute(macroNode.parents,tiddler);
|
||||||
}
|
}
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,11 @@ exports.macro = {
|
|||||||
templateText = "<<view title link>>",
|
templateText = "<<view title link>>",
|
||||||
template = macroNode.params.template ? store.getTiddler(macroNode.params.template) : null,
|
template = macroNode.params.template ? store.getTiddler(macroNode.params.template) : null,
|
||||||
content = [],
|
content = [],
|
||||||
t;
|
t,
|
||||||
|
parents = macroNode.parents;
|
||||||
if(template) {
|
if(template) {
|
||||||
|
parents = parents.slice(0);
|
||||||
|
parents.push(template.title);
|
||||||
templateType = template.type;
|
templateType = template.type;
|
||||||
templateText = template.text;
|
templateText = template.text;
|
||||||
}
|
}
|
||||||
@ -64,7 +67,7 @@ exports.macro = {
|
|||||||
cloneTemplate.push(templateTree[c].clone());
|
cloneTemplate.push(templateTree[c].clone());
|
||||||
}
|
}
|
||||||
var listNode = Renderer.ElementNode("li",null,cloneTemplate);
|
var listNode = Renderer.ElementNode("li",null,cloneTemplate);
|
||||||
listNode.execute(store.getTiddler(tiddlers[t]));
|
listNode.execute(parents,store.getTiddler(tiddlers[t]));
|
||||||
content.push(listNode);
|
content.push(listNode);
|
||||||
}
|
}
|
||||||
return [Renderer.ElementNode("ul",null,content)];
|
return [Renderer.ElementNode("ul",null,content)];
|
||||||
|
@ -54,7 +54,7 @@ exports.macro = {
|
|||||||
dependencies.addDependency(macroNode.params.template,true);
|
dependencies.addDependency(macroNode.params.template,true);
|
||||||
}
|
}
|
||||||
var m = Renderer.MacroNode("tiddler",paramFn,null,dependencies,store);
|
var m = Renderer.MacroNode("tiddler",paramFn,null,dependencies,store);
|
||||||
m.execute(tiddler);
|
m.execute(macroNode.parents,tiddler);
|
||||||
content.push(m);
|
content.push(m);
|
||||||
}
|
}
|
||||||
return content;
|
return content;
|
||||||
@ -89,7 +89,7 @@ exports.macro = {
|
|||||||
dependencies.addDependency(template,true);
|
dependencies.addDependency(template,true);
|
||||||
}
|
}
|
||||||
var m = Renderer.MacroNode("tiddler",paramFn,null,dependencies,store);
|
var m = Renderer.MacroNode("tiddler",paramFn,null,dependencies,store);
|
||||||
m.execute(store.getTiddler(targetTiddlers[t]));
|
m.execute(macroNode.parents,store.getTiddler(targetTiddlers[t]));
|
||||||
m.renderInDom(macroNode.domNode,macroNode.domNode.childNodes[t]);
|
m.renderInDom(macroNode.domNode,macroNode.domNode.childNodes[t]);
|
||||||
macroNode.content.splice(t,0,m);
|
macroNode.content.splice(t,0,m);
|
||||||
} else {
|
} else {
|
||||||
|
@ -58,33 +58,39 @@ exports.macro = {
|
|||||||
renderTemplate = macroNode.params.template,
|
renderTemplate = macroNode.params.template,
|
||||||
content,
|
content,
|
||||||
contentClone = [],
|
contentClone = [],
|
||||||
t;
|
t,
|
||||||
|
parents = macroNode.parents.slice(0);
|
||||||
if(typeof renderTitle !== "string") {
|
if(typeof renderTitle !== "string") {
|
||||||
renderTitle = tiddler.title;
|
renderTitle = tiddler.title;
|
||||||
}
|
}
|
||||||
if(typeof renderTemplate !== "string") {
|
if(typeof renderTemplate !== "string") {
|
||||||
renderTemplate = renderTitle;
|
renderTemplate = renderTitle;
|
||||||
}
|
}
|
||||||
if("with" in macroNode.params) {
|
if(parents.indexOf(renderTemplate) === -1) {
|
||||||
// Parameterised transclusion
|
if("with" in macroNode.params) {
|
||||||
var targetTiddler = store.getTiddler(renderTemplate),
|
// Parameterised transclusion
|
||||||
text = targetTiddler.text;
|
var targetTiddler = store.getTiddler(renderTemplate),
|
||||||
var withTokens = [macroNode.params["with"]];
|
text = targetTiddler.text;
|
||||||
for(t=0; t<withTokens.length; t++) {
|
var withTokens = [macroNode.params["with"]];
|
||||||
var placeholderRegExp = new RegExp("\\$"+(t+1),"mg");
|
for(t=0; t<withTokens.length; t++) {
|
||||||
text = text.replace(placeholderRegExp,withTokens[t]);
|
var placeholderRegExp = new RegExp("\\$"+(t+1),"mg");
|
||||||
|
text = text.replace(placeholderRegExp,withTokens[t]);
|
||||||
|
}
|
||||||
|
content = store.parseText(targetTiddler.type,text).tree;
|
||||||
|
} else {
|
||||||
|
// There's no parameterisation, so we can just render the target tiddler directly
|
||||||
|
var parseTree = store.parseTiddler(renderTemplate);
|
||||||
|
content = parseTree ? parseTree.tree : [];
|
||||||
}
|
}
|
||||||
content = store.parseText(targetTiddler.type,text).tree;
|
|
||||||
} else {
|
} else {
|
||||||
// There's no parameterisation, so we can just render the target tiddler directly
|
content = [Renderer.TextNode("{{** Tiddler recursion error in <<tiddler>> macro **}}")];
|
||||||
var parseTree = store.parseTiddler(renderTemplate);
|
|
||||||
content = parseTree ? parseTree.tree : [];
|
|
||||||
}
|
}
|
||||||
|
parents.push(renderTemplate);
|
||||||
for(t=0; t<content.length; t++) {
|
for(t=0; t<content.length; t++) {
|
||||||
contentClone.push(content[t].clone());
|
contentClone.push(content[t].clone());
|
||||||
}
|
}
|
||||||
for(t=0; t<contentClone.length; t++) {
|
for(t=0; t<contentClone.length; t++) {
|
||||||
contentClone[t].execute(store.getTiddler(renderTitle));
|
contentClone[t].execute(parents,store.getTiddler(renderTitle));
|
||||||
}
|
}
|
||||||
return contentClone;
|
return contentClone;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,8 @@ exports.macro = {
|
|||||||
var v = tiddler[macroNode.params.field],
|
var v = tiddler[macroNode.params.field],
|
||||||
content,
|
content,
|
||||||
t,
|
t,
|
||||||
contentClone = [];
|
contentClone = [],
|
||||||
|
parents = macroNode.parents;
|
||||||
if(v !== undefined) {
|
if(v !== undefined) {
|
||||||
switch(macroNode.params.format) {
|
switch(macroNode.params.format) {
|
||||||
case "link":
|
case "link":
|
||||||
@ -37,11 +38,17 @@ exports.macro = {
|
|||||||
[Renderer.TextNode(v)],
|
[Renderer.TextNode(v)],
|
||||||
dependencies,
|
dependencies,
|
||||||
store);
|
store);
|
||||||
link.execute(tiddler);
|
link.execute(parents,tiddler);
|
||||||
return [link];
|
return [link];
|
||||||
case "wikified":
|
case "wikified":
|
||||||
if(macroNode.params.field === "text") {
|
if(macroNode.params.field === "text") {
|
||||||
content = store.parseTiddler(tiddler.title).tree;
|
if(parents.indexOf(tiddler.title) === -1) {
|
||||||
|
content = store.parseTiddler(tiddler.title).tree;
|
||||||
|
} else {
|
||||||
|
content = [Renderer.TextNode("{{** Tiddler recursion error in <<view>> macro **}}")];
|
||||||
|
}
|
||||||
|
parents = parents.slice(0);
|
||||||
|
parents.push(tiddler.title);
|
||||||
} else {
|
} else {
|
||||||
content = store.parseText("text/x-tiddlywiki",v).tree;
|
content = store.parseText("text/x-tiddlywiki",v).tree;
|
||||||
}
|
}
|
||||||
@ -49,7 +56,7 @@ exports.macro = {
|
|||||||
contentClone.push(content[t].clone());
|
contentClone.push(content[t].clone());
|
||||||
}
|
}
|
||||||
for(t=0; t<contentClone.length; t++) {
|
for(t=0; t<contentClone.length; t++) {
|
||||||
contentClone[t].execute(tiddler);
|
contentClone[t].execute(parents,tiddler);
|
||||||
}
|
}
|
||||||
return contentClone;
|
return contentClone;
|
||||||
case "date":
|
case "date":
|
||||||
|
Loading…
Reference in New Issue
Block a user