Skip to content

Commit

Permalink
Fix conflict in parsing permissive autolinks and ordinary links.
Browse files Browse the repository at this point in the history
The issues is caused by the fact that we do not know exact position
of permissive auto-link in time of md_collect_marks() because there
is no syntax to mark its end on the 1st place.

This causes that eventually, the closer mark in ctx->marks[] can be
out-of-order somewhat.

As a consequence, if some other mark range (e.g. ordinary link)
shadows the auto-link, the closer mark may be left outside the shadowed
range and survive till the phase when we generate the output.

We fix by using an extra mark flag to remember we did really output
the opener mark, and output the closer only in such case.

Fixes mity#53.
  • Loading branch information
mity authored and ec1oud committed Apr 17, 2019
1 parent c2693fd commit 5d2f663
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
19 changes: 15 additions & 4 deletions md4c/md4c.c
Original file line number Diff line number Diff line change
Expand Up @@ -2497,6 +2497,7 @@ struct MD_MARK_tag {
#define MD_MARK_EMPH_MODULO3_2 (0x40 | 0x80)
#define MD_MARK_EMPH_MODULO3_MASK (0x40 | 0x80)
#define MD_MARK_AUTOLINK 0x20 /* Distinguisher for '<', '>'. */
#define MD_MARK_VALIDPERMISSIVEAUTOLINK 0x20 /* For permissive autolinks. */


static MD_MARK*
Expand Down Expand Up @@ -3988,11 +3989,20 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
case ':': /* Permissive URL autolink. */
case '.': /* Permissive WWW autolink. */
{
const MD_MARK* opener = ((mark->flags & MD_MARK_OPENER) ? mark : &ctx->marks[mark->prev]);
const MD_MARK* closer = &ctx->marks[opener->next];
MD_MARK* opener = ((mark->flags & MD_MARK_OPENER) ? mark : &ctx->marks[mark->prev]);
MD_MARK* closer = &ctx->marks[opener->next];
const CHAR* dest = STR(opener->end);
SZ dest_size = closer->beg - opener->end;

/* For permissive auto-links we do not know closer mark
* position at the time of md_collect_marks(), therefore
* it can be out-of-order in ctx->marks[].
*
* With this flag, we make sure that we output the closer
* only if we processed the opener. */
if(mark->flags & MD_MARK_OPENER)
closer->flags |= MD_MARK_VALIDPERMISSIVEAUTOLINK;

if(opener->ch == '@' || opener->ch == '.') {
dest_size += 7;
MD_TEMP_BUFFER(dest_size * sizeof(CHAR));
Expand All @@ -4003,8 +4013,9 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
dest = ctx->buffer;
}

MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER),
MD_SPAN_A, dest, dest_size, TRUE, NULL, 0));
if(closer->flags & MD_MARK_VALIDPERMISSIVEAUTOLINK)
MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER),
MD_SPAN_A, dest, dest_size, TRUE, NULL, 0));
break;
}

Expand Down
15 changes: 15 additions & 0 deletions test/permissive-url-autolinks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,18 @@ Anonymous FTP is available at ftp://foo.bar.baz.
<p>(Visit <a href="https://encrypted.google.com/search?q=Markup+(business)">https://encrypted.google.com/search?q=Markup+(business)</a>)</p>
<p>Anonymous FTP is available at <a href="ftp://foo.bar.baz">ftp://foo.bar.baz</a>.</p>
````````````````````````````````


## GitHub Issues

### [Issue 53](https://github.com/mity/md4c/issues/53)
```````````````````````````````` example
This is [link](http://github.com/).
.
<p>This is <a href="http://github.com/">link</a>.</p>
````````````````````````````````
```````````````````````````````` example
This is [link](http://github.com/)X
.
<p>This is <a href="http://github.com/">link</a>X</p>
````````````````````````````````
15 changes: 15 additions & 0 deletions test/permissive-www-autolinks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,18 @@ www.commonmark.org/he<lp
.
<p><a href="http://www.commonmark.org/he">www.commonmark.org/he</a>&lt;lp</p>
````````````````````````````````


## GitHub Issues

### [Issue 53](https://github.com/mity/md4c/issues/53)
```````````````````````````````` example
This is [link](www.github.com/).
.
<p>This is <a href="www.github.com/">link</a>.</p>
````````````````````````````````
```````````````````````````````` example
This is [link](www.github.com/)X
.
<p>This is <a href="www.github.com/">link</a>X</p>
````````````````````````````````

0 comments on commit 5d2f663

Please sign in to comment.