- Commit
- f8737b1c82981624b3263224dbf92fa6627f7205
- Parent
- 09d96cd0b6f352227f741c4fc9b0d82cbefcc012
- Author
- John MacFarlane <jgm@berkeley.edu>
- Date
latex writer: fix memory overflow.
We got an array overflow in enumerated lists nested more than
10 deep with start number =/= 1.
Found by google/oss-fuzz.
https://oss-fuzz.com/v2/testcase-detail/5546760854306816
This commit also ensures that we don't try to set `enum_` counters
that aren't defined by LaTeX (generally up to enumv).
Closes #210.
diff --git a/src/latex.c b/src/latex.c
@@ -220,11 +220,10 @@ static int S_get_enumlevel(cmark_node *node) {
static int S_render_node(cmark_renderer *renderer, cmark_node *node,
cmark_event_type ev_type, int options) {
int list_number;
+ int enumlevel;
char list_number_string[LIST_NUMBER_STRING_SIZE];
bool entering = (ev_type == CMARK_EVENT_ENTER);
cmark_list_type list_type;
- const char *roman_numerals[] = {"", "i", "ii", "iii", "iv", "v",
- "vi", "vii", "viii", "ix", "x"};
bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);
// avoid warning about unused parameter:
@@ -253,13 +252,24 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
CR();
list_number = cmark_node_get_list_start(node);
if (list_number > 1) {
- snprintf(list_number_string, LIST_NUMBER_STRING_SIZE, "%d",
- list_number);
- LIT("\\setcounter{enum");
- LIT((char *)roman_numerals[S_get_enumlevel(node)]);
- LIT("}{");
- OUT(list_number_string, false, NORMAL);
- LIT("}");
+ enumlevel = S_get_enumlevel(node);
+ // latex normally supports only five levels
+ if (enumlevel >= 1 && enumlevel <= 5) {
+ snprintf(list_number_string, LIST_NUMBER_STRING_SIZE, "%d",
+ list_number);
+ LIT("\\setcounter{enum");
+ switch(enumlevel) {
+ case 1: LIT("i"); break;
+ case 2: LIT("ii"); break;
+ case 3: LIT("iii"); break;
+ case 4: LIT("iv"); break;
+ case 5: LIT("v"); break;
+ default: LIT("i"); break;
+ }
+ LIT("}{");
+ OUT(list_number_string, false, NORMAL);
+ LIT("}");
+ }
CR();
}
} else {