Browse Source

Forbid nested links, prefer inner one

pull/24/head
Alex Kocharin 10 years ago
parent
commit
08f2d3eb4d
  1. 25
      lib/helpers/parse_link_label.js
  2. 2
      lib/rules_inline/links.js
  3. 4
      lib/rules_inline/state_inline.js
  4. 60
      test/fixtures/commonmark/bad.txt
  5. 40
      test/fixtures/commonmark/good.txt

25
lib/helpers/parse_link_label.js

@ -5,14 +5,11 @@
//
'use strict';
module.exports = function parseLinkLabel(state, start) {
var level, found, marker,
module.exports = function parseLinkLabel(state, start, disableNested) {
var level, found, marker, prevPos,
labelEnd = -1,
max = state.posMax,
oldPos = state.pos,
oldFlag = state.isInLabel;
if (state.isInLabel) { return -1; }
oldPos = state.pos;
if (state.labelUnmatchedScopes) {
state.labelUnmatchedScopes--;
@ -20,14 +17,11 @@ module.exports = function parseLinkLabel(state, start) {
}
state.pos = start + 1;
state.isInLabel = true;
level = 1;
while (state.pos < max) {
marker = state.src.charCodeAt(state.pos);
if (marker === 0x5B /* [ */) {
level++;
} else if (marker === 0x5D /* ] */) {
if (marker === 0x5D /* ] */) {
level--;
if (level === 0) {
found = true;
@ -35,7 +29,17 @@ module.exports = function parseLinkLabel(state, start) {
}
}
prevPos = state.pos;
state.parser.skipToken(state);
if (marker === 0x5B /* [ */) {
if (prevPos === state.pos - 1) {
// increase level if we find text `[`, which is not a part of any token
level++;
} else if (disableNested) {
state.pos = oldPos;
return -1;
}
}
}
if (found) {
@ -47,7 +51,6 @@ module.exports = function parseLinkLabel(state, start) {
// restore old state
state.pos = oldPos;
state.isInLabel = oldFlag;
return labelEnd;
};

2
lib/rules_inline/links.js

@ -34,7 +34,7 @@ module.exports = function links(state, silent) {
if (state.level >= state.options.maxNesting) { return false; }
labelStart = start + 1;
labelEnd = parseLinkLabel(state, start);
labelEnd = parseLinkLabel(state, start, !isImage);
// parser failed to find ']', so it's not a valid link
if (labelEnd < 0) { return false; }

4
lib/rules_inline/state_inline.js

@ -20,10 +20,6 @@ function StateInline(src, parserInline, options, env, outTokens) {
// Link parser state vars
this.isInLabel = false; // Set true when seek link label - we should disable
// "paired" rules (emphasis, strikes) to not skip
// tailing `]`
this.linkLevel = 0; // Increment for each nesting link. Used to prevent
// nesting in definitions

60
test/fixtures/commonmark/bad.txt

@ -1,60 +0,0 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5513
.
[foo [bar](/uri)](/uri)
.
<p>[foo <a href="/uri">bar</a>](/uri)</p>
.
error:
<p><a href="/uri">foo <a href="/uri">bar</a></a></p>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5519
.
[foo *[bar [baz](/uri)](/uri)*](/uri)
.
<p>[foo <em>[bar <a href="/uri">baz</a>](/uri)</em>](/uri)</p>
.
error:
<p><a href="/uri">foo <em><a href="/uri">bar <a href="/uri">baz</a></a></em></a></p>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5640
.
[foo [bar](/uri)][ref]
[ref]: /uri
.
<p>[foo <a href="/uri">bar</a>]<a href="/uri">ref</a></p>
.
error:
<p><a href="/uri">foo <a href="/uri">bar</a></a></p>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5648
.
[foo *bar [baz][ref]*][ref]
[ref]: /uri
.
<p>[foo <em>bar <a href="/uri">baz</a></em>]<a href="/uri">ref</a></p>
.
error:
<p><a href="/uri">foo <em>bar [baz][ref]</em></a></p>

40
test/fixtures/commonmark/good.txt

@ -4832,6 +4832,24 @@ src line: 5505
<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p>
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5513
.
[foo [bar](/uri)](/uri)
.
<p>[foo <a href="/uri">bar</a>](/uri)</p>
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5519
.
[foo *[bar [baz](/uri)](/uri)*](/uri)
.
<p>[foo <em>[bar <a href="/uri">baz</a>](/uri)</em>](/uri)</p>
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5528
@ -4932,6 +4950,28 @@ src line: 5630
<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p>
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5640
.
[foo [bar](/uri)][ref]
[ref]: /uri
.
<p>[foo <a href="/uri">bar</a>]<a href="/uri">ref</a></p>
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5648
.
[foo *bar [baz][ref]*][ref]
[ref]: /uri
.
<p>[foo <em>bar <a href="/uri">baz</a></em>]<a href="/uri">ref</a></p>
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5663

Loading…
Cancel
Save