Browse Source

Forbid nested brackets in references

This applies to footnotes/abbrs as well, because they are
designed to be implemented in the similar way.
pull/14/head
Alex Kocharin 10 years ago
parent
commit
f7edb05ef8
  1. 27
      lib/rules_core/abbr.js
  2. 20
      lib/rules_core/references.js
  3. 51
      test/fixtures/commonmark/bad.txt
  4. 36
      test/fixtures/commonmark/good.txt
  5. 11
      test/fixtures/markdown-it/abbr.txt
  6. 11
      test/fixtures/markdown-it/commonmark_extras.txt

27
lib/rules_core/abbr.js

@ -4,31 +4,36 @@
'use strict'; 'use strict';
var StateInline = require('../rules_inline/state_inline');
var parseLinkLabel = require('../helpers/parse_link_label');
function parseAbbr(str, parserInline, options, env) { function parseAbbr(str, parserInline, options, env) {
var state, labelEnd, pos, max, label, title; var pos, label, title, ch,
max = str.length,
labelEnd = -1;
if (str.charCodeAt(0) !== 0x2A/* * */) { return -1; } if (str.charCodeAt(0) !== 0x2A/* * */) { return -1; }
if (str.charCodeAt(1) !== 0x5B/* [ */) { return -1; } if (str.charCodeAt(1) !== 0x5B/* [ */) { return -1; }
if (str.indexOf(']:') === -1) { return -1; } if (str.indexOf(']:') === -1) { return -1; }
state = new StateInline(str, parserInline, options, env, []); for (pos = 2; pos < max; pos++) {
labelEnd = parseLinkLabel(state, 1); ch = str.charCodeAt(pos);
if (ch === 0x5B /* [ */) {
return -1;
} else if (ch === 0x5D /* ] */) {
labelEnd = pos;
break;
} else if (ch === 0x5C /* \ */) {
pos++;
}
}
if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return -1; } if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return -1; }
max = state.posMax;
// abbr title is always one line, so looking for ending "\n" here // abbr title is always one line, so looking for ending "\n" here
for (pos = labelEnd + 2; pos < max; pos++) { for (pos = labelEnd + 2; pos < max; pos++) {
if (state.src.charCodeAt(pos) === 0x0A) { break; } if (str.charCodeAt(pos) === 0x0A) { break; }
} }
label = str.slice(2, labelEnd); label = str.slice(2, labelEnd).replace(/\\(.)/g, '$1');
title = str.slice(labelEnd + 2, pos).trim(); title = str.slice(labelEnd + 2, pos).trim();
if (title.length === 0) { return -1; } if (title.length === 0) { return -1; }
if (!env.abbreviations) { env.abbreviations = {}; } if (!env.abbreviations) { env.abbreviations = {}; }

20
lib/rules_core/references.js

@ -2,25 +2,35 @@
var StateInline = require('../rules_inline/state_inline'); var StateInline = require('../rules_inline/state_inline');
var parseLinkLabel = require('../helpers/parse_link_label');
var parseLinkDestination = require('../helpers/parse_link_destination'); var parseLinkDestination = require('../helpers/parse_link_destination');
var parseLinkTitle = require('../helpers/parse_link_title'); var parseLinkTitle = require('../helpers/parse_link_title');
var normalizeReference = require('../helpers/normalize_reference'); var normalizeReference = require('../helpers/normalize_reference');
function parseReference(str, parser, options, env) { function parseReference(str, parser, options, env) {
var state, labelEnd, pos, max, code, start, href, title, label; var state, pos, code, start, href, title, label, ch, max,
labelEnd = -1;
if (str.charCodeAt(0) !== 0x5B/* [ */) { return -1; } if (str.charCodeAt(0) !== 0x5B/* [ */) { return -1; }
if (str.indexOf(']:') === -1) { return -1; } if (str.indexOf(']:') === -1) { return -1; }
state = new StateInline(str, parser, options, env, []); state = new StateInline(str, parser, options, env, []);
labelEnd = parseLinkLabel(state, 0); max = state.posMax;
if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return -1; } for (pos = 1; pos < max; pos++) {
ch = str.charCodeAt(pos);
if (ch === 0x5B /* [ */) {
return -1;
} else if (ch === 0x5D /* ] */) {
labelEnd = pos;
break;
} else if (ch === 0x5C /* \ */) {
pos++;
}
}
max = state.posMax; if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return -1; }
// [label]: destination 'title' // [label]: destination 'title'
// ^^^ skip optional whitespace here // ^^^ skip optional whitespace here

