From 474905828fe41794f9b608c3ba6659db6827b45f Mon Sep 17 00:00:00 2001 From: pmario Date: Wed, 17 Apr 2024 13:22:09 +0200 Subject: [PATCH] add button custom recursion detection and protection --- core/language/en-GB/Misc.multids | 1 + core/modules/widgets/button.js | 17 ++++++++++++++++- .../Recursion-Button-Transclusion.tid | 15 +++++++++++++++ .../transclude/Recursion-Button-in-Button.tid | 15 +++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 editions/test/tiddlers/tests/data/transclude/Recursion-Button-Transclusion.tid create mode 100644 editions/test/tiddlers/tests/data/transclude/Recursion-Button-in-Button.tid diff --git a/core/language/en-GB/Misc.multids b/core/language/en-GB/Misc.multids index b5e6e2374..a806774c1 100644 --- a/core/language/en-GB/Misc.multids +++ b/core/language/en-GB/Misc.multids @@ -37,6 +37,7 @@ Error/NetworkErrorAlert: `

''Network Error''

It looks like the connection Error/PutEditConflict: File changed on server Error/PutForbidden: Permission denied Error/PutUnauthorized: Authentication required +Error/RecursiveButton: Possible Recursive Error: Button in button is not allowed Error/RecursiveTransclusion: Recursive transclusion error in transclude widget Error/RetrievingSkinny: Error retrieving skinny tiddler list Error/SavingToTWEdit: Error saving to TWEdit diff --git a/core/modules/widgets/button.js b/core/modules/widgets/button.js index 958b6f6da..633514f45 100644 --- a/core/modules/widgets/button.js +++ b/core/modules/widgets/button.js @@ -18,6 +18,10 @@ var Popup = require("$:/core/modules/utils/dom/popup.js"); var ButtonWidget = function(parseTreeNode,options) { this.initialise(parseTreeNode,options); + // Check if any parent is a button. Custom recursion detection for buttons in buttons + if(!this.hasVariable("tv-is-button","yes")) { + this.setVariable("tv-is-button", "yes"); + } }; /* @@ -37,6 +41,17 @@ ButtonWidget.prototype.render = function(parent,nextSibling) { // Compute attributes and execute state this.computeAttributes(); this.execute(); + // Check "button in button". Return early with an error message + // This check also prevents fatal recursion errors using the transclusion widget + if(this.parentWidget && this.parentWidget.hasVariable("tv-is-button","yes")) { + var domNode = this.document.createElement("span"); + var textNode = this.document.createTextNode($tw.language.getString("Error/RecursiveButton")); + domNode.appendChild(textNode); + domNode.className = "tc-error"; + parent.insertBefore(domNode,nextSibling); + this.domNodes.push(domNode); + return; + } // Create element if(this.buttonTag && $tw.config.htmlUnsafeElements.indexOf(this.buttonTag) === -1) { tag = this.buttonTag; @@ -74,7 +89,7 @@ ButtonWidget.prototype.render = function(parent,nextSibling) { if(this["aria-label"]) { domNode.setAttribute("aria-label",this["aria-label"]); } - if (this.role) { + if(this.role) { domNode.setAttribute("role", this.role); } if(this.popup || this.popupTitle) { diff --git a/editions/test/tiddlers/tests/data/transclude/Recursion-Button-Transclusion.tid b/editions/test/tiddlers/tests/data/transclude/Recursion-Button-Transclusion.tid new file mode 100644 index 000000000..c6a08e1d2 --- /dev/null +++ b/editions/test/tiddlers/tests/data/transclude/Recursion-Button-Transclusion.tid @@ -0,0 +1,15 @@ +title: Transclude/Recursion/Button +description: Transclusion recursion inside a button +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +\whitespace trim +<$button> +<$transclude/> + ++ +title: ExpectedResult + +

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/transclude/Recursion-Button-in-Button.tid b/editions/test/tiddlers/tests/data/transclude/Recursion-Button-in-Button.tid new file mode 100644 index 000000000..f90afb134 --- /dev/null +++ b/editions/test/tiddlers/tests/data/transclude/Recursion-Button-in-Button.tid @@ -0,0 +1,15 @@ +title: Transclude/Recursion/ButtonInButton +description: Button in Button +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +\whitespace trim +<$button>Test Button +<$button>Invalid button + ++ +title: ExpectedResult + +

\ No newline at end of file