aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/mdoc_markdown.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-03-11 12:35:45 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-03-11 12:35:45 +0000
commit890cc9cbd6565ee3b92c304210f49013e9759f7e (patch)
treef16e7fd636ad2757d76b6fc7962c1492edfae820 /mdoc_markdown.c
parenta6c40a72a232a59361c880ec1ecddfbd5df8eaaa (diff)
downloadmandoc-890cc9cbd6565ee3b92c304210f49013e9759f7e.tar.gz
mandoc-890cc9cbd6565ee3b92c304210f49013e9759f7e.tar.zst
mandoc-890cc9cbd6565ee3b92c304210f49013e9759f7e.zip
In markdown, autolinks are dangerous. Different compilers disagree
with respect to what constitutes a valid autolink, and if a compiler deems an autolink invalid, the input turns into an unintended and potentially harmful raw HTML tag. So, never write autolinks. Instead of <link>, write [link](link). Instead of <addr>, write [addr](mailto:addr). Issue pointed out by bentley@, who also agrees with the general direction of the change.
Diffstat (limited to 'mdoc_markdown.c')
-rw-r--r--mdoc_markdown.c71
1 files changed, 49 insertions, 22 deletions
diff --git a/mdoc_markdown.c b/mdoc_markdown.c
index 1bf1c13c..6f80d70c 100644
--- a/mdoc_markdown.c
+++ b/mdoc_markdown.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_markdown.c,v 1.14 2017/03/08 19:23:43 schwarze Exp $ */
+/* $Id: mdoc_markdown.c,v 1.15 2017/03/11 12:35:45 schwarze Exp $ */
/*
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -43,6 +43,7 @@ static void md_rawword(const char *);
static void md_word(const char *);
static void md_named(const char *);
static void md_char(unsigned char);
+static void md_uri(const char *);
static int md_cond_head(struct roff_node *);
static int md_cond_body(struct roff_node *);
@@ -67,6 +68,7 @@ static int md_pre_Fo(struct roff_node *);
static int md_pre_In(struct roff_node *);
static int md_pre_It(struct roff_node *);
static int md_pre_Lk(struct roff_node *);
+static int md_pre_Mt(struct roff_node *);
static int md_pre_Nd(struct roff_node *);
static int md_pre_Nm(struct roff_node *);
static int md_pre_No(struct roff_node *);
@@ -211,7 +213,7 @@ static const struct md_act md_acts[MDOC_MAX + 1] = {
{ NULL, NULL, md_post_Lb, NULL, NULL }, /* Lb */
{ NULL, md_pre_Pp, NULL, NULL, NULL }, /* Lp */
{ NULL, md_pre_Lk, NULL, NULL, NULL }, /* Lk */
- { NULL, md_pre_raw, md_post_raw, "<", ">" }, /* Mt */
+ { NULL, md_pre_Mt, NULL, NULL, NULL }, /* Mt */
{ md_cond_body, md_pre_word, md_post_word, "{", "}" }, /* Brq */
{ md_cond_body, md_pre_word, md_post_word, "{", "}" }, /* Bro */
{ NULL, NULL, NULL, NULL, NULL }, /* Brc */
@@ -1279,39 +1281,64 @@ md_post_Lb(struct roff_node *n)
outflags |= MD_br;
}
+static void
+md_uri(const char *s)
+{
+ while (*s != '\0') {
+ if (strchr("%()<>", *s) != NULL) {
+ printf("%%%2.2hhX", *s);
+ outcount += 3;
+ } else {
+ putchar(*s);
+ outcount++;
+ }
+ s++;
+ }
+}
+
static int
md_pre_Lk(struct roff_node *n)
{
const struct roff_node *link, *descr;
- const unsigned char *s;
if ((link = n->child) == NULL)
return 0;
- if ((descr = link->next) != NULL) {
- md_rawword("[");
- outflags &= ~MD_spc;
- while (descr != NULL) {
- md_word(descr->string);
- descr = descr->next;
- }
- outflags &= ~MD_spc;
- md_rawword("](");
- } else
- md_rawword("<");
+ descr = link->next == NULL ? link : link->next;
+ md_rawword("[");
+ outflags &= ~MD_spc;
+ do {
+ md_word(descr->string);
+ descr = link->next == NULL ? NULL : descr->next;
+ } while (descr != NULL);
+ outflags &= ~MD_spc;
+ md_rawword("](");
+ md_uri(link->string);
+ outflags &= ~MD_spc;
+ md_rawword(")");
+ return 0;
+}
- for (s = link->string; *s != '\0'; s++) {
- if (strchr("%()<>", *s) != NULL) {
- printf("%%%2.2hhX", *s);
- outcount += 3;
- } else {
- putchar(*s);
+static int
+md_pre_Mt(struct roff_node *n)
+{
+ const struct roff_node *nch;
+
+ md_rawword("[");
+ outflags &= ~MD_spc;
+ for (nch = n->child; nch != NULL; nch = nch->next)
+ md_word(nch->string);
+ outflags &= ~MD_spc;
+ md_rawword("](mailto:");
+ for (nch = n->child; nch != NULL; nch = nch->next) {
+ md_uri(nch->string);
+ if (nch->next != NULL) {
+ putchar(' ');
outcount++;
}
}
-
outflags &= ~MD_spc;
- md_rawword(link->next == NULL ? ">" : ")");
+ md_rawword(")");
return 0;
}