51
test/fixtures/commonmark/bad.txt

@ -74,40 +74,6 @@ error:
<p><a href="/uri">foo <em>bar [baz][ref]</em></a></p> <p><a href="/uri">foo <em>bar [baz][ref]</em></a></p>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5803
.
[foo][ref[bar]]
[ref[bar]]: /uri
.
<p>[foo][ref[bar]]</p>
<p>[ref[bar]]: /uri</p>
.
error:
<p><a href="/uri">foo</a></p>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5812
.
[[[foo]]]
[[[foo]]]: /url
.
<p>[[[foo]]]</p>
<p>[[[foo]]]: /url</p>
.
error:
<p><a href="/url">[[foo]]</a></p>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5923 src line: 5923
@ -232,20 +198,3 @@ error:
<p><img src="/url" alt="*foo* bar" title="title" /></p> <p><img src="/url" alt="*foo* bar" title="title" /></p>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 6173
.
![[foo]]
[[foo]]: /url "title"
.
<p>![[foo]]</p>
<p>[[foo]]: /url &quot;title&quot;</p>
.
error:
<p><img src="/url" alt="[foo]" title="title" /></p>

36
test/fixtures/commonmark/good.txt

@ -5080,6 +5080,30 @@ src line: 5794
<p>[ref[]: /uri</p> <p>[ref[]: /uri</p>
. .
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5803
.
[foo][ref[bar]]
[ref[bar]]: /uri
.
<p>[foo][ref[bar]]</p>
<p>[ref[bar]]: /uri</p>
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5812
.
[[[foo]]]
[[[foo]]]: /url
.
<p>[[[foo]]]</p>
<p>[[[foo]]]: /url</p>
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5821 src line: 5821
@ -5372,6 +5396,18 @@ src line: 6155
<p><img src="/url" alt="foo" title="title" /></p> <p><img src="/url" alt="foo" title="title" /></p>
. .
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 6173
.
![[foo]]
[[foo]]: /url "title"
.
<p>![[foo]]</p>
<p>[[foo]]: /url &quot;title&quot;</p>
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 6184 src line: 6184

11
test/fixtures/markdown-it/abbr.txt

@ -26,21 +26,12 @@ foo
They can contain arbitrary markup (see pandoc implementation): They can contain arbitrary markup (see pandoc implementation):
. .
*[`]:`]: foo *[`\]:`]: foo
\`]:\` \`]:\`
. .
<p><abbr title="foo">`]:`</abbr></p> <p><abbr title="foo">`]:`</abbr></p>
. .
Can contain matched brackets:
.
*[[abbr]]: foo
[abbr]
.
<p><abbr title="foo">[abbr]</abbr></p>
.
No empty abbreviations: No empty abbreviations:
. .

11
test/fixtures/markdown-it/commonmark_extras.txt

@ -8,15 +8,6 @@ Regression tests for link backtracking optimizations:
<p>[[some unrelated text <a href="foo">link</a></p> <p>[[some unrelated text <a href="foo">link</a></p>
. .
.
[[some unrelated text [[link]]
[[link]]: foo
.
<p>[[some unrelated text <a href="foo">[link]</a></p>
.
This is not a valid emphasis, because \n considered a whitespace: This is not a valid emphasis, because \n considered a whitespace:
@ -131,4 +122,4 @@ Should not throw exception on mailformed URI
[foo](<&#x25;test>) [foo](<&#x25;test>)
. .
<p><a href="%25test">foo</a></p> <p><a href="%25test">foo</a></p>
. .

Loading…
Cancel
Save