From 23002ae01cde0fdf1b119d3ae50d5ba2cce11306 Mon Sep 17 00:00:00 2001
From: Jens Maier ]*\>)([\s\S]*)/igm,
- stop: '
',
+ stop: /<\/pre>/igm,
rawContents: true,
skipIfTradtionalLinebreaks: true,
diff --git a/app/assets/javascripts/discourse/dialects/dialect.js b/app/assets/javascripts/discourse/dialects/dialect.js
index 663e7205c6b..ddb84b45a8d 100644
--- a/app/assets/javascripts/discourse/dialects/dialect.js
+++ b/app/assets/javascripts/discourse/dialects/dialect.js
@@ -379,7 +379,7 @@ Discourse.Dialect = {
if (!match) { return; }
var lastChance = function() {
- return !next.some(function(e) { return e.indexOf(args.stop) !== -1; });
+ return !next.some(function(blk) { return blk.match(args.stop); });
};
// shave off start tag and leading text, if any.
@@ -387,7 +387,8 @@ Discourse.Dialect = {
leading = block.slice(0, pos),
trailing = match[2] ? match[2].replace(/^\n*/, "") : "";
// just give up if there's no stop tag in this or any next block
- if (block.indexOf(args.stop, pos + args.stop.length) === -1 && lastChance()) { return; }
+ args.stop.lastIndex = block.length - trailing.length;
+ if (!args.stop.exec(block) && lastChance()) { return; }
if (leading.length > 0) { result.push(['p'].concat(this.processInline(leading))); }
if (trailing.length > 0) {
next.unshift(MD.mk_block(trailing, block.trailing,
@@ -405,10 +406,10 @@ Discourse.Dialect = {
startPos.push(args.start.lastIndex - m[0].length);
args.start.lastIndex = args.start.lastIndex - (m[2] ? m[2].length : 0);
}
- var endPos = [], offset = 0;
- while ((pos = currentBlock.indexOf(args.stop, offset)) !== -1) {
- endPos.push(pos);
- offset += (pos + args.stop.length);
+ args.stop.lastIndex = 0;
+ var endPos = [];
+ while (m = (args.stop).exec(currentBlock)) {
+ endPos.push(args.stop.lastIndex - m[0].length);
}
// go through the available end tags:
@@ -421,7 +422,8 @@ Discourse.Dialect = {
// found an end tag, but we must go up a level first.
ep++; nesting--;
} else {
- // found an end tag and we're at the top: done!
+ // found an end tag and we're at the top: done! -- or: start tag and end tag are
+ // identical, (i.e. startPos[sp] == endPos[ep]), so we don't do nesting at all.
actualEndPos = endPos[ep];
break blockloop;
}
@@ -442,8 +444,9 @@ Discourse.Dialect = {
contentBlocks.push(currentBlock);
}
- var before = currentBlock.slice(0, actualEndPos).replace(/\n*$/, ""),
- after = currentBlock.slice(actualEndPos + args.stop.length).replace(/^\n*/, "");
+ var stopLen = currentBlock.match(args.stop)[0].length,
+ before = currentBlock.slice(0, actualEndPos).replace(/\n*$/, ""),
+ after = currentBlock.slice(actualEndPos + stopLen).replace(/^\n*/, "");
if (before.length > 0) contentBlocks.push(MD.mk_block(before, "", currentBlock.lineNumber));
if (after.length > 0) next.unshift(MD.mk_block(after, "", currentBlock.lineNumber + countLines(before)));
diff --git a/app/assets/javascripts/discourse/dialects/quote_dialect.js b/app/assets/javascripts/discourse/dialects/quote_dialect.js
index 69ac28dcb29..bb740582e73 100644
--- a/app/assets/javascripts/discourse/dialects/quote_dialect.js
+++ b/app/assets/javascripts/discourse/dialects/quote_dialect.js
@@ -6,7 +6,7 @@ var esc = Handlebars.Utils.escapeExpression;
Discourse.Dialect.replaceBlock({
start: new RegExp("\\[quote(=[^\\[\\]]+)?\\]([\\s\\S]*)", "igm"),
- stop: '[/quote]',
+ stop: /\[\/quote\]/igm,
emitter: function(blockContents, matches, options) {
var params = {'class': 'quote'},
diff --git a/test/javascripts/lib/markdown-test.js.es6 b/test/javascripts/lib/markdown-test.js.es6
index f8b22858138..2a06be5ae70 100644
--- a/test/javascripts/lib/markdown-test.js.es6
+++ b/test/javascripts/lib/markdown-test.js.es6
@@ -365,13 +365,17 @@ test("Code Blocks", function() {
"hello
[quote="sam, post:1, topic:9441, full:true"]This is `<not>` a bug.[/quote]
",
"it allows code with backticks in it");
cooked(" hello\ntest", "
hello
\n\ntest", "it allows an indented code block to by followed by a `
`"); + + cooked("``` foo bar ```", + "", + "it tolerates misuse of code block tags as inline code"); }); test("sanitize", function() {
foo bar