Skip to content

Commit 5e8ad61

Browse files
Fix GHSL-2023-117: store cell index on node so that it doesn't need to be recomputed during rendering.
1 parent 1d17fa9 commit 5e8ad61

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

extensions/table.c

+22-16
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,23 @@ static int set_table_alignments(cmark_node *node, uint8_t *alignments) {
9898
return 1;
9999
}
100100

101+
static uint8_t get_cell_alignment(cmark_node *node) {
102+
if (!node || node->type != CMARK_NODE_TABLE_CELL)
103+
return 0;
104+
105+
const uint8_t *alignments = get_table_alignments(node->parent->parent);
106+
int i = node->as.custom_int;
107+
return alignments[i];
108+
}
109+
110+
static int set_cell_index(cmark_node *node, int i) {
111+
if (!node || node->type != CMARK_NODE_TABLE_CELL)
112+
return 0;
113+
114+
node->as.custom_int = i;
115+
return 1;
116+
}
117+
101118
static cmark_strbuf *unescape_pipes(cmark_mem *mem, unsigned char *string, bufsize_t len)
102119
{
103120
cmark_strbuf *res = (cmark_strbuf *)mem->calloc(1, sizeof(cmark_strbuf));
@@ -333,7 +350,6 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
333350
for (i = 0; i < marker_row->n_columns; ++i) {
334351
node_cell *node = &marker_row->cells[i];
335352
bool left = node->buf->ptr[0] == ':', right = node->buf->ptr[node->buf->size - 1] == ':';
336-
337353
if (left && right)
338354
alignments[i] = 'c';
339355
else if (left)
@@ -363,6 +379,7 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
363379
header_cell->end_column = parent_container->start_column + cell->end_offset;
364380
cmark_node_set_string_content(header_cell, (char *) cell->buf->ptr);
365381
cmark_node_set_syntax_extension(header_cell, self);
382+
set_cell_index(header_cell, i);
366383
}
367384
}
368385

@@ -412,12 +429,14 @@ static cmark_node *try_opening_table_row(cmark_syntax_extension *self,
412429
node->end_column = parent_container->start_column + cell->end_offset;
413430
cmark_node_set_string_content(node, (char *) cell->buf->ptr);
414431
cmark_node_set_syntax_extension(node, self);
432+
set_cell_index(node, i);
415433
}
416434

417435
for (; i < table_columns; ++i) {
418436
cmark_node *node = cmark_parser_add_child(
419437
parser, table_row_block, CMARK_NODE_TABLE_CELL, 0);
420438
cmark_node_set_syntax_extension(node, self);
439+
set_cell_index(node, i);
421440
}
422441
}
423442

@@ -602,13 +621,7 @@ static const char *xml_attr(cmark_syntax_extension *extension,
602621
cmark_node *node) {
603622
if (node->type == CMARK_NODE_TABLE_CELL) {
604623
if (cmark_gfm_extensions_get_table_row_is_header(node->parent)) {
605-
uint8_t *alignments = get_table_alignments(node->parent->parent);
606-
int i = 0;
607-
cmark_node *n;
608-
for (n = node->parent->first_child; n; n = n->next, ++i)
609-
if (n == node)
610-
break;
611-
switch (alignments[i]) {
624+
switch (get_cell_alignment(node)) {
612625
case 'l': return " align=\"left\"";
613626
case 'c': return " align=\"center\"";
614627
case 'r': return " align=\"right\"";
@@ -696,7 +709,6 @@ static void html_render(cmark_syntax_extension *extension,
696709
cmark_event_type ev_type, int options) {
697710
bool entering = (ev_type == CMARK_EVENT_ENTER);
698711
cmark_strbuf *html = renderer->html;
699-
cmark_node *n;
700712

701713
// XXX: we just monopolise renderer->opaque.
702714
struct html_table_state *table_state =
@@ -745,7 +757,6 @@ static void html_render(cmark_syntax_extension *extension,
745757
}
746758
}
747759
} else if (node->type == CMARK_NODE_TABLE_CELL) {
748-
uint8_t *alignments = get_table_alignments(node->parent->parent);
749760
if (entering) {
750761
cmark_html_render_cr(html);
751762
if (table_state->in_table_header) {
@@ -754,12 +765,7 @@ static void html_render(cmark_syntax_extension *extension,
754765
cmark_strbuf_puts(html, "<td");
755766
}
756767

757-
int i = 0;
758-
for (n = node->parent->first_child; n; n = n->next, ++i)
759-
if (n == node)
760-
break;
761-
762-
switch (alignments[i]) {
768+
switch (get_cell_alignment(node)) {
763769
case 'l': html_table_add_align(html, "left", options); break;
764770
case 'c': html_table_add_align(html, "center", options); break;
765771
case 'r': html_table_add_align(html, "right", options); break;

src/node.h

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ struct cmark_node {
105105
cmark_link link;
106106
cmark_custom custom;
107107
int html_block_type;
108+
int custom_int; // For extensions to store an int
108109
void *opaque;
109110
} as;
110111
};

0 commit comments

Comments
 (0)