From b8c9f1ee3dc5e15d850a2f622cf4d7851333a90f Mon Sep 17 00:00:00 2001 From: Marti Martz Date: Thu, 9 Nov 2023 14:14:40 -0700 Subject: [PATCH] Work-around for *marked* issue on single tags and dep update (#2014) * walkTokens in *marked* is not any better because `` + `string` + `` still happen individually... more maintenance needed. * tokenizer in *marked* could work as long as the default handler wouldn't split the input but untested at the moment and I suspect it would split. Also even more to maintain. * Only applying this workaround to `html` type input with single tags only for now. Nested is unsupported. * Not closing atm because this is extremely hacky and it may not cover all instances since user-content can be anything. * Next *marked* will be breaking in multiple places and requires yet another dependency to continue to work with highlighting at minimum. * Alternative sanitizers, that may or may not auto close tags are either built on current, or have DOM only prerequisites/hacky Server implementation. * Missing semicolon. NOTE(s): * `blockquote` renderer appears to never be called but haven't typed everything there is possible into user-content. ;) * `innerHTML` *possibly* auto-closes just like GM_setStyle lib does with CSS in the DOM i.e. validation before execution... a form of sanitizing... currently untested but assumed for future ease-of maintainability. Applies to #1775 Auto-merge --- libs/markdown.js | 29 ++++++++++++++++++++++++++++- package.json | 2 +- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/libs/markdown.js b/libs/markdown.js index 0794c1898..edd0e4bd9 100644 --- a/libs/markdown.js +++ b/libs/markdown.js @@ -143,6 +143,22 @@ function sanitize(aHtml) { // Sanitize the output from the block level renderers blockRenderers.forEach(function (aType) { renderer[aType] = function () { + var matches = null; + var openTagName = null; + var closeTagName = null; + + // Begin workaround for #1775 + if (aType === 'html') { + matches = arguments[0].match(/^<([a-z]+)(?![^>]*\/>)[^>]*>$/); + if (matches) { + openTagName = matches[1]; + } + matches = arguments[0].match(/^<\/([a-z]+)>$/); + if (matches) { + closeTagName = matches[1]; + } + } + // Sanitize first to close any tags var sanitized = sanitize(marked.Renderer.prototype[aType].apply(renderer, arguments)); @@ -198,7 +214,18 @@ blockRenderers.forEach(function (aType) { } } - sanitized = hookNode.innerHTML + sanitized = hookNode.innerHTML; + } + + // End workaround for #1775 + if (aType === 'html') { + if (openTagName) { + sanitized = sanitized.replace(/<\/[a-z]+>/, ''); + } + + if (closeTagName) { + sanitized = ''; + } } return sanitized; diff --git a/package.json b/package.json index 2b280de94..7926ce78f 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "js-beautify": "1.14.9", "jsdom": "22.1.0", "less-middleware": "3.1.0", - "marked": "4.3.0", + "marked": "7.0.5", "media-type": "0.3.1", "method-override": "3.0.0", "mime-db": "1.52.0",