From e72603af706f21fa9e77faeb11c3589ef27961d5 Mon Sep 17 00:00:00 2001 From: Vitaly Puzrin Date: Wed, 31 Dec 2014 21:07:32 +0300 Subject: [PATCH] Moved nesting check from rules to upper level --- lib/parser_block.js | 10 +++++++++- lib/parser_inline.js | 30 ++++++++++++++++++++++------- lib/rules_block/blockquote.js | 2 -- lib/rules_block/deflist.js | 2 -- lib/rules_block/footnote.js | 1 - lib/rules_block/list.js | 2 -- lib/rules_inline/del.js | 1 - lib/rules_inline/emphasis.js | 2 -- lib/rules_inline/footnote_inline.js | 1 - lib/rules_inline/footnote_ref.js | 1 - lib/rules_inline/ins.js | 1 - lib/rules_inline/links.js | 1 - lib/rules_inline/mark.js | 1 - lib/rules_inline/sub.js | 1 - lib/rules_inline/sup.js | 1 - 15 files changed, 32 insertions(+), 25 deletions(-) diff --git a/lib/parser_block.js b/lib/parser_block.js index 8eb2c79..5c1fedb 100644 --- a/lib/parser_block.js +++ b/lib/parser_block.js @@ -49,7 +49,8 @@ ParserBlock.prototype.tokenize = function (state, startLine, endLine) { rules = this.ruler.getRules(''), len = rules.length, line = startLine, - hasEmptyLines = false; + hasEmptyLines = false, + maxNesting = state.md.options.maxNesting; while (line < endLine) { state.line = line = state.skipEmptyLines(line); @@ -59,6 +60,13 @@ ParserBlock.prototype.tokenize = function (state, startLine, endLine) { // Nested calls currently used for blockquotes & lists if (state.tShift[line] < state.blkIndent) { break; } + // If nesting level exceeded - skip tail to the end. That's not ordinary + // situation and we should not care about content. + if (state.level >= maxNesting) { + state.line = endLine; + break; + } + // Try all possible rules. // On success, rule should: // diff --git a/lib/parser_inline.js b/lib/parser_inline.js index 81ebcdc..2dfd0d9 100644 --- a/lib/parser_inline.js +++ b/lib/parser_inline.js @@ -85,21 +85,30 @@ function ParserInline() { ParserInline.prototype.skipToken = function (state) { var i, cached_pos, pos = state.pos, rules = this.ruler.getRules(''), - len = rules.length; + len = rules.length, + maxNesting = state.md.options.maxNesting; + if ((cached_pos = state.cacheGet(pos)) > 0) { state.pos = cached_pos; return; } - for (i = 0; i < len; i++) { - if (rules[i](state, true)) { - state.cacheSet(pos, state.pos); - return; + if (state.level < maxNesting) { + for (i = 0; i < len; i++) { + if (rules[i](state, true)) { + state.cacheSet(pos, state.pos); + return; + } } + state.pos++; + + } else { + // If nesting level exceeded - skip tail to the end. That's not ordinary + // situation and we should not care about content. + state.pos = state.max; } - state.pos++; state.cacheSet(pos, state.pos); }; @@ -110,10 +119,17 @@ ParserInline.prototype.tokenize = function (state) { var ok, i, rules = this.ruler.getRules(''), len = rules.length, - end = state.posMax; + end = state.posMax, + maxNesting = state.md.options.maxNesting; while (state.pos < end) { + // If nesting level exceeded - skip tail to the end. That's not ordinary + // situation and we should not care about content. + if (state.level >= maxNesting) { + state.pos = end; + break; + } // Try all possible rules. // On success, rule should: // diff --git a/lib/rules_block/blockquote.js b/lib/rules_block/blockquote.js index 99d2ef3..a83c0df 100644 --- a/lib/rules_block/blockquote.js +++ b/lib/rules_block/blockquote.js @@ -15,8 +15,6 @@ module.exports = function blockquote(state, startLine, endLine, silent) { // check the block quote marker if (state.src.charCodeAt(pos++) !== 0x3E/* > */) { return false; } - if (state.level >= state.md.options.maxNesting) { return false; } - // we know that it's going to be a valid blockquote, // so no point trying to find the end of it in silent mode if (silent) { return true; } diff --git a/lib/rules_block/deflist.js b/lib/rules_block/deflist.js index 996fb1e..5aa7b38 100644 --- a/lib/rules_block/deflist.js +++ b/lib/rules_block/deflist.js @@ -71,8 +71,6 @@ module.exports = function deflist(state, startLine, endLine, silent) { contentStart = skipMarker(state, nextLine); if (contentStart < 0) { return false; } - if (state.level >= state.md.options.maxNesting) { return false; } - // Start list listTokIdx = state.tokens.length; diff --git a/lib/rules_block/footnote.js b/lib/rules_block/footnote.js index 2516f5a..fde28a3 100644 --- a/lib/rules_block/footnote.js +++ b/lib/rules_block/footnote.js @@ -13,7 +13,6 @@ module.exports = function footnote(state, startLine, endLine, silent) { if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; } if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; } - if (state.level >= state.md.options.maxNesting) { return false; } for (pos = start + 2; pos < max; pos++) { if (state.src.charCodeAt(pos) === 0x20) { return false; } diff --git a/lib/rules_block/list.js b/lib/rules_block/list.js index d9d6ccb..dda8eb7 100644 --- a/lib/rules_block/list.js +++ b/lib/rules_block/list.js @@ -114,8 +114,6 @@ module.exports = function list(state, startLine, endLine, silent) { return false; } - if (state.level >= state.md.options.maxNesting) { return false; } - // We should terminate list on style change. Remember first one to compare. markerCharCode = state.src.charCodeAt(posAfterMarker - 1); diff --git a/lib/rules_inline/del.js b/lib/rules_inline/del.js index 15b3c9e..11b204b 100644 --- a/lib/rules_inline/del.js +++ b/lib/rules_inline/del.js @@ -51,7 +51,6 @@ module.exports = function(state, silent) { return true; } - if (state.level >= state.md.options.maxNesting) { return false; } stack = Math.floor(startCount / 2); if (stack <= 0) { return false; } state.pos = start + startCount; diff --git a/lib/rules_inline/emphasis.js b/lib/rules_inline/emphasis.js index 3cc08d1..45f359b 100644 --- a/lib/rules_inline/emphasis.js +++ b/lib/rules_inline/emphasis.js @@ -66,8 +66,6 @@ module.exports = function emphasis(state, silent) { return true; } - if (state.level >= state.md.options.maxNesting) { return false; } - state.pos = start + startCount; stack = [ startCount ]; diff --git a/lib/rules_inline/footnote_inline.js b/lib/rules_inline/footnote_inline.js index b7e9b98..4885abc 100644 --- a/lib/rules_inline/footnote_inline.js +++ b/lib/rules_inline/footnote_inline.js @@ -16,7 +16,6 @@ module.exports = function footnote_inline(state, silent) { if (start + 2 >= max) { return false; } if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; } if (state.src.charCodeAt(start + 1) !== 0x5B/* [ */) { return false; } - if (state.level >= state.md.options.maxNesting) { return false; } labelStart = start + 2; labelEnd = parseLinkLabel(state, start + 1); diff --git a/lib/rules_inline/footnote_ref.js b/lib/rules_inline/footnote_ref.js index c2df23a..d412ca5 100644 --- a/lib/rules_inline/footnote_ref.js +++ b/lib/rules_inline/footnote_ref.js @@ -17,7 +17,6 @@ module.exports = function footnote_ref(state, silent) { if (!state.env.footnotes || !state.env.footnotes.refs) { return false; } if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; } if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; } - if (state.level >= state.md.options.maxNesting) { return false; } for (pos = start + 2; pos < max; pos++) { if (state.src.charCodeAt(pos) === 0x20) { return false; } diff --git a/lib/rules_inline/ins.js b/lib/rules_inline/ins.js index 107cf54..1645822 100644 --- a/lib/rules_inline/ins.js +++ b/lib/rules_inline/ins.js @@ -51,7 +51,6 @@ module.exports = function(state, silent) { return true; } - if (state.level >= state.md.options.maxNesting) { return false; } stack = Math.floor(startCount / 2); if (stack <= 0) { return false; } state.pos = start + startCount; diff --git a/lib/rules_inline/links.js b/lib/rules_inline/links.js index f71c833..ae3a793 100644 --- a/lib/rules_inline/links.js +++ b/lib/rules_inline/links.js @@ -30,7 +30,6 @@ module.exports = function links(state, silent) { } if (marker !== 0x5B/* [ */) { return false; } - if (state.level >= state.md.options.maxNesting) { return false; } labelStart = start + 1; labelEnd = parseLinkLabel(state, start, !isImage); diff --git a/lib/rules_inline/mark.js b/lib/rules_inline/mark.js index 64d4c90..da588df 100644 --- a/lib/rules_inline/mark.js +++ b/lib/rules_inline/mark.js @@ -51,7 +51,6 @@ module.exports = function(state, silent) { return true; } - if (state.level >= state.md.options.maxNesting) { return false; } stack = Math.floor(startCount / 2); if (stack <= 0) { return false; } state.pos = start + startCount; diff --git a/lib/rules_inline/sub.js b/lib/rules_inline/sub.js index ccaf6d7..e468e67 100644 --- a/lib/rules_inline/sub.js +++ b/lib/rules_inline/sub.js @@ -14,7 +14,6 @@ module.exports = function sub(state, silent) { if (state.src.charCodeAt(start) !== 0x7E/* ~ */) { return false; } if (silent) { return false; } // don't run any pairs in validation mode if (start + 2 >= max) { return false; } - if (state.level >= state.md.options.maxNesting) { return false; } state.pos = start + 1; diff --git a/lib/rules_inline/sup.js b/lib/rules_inline/sup.js index d5d0ea3..8a184bd 100644 --- a/lib/rules_inline/sup.js +++ b/lib/rules_inline/sup.js @@ -14,7 +14,6 @@ module.exports = function sup(state, silent) { if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; } if (silent) { return false; } // don't run any pairs in validation mode if (start + 2 >= max) { return false; } - if (state.level >= state.md.options.maxNesting) { return false; } state.pos = start + 1;