Skip to content

Commit bfdc057

Browse files
Merge pull request #47 from apple/QuietMisdreaus/upstream-update
Update cmark-gfm base to 0.29.0.gfm.6
2 parents eb9a6a3 + c2479d6 commit bfdc057

File tree

9 files changed

+2563
-2470
lines changed

9 files changed

+2563
-2470
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ project(cmark-gfm)
44
set(PROJECT_VERSION_MAJOR 0)
55
set(PROJECT_VERSION_MINOR 29)
66
set(PROJECT_VERSION_PATCH 0)
7-
set(PROJECT_VERSION_GFM 3)
7+
set(PROJECT_VERSION_GFM 6)
88
set(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.gfm.${PROJECT_VERSION_GFM})
99

1010
include("FindAsan.cmake")

changelog.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
[0.29.0.gfm.6]
2+
* Fixed polynomial time complexity DoS vulnerability in autolink extension
3+
4+
[0.29.0.gfm.5]
5+
* Added xmpp: and mailto: support to the autolink extension
6+
7+
[0.29.0.gfm.4]
8+
* Remove `source` from list of HTML blocks
9+
110
[0.29.0.gfm.3]
211
* Fixed heap memory corruption vulnerabiliy via integer overflow per https://github.com/github/cmark-gfm/security/advisories/GHSA-mc3g-88wq-6f4x
312

extensions/autolink.c

Lines changed: 34 additions & 3 deletions
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

src/inlines.c

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ typedef struct bracket {
4747
bracket_type type;
4848
bool active;
4949
bool bracket_after;
50+
bool in_bracket[4];
5051
} bracket;
5152

5253
typedef struct subject{
@@ -532,6 +533,7 @@ static void push_bracket(subject *subj, bracket_type type, cmark_node *inl_text)
532533
bracket *b = (bracket *)subj->mem->calloc(1, sizeof(bracket));
533534
if (subj->last_bracket != NULL) {
534535
subj->last_bracket->bracket_after = true;
536+
memcpy(b->in_bracket, subj->last_bracket->in_bracket, sizeof(b->in_bracket));
535537
}
536538
b->type = type;
537539
b->active = true;
@@ -540,6 +542,7 @@ static void push_bracket(subject *subj, bracket_type type, cmark_node *inl_text)
540542
b->previous_delimiter = subj->last_delim;
541543
b->position = subj->pos;
542544
b->bracket_after = false;
545+
b->in_bracket[type] = true;
543546
subj->last_bracket = b;
544547
}
545548

@@ -1401,6 +1404,17 @@ static cmark_node *handle_close_bracket(cmark_parser *parser, subject *subj) {
14011404
}
14021405
opener = opener->previous;
14031406
}
1407+
bool in_image = false;
1408+
if (opener) {
1409+
in_image = opener->in_bracket[IMAGE];
1410+
}
1411+
bracket *opener2 = subj->last_bracket;
1412+
while (opener2 != opener) {
1413+
if (opener2->type == IMAGE) {
1414+
opener2->in_bracket[IMAGE] = in_image;
1415+
}
1416+
opener2 = opener2->previous;
1417+
}
14041418
}
14051419

14061420
return NULL;
@@ -1891,19 +1905,20 @@ cmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser) {
18911905
}
18921906

18931907
int cmark_inline_parser_in_bracket(cmark_inline_parser *parser, int type) {
1894-
for (bracket *b = parser->last_bracket; b; b = b->previous) {
1895-
if (b->active) {
1896-
switch (type) {
1897-
case 0:
1898-
return b->type == LINK;
1899-
case 1:
1900-
return b->type == IMAGE;
1901-
case 2:
1902-
return b->type == ATTRIBUTE;
1903-
}
1904-
}
1908+
bracket *b = parser->last_bracket;
1909+
if (!b) {
1910+
return 0;
1911+
}
1912+
switch (type) {
1913+
case 0:
1914+
return b->in_bracket[LINK];
1915+
case 1:
1916+
return b->in_bracket[IMAGE];
1917+
case 2:
1918+
return b->in_bracket[ATTRIBUTE];
1919+
default:
1920+
return 0;
19051921
}
1906-
return 0;
19071922
}
19081923

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

0 commit comments

Comments
 (0)