Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use correct options in specs #1511

Merged
merged 13 commits into from Jul 2, 2019
57 changes: 32 additions & 25 deletions lib/marked.js
Expand Up @@ -14,10 +14,9 @@
var block = {
newline: /^\n+/,
code: /^( {4}[^\n]+\n*)+/,
fences: noop,
fences: /^ {0,3}(`{3,}|~{3,})([^`~\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,
hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
heading: /^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/,
nptable: noop,
heading: /^ {0,3}(#{1,6}) +([^\n]*?)(?: +#+)? *(?:\n+|$)/,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks OK

blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
list: /^( {0,3})(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
html: '^ {0,3}(?:' // optional indentation
Expand All @@ -31,9 +30,12 @@ var block = {
+ '|</(?!script|pre|style)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$)' // (7) closing tag
+ ')',
def: /^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,
nptable: noop,
table: noop,
lheading: /^([^\n]+)\n {0,3}(=|-){2,} *(?:\n+|$)/,
paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,
lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

// regex template, placeholders will be replaced according to different paragraph
// interruption rules of commonmark and the original markdown spec:
_paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html)[^\n]+)*)/,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

text: /^[^\n]+/
};

Expand Down Expand Up @@ -69,10 +71,14 @@ block.html = edit(block.html, 'i')
.replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
.getRegex();

block.paragraph = edit(block.paragraph)
block.paragraph = edit(block._paragraph)
.replace('hr', block.hr)
.replace('heading', block.heading)
.replace('lheading', block.lheading)
.replace('heading', ' {0,3}#{1,6} +')
.replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
.replace('blockquote', ' {0,3}>')
.replace('fences', ' {0,3}(?:`{3,}|~{3,})[^`\\n]*\\n')
.replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)')
.replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
.getRegex();

Expand All @@ -91,28 +97,18 @@ block.normal = merge({}, block);
*/

