Skip to content

Commit 09839b2

Browse files
authored
Merge pull request #25 from kivikakk/latest-upstream
Latest upstream
2 parents d2ece94 + f7b2347 commit 09839b2

File tree

7 files changed

+2510
-2462
lines changed

7 files changed

+2510
-2462
lines changed

cbits/autolink.c

+34-3
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,22 @@ static cmark_node *match(cmark_syntax_extension *ext, cmark_parser *parser,
269269
// inline was finished in inlines.c.
270270
}
271271

272+
static bool validate_protocol(char protocol[], uint8_t *data, int rewind) {
273+
size_t len = strlen(protocol);
274+
275+
// Check that the protocol matches
276+
for (int i = 1; i <= len; i++) {
277+
if (data[-rewind - i] != protocol[len - i]) {
278+
return false;
279+
}
280+
}
281+
282+
char prev_char = data[-rewind - len - 1];
283+
284+
// Make sure the character before the protocol is non-alphanumeric
285+
return !cmark_isalnum(prev_char);
286+
}
287+
272288
static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset, int depth) {
273289
// postprocess_text can recurse very deeply if there is a very long line of
274290
// '@' only. Stop at a reasonable depth to ensure it cannot crash.
@@ -278,6 +294,8 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset,
278294
uint8_t *data = text->as.literal.data,
279295
*at;
280296
size_t size = text->as.literal.len;
297+
bool auto_mailto = true;
298+
bool is_xmpp = false;
281299
int rewind, max_rewind,
282300
nb = 0, np = 0, ns = 0;
283301

@@ -304,8 +322,18 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset,
304322
if (strchr(".+-_", c) != NULL)
305323
continue;
306324

307-
if (c == '/')
308-
ns++;
325+
if (strchr(":", c) != NULL) {
326+
if (validate_protocol("mailto:", data, rewind)) {
327+
auto_mailto = false;
328+
continue;
329+
}
330+
331+
if (validate_protocol("xmpp:", data, rewind)) {
332+
auto_mailto = false;
333+
is_xmpp = true;
334+
continue;
335+
}
336+
}
309337

310338
break;
311339
}
@@ -325,6 +353,8 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset,
325353
nb++;
326354
else if (c == '.' && link_end < size - 1 && cmark_isalnum(data[link_end + 1]))
327355
np++;
356+
else if (c == '/' && is_xmpp)
357+
continue;
328358
else if (c != '-' && c != '_')
329359
break;
330360
}
@@ -347,7 +377,8 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset,
347377
cmark_node *link_node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);
348378
cmark_strbuf buf;
349379
cmark_strbuf_init(parser->mem, &buf, 10);
350-
cmark_strbuf_puts(&buf, "mailto:");
380+
if (auto_mailto)
381+
cmark_strbuf_puts(&buf, "mailto:");
351382
cmark_strbuf_put(&buf, data - rewind, (bufsize_t)(link_end + rewind));
352383
link_node->as.link.url = cmark_chunk_buf_detach(&buf);
353384

cbits/cmark-gfm_version.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef CMARK_GFM_VERSION_H
22
#define CMARK_GFM_VERSION_H
33

4-
#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 0)
5-
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.0"
4+
#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 6)
5+
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.6"
66

77
#endif

cbits/inlines.c

+29-4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ typedef struct bracket {
4141
bool image;
4242
bool active;
4343
bool bracket_after;
44+
bool in_bracket_image0;
45+
bool in_bracket_image1;
4446
} bracket;
4547

4648
typedef struct subject{
@@ -516,6 +518,8 @@ static void push_bracket(subject *subj, bool image, cmark_node *inl_text) {
516518
bracket *b = (bracket *)subj->mem->calloc(1, sizeof(bracket));
517519
if (subj->last_bracket != NULL) {
518520
subj->last_bracket->bracket_after = true;
521+
b->in_bracket_image0 = subj->last_bracket->in_bracket_image0;
522+
b->in_bracket_image1 = subj->last_bracket->in_bracket_image1;
519523
}
520524
b->image = image;
521525
b->active = true;
@@ -524,6 +528,11 @@ static void push_bracket(subject *subj, bool image, cmark_node *inl_text) {
524528
b->previous_delimiter = subj->last_delim;
525529
b->position = subj->pos;
526530
b->bracket_after = false;
531+
if (image) {
532+
b->in_bracket_image1 = true;
533+
} else {
534+
b->in_bracket_image0 = true;
535+
}
527536
subj->last_bracket = b;
528537
}
529538

@@ -1254,6 +1263,17 @@ static cmark_node *handle_close_bracket(cmark_parser *parser, subject *subj) {
12541263
}
12551264
opener = opener->previous;
12561265
}
1266+
bool in_bracket_image1 = false;
1267+
if (opener) {
1268+
in_bracket_image1 = opener->in_bracket_image1;
1269+
}
1270+
bracket *opener2 = subj->last_bracket;
1271+
while (opener2 != opener) {
1272+
if (opener2->image) {
1273+
opener2->in_bracket_image1 = in_bracket_image1;
1274+
}
1275+
opener2 = opener2->previous;
1276+
}
12571277
}
12581278

12591279
return NULL;
@@ -1662,10 +1682,15 @@ cmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser) {
16621682
}
16631683

16641684
int cmark_inline_parser_in_bracket(cmark_inline_parser *parser, int image) {
1665-
for (bracket *b = parser->last_bracket; b; b = b->previous)
1666-
if (b->active && b->image == (image != 0))
1667-
return 1;
1668-
return 0;
1685+
bracket *b = parser->last_bracket;
1686+
if (!b) {
1687+
return 0;
1688+
}
1689+
if (image != 0) {
1690+
return b->in_bracket_image1;
1691+
} else {
1692+
return b->in_bracket_image0;
1693+
}
16691694
}
16701695

16711696
void cmark_node_unput(cmark_node *node, int n) {

0 commit comments

Comments
 (0)