Merge pull request #2650 from Elberet/fix-parser

Fix: block parser uses regexes for stop tags, allows stricter matching
This commit is contained in:
Robin Ward 2014-08-18 11:06:08 -04:00
commit 49f0eaea13
5 changed files with 21 additions and 14 deletions

View file

@ -120,7 +120,7 @@ Discourse.Markdown.whiteListTag('span', 'class', /^bbcode-size-\d+$/);
// Handles `[code] ... [/code]` blocks
Discourse.Dialect.replaceBlock({
start: /(\[code\])([\s\S]*)/igm,
stop: '[/code]',
stop: /\[\/code\]/igm,
rawContents: true,
emitter: function(blockContents) {

View file

@ -21,7 +21,7 @@ function flattenBlocks(blocks) {
Discourse.Dialect.replaceBlock({
start: /^`{3}([^\n\[\]]+)?\n?([\s\S]*)?/gm,
stop: '```',
stop: /^```$/gm,
emitter: function(blockContents, matches) {
var klass = Discourse.SiteSettings.default_code_lang;
@ -54,7 +54,7 @@ Discourse.Dialect.on('parseNode', function (event) {
Discourse.Dialect.replaceBlock({
start: /(<pre[^\>]*\>)([\s\S]*)/igm,
stop: '</pre>',
stop: /<\/pre>/igm,
rawContents: true,
skipIfTradtionalLinebreaks: true,

View file

@ -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)));

View file

@ -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'},

View file

@ -365,13 +365,17 @@ test("Code Blocks", function() {
"<p><pre><code class=\"lang-auto\">hello</code></pre></p>",
"it doesn't not whitelist all classes");
cooked("```[quote=\"sam, post:1, topic:9441, full:true\"]This is `<not>` a bug.[/quote]```",
cooked("```\n[quote=\"sam, post:1, topic:9441, full:true\"]This is `<not>` a bug.[/quote]\n```",
"<p><pre><code class=\"lang-auto\">[quote=&quot;sam, post:1, topic:9441, full:true&quot;]This is &#x60;&lt;not&gt;&#x60; a bug.[/quote]</code></pre></p>",
"it allows code with backticks in it");
cooked(" hello\n<blockquote>test</blockquote>",
"<pre><code>hello</code></pre>\n\n<blockquote>test</blockquote>",
"it allows an indented code block to by followed by a `<blockquote>`");
cooked("``` foo bar ```",
"<p><code>foo bar</code></p>",
"it tolerates misuse of code block tags as inline code");
});
test("sanitize", function() {