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'; 'use strict';
module.exports = function parseLinkLabel(state, start) { module.exports = function parseLinkLabel(state, start, disableNested) {
var level, found, marker, var level, found, marker, prevPos,
labelEnd = -1, labelEnd = -1,
max = state.posMax, max = state.posMax,
oldPos = state.pos, oldPos = state.pos;
oldFlag = state.isInLabel;
if (state.isInLabel) { return -1; }
if (state.labelUnmatchedScopes) { if (state.labelUnmatchedScopes) {
state.labelUnmatchedScopes--; state.labelUnmatchedScopes--;
@ -20,14 +17,11 @@ module.exports = function parseLinkLabel(state, start) {
} }
state.pos = start + 1; state.pos = start + 1;
state.isInLabel = true;
level = 1; level = 1;
while (state.pos < max) { while (state.pos < max) {
marker = state.src.charCodeAt(state.pos); marker = state.src.charCodeAt(state.pos);
if (marker === 0x5B /* [ */) { if (marker === 0x5D /* ] */) {
level++;
} else if (marker === 0x5D /* ] */) {
level--; level--;
if (level === 0) { if (level === 0) {
found = true; found = true;
@ -35,7 +29,17 @@ module.exports = function parseLinkLabel(state, start) {
} }
} }
prevPos = state.pos;
state.parser.skipToken(state); 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) { if (found) {
@ -47,7 +51,6 @@ module.exports = function parseLinkLabel(state, start) {
// restore old state // restore old state
state.pos = oldPos; state.pos = oldPos;
state.isInLabel = oldFlag;
return labelEnd; 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; } if (state.level >= state.options.maxNesting) { return false; }
labelStart = start + 1; labelStart = start + 1;
labelEnd = parseLinkLabel(state, start); labelEnd = parseLinkLabel(state, start, !isImage);
// parser failed to find ']', so it's not a valid link // parser failed to find ']', so it's not a valid link
if (labelEnd < 0) { return false; } 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 // 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 this.linkLevel = 0; // Increment for each nesting link. Used to prevent
// nesting in definitions // 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> <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 src line: 5528
@ -4932,6 +4950,28 @@ src line: 5630
<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p> <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 src line: 5663

Loading…
Cancel
Save