Skip to content

Commit cd2f088

Browse files
committed
Merge remote-tracking branch 'origin/fix-GHSL-2022-089'
2 parents 39ca0d9 + d1032f2 commit cd2f088

File tree

6 files changed

+73
-6
lines changed

6 files changed

+73
-6
lines changed

api_test/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,7 @@ int main() {
11331133
int retval;
11341134
test_batch_runner *runner = test_batch_runner_new();
11351135

1136+
cmark_init_standard_node_flags();
11361137
version(runner);
11371138
constructor(runner);
11381139
accessors(runner);

extensions/table.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#include "table.h"
1212
#include "cmark-gfm-core-extensions.h"
1313

14+
// Custom node flag, initialized in `create_table_extension`.
15+
static cmark_node__internal_flags CMARK_NODE__TABLE_VISITED;
16+
1417
cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,
1518
CMARK_NODE_TABLE_CELL;
1619

@@ -240,6 +243,10 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
240243
const char *parent_string;
241244
uint16_t i;
242245

246+
if (parent_container->flags & CMARK_NODE__TABLE_VISITED) {
247+
return parent_container;
248+
}
249+
243250
if (!scan_table_start(input, len, cmark_parser_get_first_nonspace(parser))) {
244251
return parent_container;
245252
}
@@ -267,6 +274,7 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
267274
free_table_row(parser->mem, marker_row);
268275
free_table_row(parser->mem, header_row);
269276
cmark_arena_pop();
277+
parent_container->flags |= CMARK_NODE__TABLE_VISITED;
270278
return parent_container;
271279
}
272280

@@ -785,6 +793,7 @@ static int escape(cmark_syntax_extension *self, cmark_node *node, int c) {
785793
cmark_syntax_extension *create_table_extension(void) {
786794
cmark_syntax_extension *self = cmark_syntax_extension_new("table");
787795

796+
cmark_register_node_flag(&CMARK_NODE__TABLE_VISITED);
788797
cmark_syntax_extension_set_match_block_func(self, matches);
789798
cmark_syntax_extension_set_open_block_func(self, try_opening_table_block);
790799
cmark_syntax_extension_set_get_type_string_func(self, get_type_string);

src/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ int main(int argc, char *argv[]) {
139139
}
140140
#endif
141141

142+
cmark_init_standard_node_flags();
142143
cmark_gfm_core_extensions_ensure_registered();
143144

144145
#ifdef USE_PLEDGE

src/node.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,40 @@ static void S_node_unlink(cmark_node *node);
99

1010
#define NODE_MEM(node) cmark_node_mem(node)
1111

12+
cmark_node__internal_flags CMARK_NODE__OPEN;
13+
cmark_node__internal_flags CMARK_NODE__LAST_LINE_BLANK;
14+
cmark_node__internal_flags CMARK_NODE__LAST_LINE_CHECKED;
15+
16+
void cmark_register_node_flag(cmark_node__internal_flags *flags) {
17+
static uint8_t shift = 0;
18+
19+
// flags should be a pointer to a global variable and this function
20+
// should only be called once to initialize its value.
21+
if (*flags) {
22+
fprintf(stderr, "flag initialization error in cmark_register_node_flag\n");
23+
abort();
24+
}
25+
26+
// Check that we haven't run out of bits.
27+
if (shift >= 8 * sizeof(cmark_node__internal_flags)) {
28+
fprintf(stderr, "too many flags in cmark_register_node_flag\n");
29+
abort();
30+
}
31+
32+
*flags = (cmark_node__internal_flags)1 << shift;
33+
shift++;
34+
}
35+
36+
void cmark_init_standard_node_flags() {
37+
static int initialized = 0;
38+
if (!initialized) {
39+
initialized = 1;
40+
cmark_register_node_flag(&CMARK_NODE__OPEN);
41+
cmark_register_node_flag(&CMARK_NODE__LAST_LINE_BLANK);
42+
cmark_register_node_flag(&CMARK_NODE__LAST_LINE_CHECKED);
43+
}
44+
}
45+
1246
bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type) {
1347
if (child_type == CMARK_NODE_DOCUMENT) {
1448
return false;

src/node.h

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,7 @@ typedef struct {
4848
cmark_chunk on_exit;
4949
} cmark_custom;
5050

51-
enum cmark_node__internal_flags {
52-
CMARK_NODE__OPEN = (1 << 0),
53-
CMARK_NODE__LAST_LINE_BLANK = (1 << 1),
54-
CMARK_NODE__LAST_LINE_CHECKED = (1 << 2),
55-
};
51+
typedef uint16_t cmark_node__internal_flags;
5652

5753
struct cmark_node {
5854
cmark_strbuf content;
@@ -72,7 +68,7 @@ struct cmark_node {
7268
int end_column;
7369
int internal_offset;
7470
uint16_t type;
75-
uint16_t flags;
71+
cmark_node__internal_flags flags;
7672

7773
cmark_syntax_extension *extension;
7874

@@ -95,6 +91,30 @@ struct cmark_node {
9591
} as;
9692
};
9793

94+
/**
95+
* Syntax extensions can use this function to register a custom node
96+
* flag. The flags are stored in the `flags` field of the `cmark_node`
97+
* struct. The `flags` parameter should be the address of a global variable
98+
* which will store the flag value.
99+
*/
100+
CMARK_GFM_EXPORT
101+
void cmark_register_node_flag(cmark_node__internal_flags *flags);
102+
103+
/**
104+
* Standard node flags. (Initialized using `cmark_init_standard_node_flags`.)
105+
*/
106+
extern cmark_node__internal_flags CMARK_NODE__OPEN;
107+
extern cmark_node__internal_flags CMARK_NODE__LAST_LINE_BLANK;
108+
extern cmark_node__internal_flags CMARK_NODE__LAST_LINE_CHECKED;
109+
110+
/**
111+
* Uses `cmark_register_node_flag` to initialize the standard node flags.
112+
* This function should be called at program startup time. Calling it
113+
* multiple times has no additional effect.
114+
*/
115+
CMARK_GFM_EXPORT
116+
void cmark_init_standard_node_flags();
117+
98118
static CMARK_INLINE cmark_mem *cmark_node_mem(cmark_node *node) {
99119
return node->content.mem;
100120
}

test/cmark.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def pipe_through_prog(prog, text):
1313

1414
def parse(lib, extlib, text, extensions):
1515
cmark_gfm_core_extensions_ensure_registered = extlib.cmark_gfm_core_extensions_ensure_registered
16+
cmark_init_standard_node_flags = lib.cmark_init_standard_node_flags
1617

1718
find_syntax_extension = lib.cmark_find_syntax_extension
1819
find_syntax_extension.restype = c_void_p
@@ -32,6 +33,7 @@ def parse(lib, extlib, text, extensions):
3233
parser_finish.restype = c_void_p
3334
parser_finish.argtypes = [c_void_p]
3435

36+
cmark_init_standard_node_flags()
3537
cmark_gfm_core_extensions_ensure_registered()
3638

3739
parser = parser_new(0)

0 commit comments

Comments
 (0)