block.gfm = merge({}, block.normal, {
fences: /^ {0,3}(`{3,}|~{3,})([^`\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,
paragraph: /^/,
heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
nptable: /^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super-linear.

  1. The construct .*\|.* can be exploited through a run of |||...|. Can we replace with [^|]*|[^|]* ?
  2. I believe the same problem applies later in the (?:.*[^>\n ].* section.

table: /^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/
Copy link
Contributor

@davisjam davisjam Jul 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same genre of problem as the nptable.

if (/^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/.exec(' | \n' + ' '.repeat(50000))) {
  console.log('match');
}

(Note, here and elsewhere I'm just checking regexes, not full exploitability).

});

block.gfm.paragraph = edit(block.paragraph)
.replace('(?!', '(?!'
+ block.gfm.fences.source.replace('\\1', '\\2') + '|'
+ block.list.source.replace('\\1', '\\3') + '|')
.getRegex();

/**
* GFM + Tables Block Grammar
*/

block.tables = merge({}, block.gfm, {
nptable: /^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,
table: /^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/
});
block.tables = merge({}, block.gfm);

/**
* Pedantic grammar
* Pedantic grammar (original John Gruber's loose markdown specification)
*/

block.pedantic = merge({}, block.normal, {
Expand All @@ -126,7 +122,18 @@ block.pedantic = merge({}, block.normal, {
+ '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
+ '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
.getRegex(),
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
heading: /^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/,
fences: noop, // fences not supported
paragraph: edit(block.normal._paragraph)
.replace('hr', block.hr)
.replace('heading', ' *#{1,6} *[^\n]')
.replace('lheading', block.lheading)
.replace('blockquote', ' {0,3}>')
.replace('|fences', '')
.replace('|list', '')
.replace('|html', '')
.getRegex()
});

/**
Expand Down Expand Up @@ -233,7 +240,7 @@ Lexer.prototype.token = function(src, top) {
continue;
}

// fences (gfm)
// fences
if (cap = this.rules.fences.exec(src)) {
src = src.substring(cap[0].length);
this.tokens.push({
Expand Down Expand Up @@ -494,7 +501,7 @@ Lexer.prototype.token = function(src, top) {
src = src.substring(cap[0].length);
this.tokens.push({
type: 'heading',
depth: cap[2] === '=' ? 1 : 2,
depth: cap[2].charAt(0) === '=' ? 1 : 2,
text: cap[1]
});
continue;
Expand Down
8 changes: 7 additions & 1 deletion test/helpers/load.js
Expand Up @@ -79,11 +79,17 @@ function loadFiles(dir) {
switch (ext) {
case '.md': {
const content = fm(fs.readFileSync(absFile, 'utf8'));
const skip = content.attributes.skip;
delete content.attributes.skip;
const only = content.attributes.only;
delete content.attributes.only;
specs = [{
section: name,
markdown: content.body,
html: fs.readFileSync(absFile.replace(/[^.]+$/, 'html'), 'utf8'),
options: content.attributes
options: content.attributes,
only,
skip
}];
break;
}
Expand Down
33 changes: 11 additions & 22 deletions test/specs/commonmark/commonmark.0.29.json
Expand Up @@ -358,17 +358,15 @@
"example": 45,
"start_line": 915,
"end_line": 919,
"section": "ATX headings",
"shouldFail": true
"section": "ATX headings"
},
{
"markdown": "### foo \\###\n## foo #\\##\n# foo \\#\n",
"html": "<h3>foo ###</h3>\n<h2>foo ###</h2>\n<h1>foo #</h1>\n",
"example": 46,
"start_line": 925,
"end_line": 933,
"section": "ATX headings",
"shouldFail": true
"section": "ATX headings"
},
{
"markdown": "****\n## foo\n****\n",
Expand Down Expand Up @@ -427,8 +425,7 @@
"example": 53,
"start_line": 1046,
"end_line": 1055,
"section": "Setext headings",
"shouldFail": true
"section": "Setext headings"
},
{
"markdown": " Foo\n---\n\n Foo\n-----\n\n Foo\n ===\n",
Expand Down Expand Up @@ -508,8 +505,7 @@
"example": 63,
"start_line": 1186,
"end_line": 1196,
"section": "Setext headings",
"shouldFail": true
"section": "Setext headings"
},
{
"markdown": "- Foo\n---\n",
Expand Down Expand Up @@ -1650,8 +1646,7 @@
"example": 205,
"start_line": 3464,
"end_line": 3476,
"section": "Block quotes",
"shouldFail": true
"section": "Block quotes"
},
{
"markdown": "> foo\n bar\n",
Expand Down Expand Up @@ -2220,8 +2215,7 @@
"example": 274,
"start_line": 5005,
"end_line": 5011,
"section": "Lists",
"shouldFail": true
"section": "Lists"
},
{
"markdown": "The number of windows in my house is\n1. The number of doors is 6.\n",
Expand Down Expand Up @@ -2366,8 +2360,7 @@
"example": 291,
"start_line": 5379,
"end_line": 5397,
"section": "Lists",
"shouldFail": true
"section": "Lists"
},
{
"markdown": "- a\n",
Expand Down Expand Up @@ -4904,8 +4897,7 @@
"example": 598,
"start_line": 8787,
"end_line": 8791,
"section": "Autolinks",
"shouldFail": true
"section": "Autolinks"
},
{
"markdown": "<http://example.com/\\[\\>\n",
Expand Down Expand Up @@ -4953,8 +4945,7 @@
"example": 604,
"start_line": 8850,
"end_line": 8854,
"section": "Autolinks",
"shouldFail": true
"section": "Autolinks"
},
{
"markdown": "<m:abc>\n",
Expand All @@ -4978,17 +4969,15 @@
"example": 607,
"start_line": 8871,
"end_line": 8875,
"section": "Autolinks",
"shouldFail": true
"section": "Autolinks"
},
{
"markdown": "foo@bar.example.com\n",
"html": "<p>foo@bar.example.com</p>\n",
"example": 608,
"start_line": 8878,
"end_line": 8882,
"section": "Autolinks",
"shouldFail": true
"section": "Autolinks"
},
{
"markdown": "<a><bab><c2c>\n",
Expand Down