From df147e98df6210511b3569d51e02b021ef34063b Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Fri, 31 Jan 2020 23:33:28 -0800 Subject: [PATCH] Avoid use of VLAs --- sam.c | 6 +++--- text-regex-tre.c | 2 +- text-regex.c | 4 ++-- text-regex.h | 2 ++ ui-terminal.c | 32 +++++++++++++++++--------------- view.c | 13 +++++++++++-- vis-digraph.c | 8 ++++++-- 7 files changed, 42 insertions(+), 25 deletions(-) diff --git a/sam.c b/sam.c index 5b4b636..0900c76 100644 --- a/sam.c +++ b/sam.c @@ -1389,9 +1389,9 @@ static int extract(Vis *vis, Win *win, Command *cmd, const char *argv[], Selecti bool trailing_match = false; size_t start = range->start, end = range->end, last_start = EPOS; size_t nsub = 1 + text_regex_nsub(cmd->regex); - if (nsub > 10) - nsub = 10; - RegexMatch match[nsub]; + if (nsub > MAX_REGEX_SUB) + nsub = MAX_REGEX_SUB; + RegexMatch match[MAX_REGEX_SUB]; while (start < end || trailing_match) { trailing_match = false; char c; diff --git a/text-regex-tre.c b/text-regex-tre.c index da377b4..eccbafb 100644 --- a/text-regex-tre.c +++ b/text-regex-tre.c @@ -136,7 +136,7 @@ int text_search_range_forward(Text *txt, size_t pos, size_t len, Regex *r, size_ r->it = text_iterator_get(txt, pos); r->end = pos+len; - regmatch_t match[nmatch]; + regmatch_t match[MAX_REGEX_SUB]; int ret = tre_reguexec(&r->regex, &r->str_source, nmatch, match, eflags); if (!ret) { for (size_t i = 0; i < nmatch; i++) { diff --git a/text-regex.c b/text-regex.c index 56ecafc..7c6812e 100644 --- a/text-regex.c +++ b/text-regex.c @@ -45,7 +45,7 @@ int text_search_range_forward(Text *txt, size_t pos, size_t len, Regex *r, size_ return REG_NOMATCH; char *cur = buf, *end = buf + len; int ret = REG_NOMATCH; - regmatch_t match[nmatch]; + regmatch_t match[MAX_REGEX_SUB]; for (size_t junk = len; len > 0; len -= junk, pos += junk) { ret = regexec(&r->regex, cur, nmatch, match, eflags); if (!ret) { @@ -73,7 +73,7 @@ int text_search_range_backward(Text *txt, size_t pos, size_t len, Regex *r, size return REG_NOMATCH; char *cur = buf, *end = buf + len; int ret = REG_NOMATCH; - regmatch_t match[nmatch]; + regmatch_t match[MAX_REGEX_SUB]; for (size_t junk = len; len > 0; len -= junk, pos += junk) { char *next; if (!regexec(&r->regex, cur, nmatch, match, eflags)) { diff --git a/text-regex.h b/text-regex.h index 45054c8..dd87c1c 100644 --- a/text-regex.h +++ b/text-regex.h @@ -9,6 +9,8 @@ #endif #include "text.h" +#define MAX_REGEX_SUB 10 + typedef struct Regex Regex; typedef Filerange RegexMatch; diff --git a/ui-terminal.c b/ui-terminal.c index bcf4f48..b939947 100644 --- a/ui-terminal.c +++ b/ui-terminal.c @@ -198,11 +198,11 @@ static void ui_draw_line(UiTerm *tui, int x, int y, char c, enum UiStyle style_i if (x < 0 || x >= tui->width || y < 0 || y >= tui->height) return; CellStyle style = tui->styles[style_id]; - Cell (*cells)[tui->width] = (void*)tui->cells; + Cell *cells = tui->cells + y * tui->width; while (x < tui->width) { - cells[y][x].data[0] = c; - cells[y][x].data[1] = '\0'; - cells[y][x].style = style; + cells[x].data[0] = c; + cells[x].data[1] = '\0'; + cells[x].style = style; x++; } } @@ -213,17 +213,17 @@ static void ui_draw_string(UiTerm *tui, int x, int y, const char *str, UiTermWin return; CellStyle style = tui->styles[(win ? win->id : 0)*UI_STYLE_MAX + style_id]; // FIXME: does not handle double width characters etc, share code with view.c? - Cell (*cells)[tui->width] = (void*)tui->cells; - const size_t cell_size = sizeof(cells[0][0].data)-1; + Cell *cells = tui->cells + y * tui->width; + const size_t cell_size = sizeof(cells[0].data)-1; for (const char *next = str; *str && x < tui->width; str = next) { do next++; while (!ISUTF8(*next)); size_t len = next - str; if (!len) break; len = MIN(len, cell_size); - strncpy(cells[y][x].data, str, len); - cells[y][x].data[len] = '\0'; - cells[y][x].style = style; + strncpy(cells[x].data, str, len); + cells[x].data[len] = '\0'; + cells[x].style = style; x++; } } @@ -232,7 +232,6 @@ static void ui_window_draw(UiWin *w) { UiTermWin *win = (UiTermWin*)w; UiTerm *ui = win->ui; View *view = win->win->view; - Cell (*cells)[ui->width] = (void*)ui->cells; int width = win->width, height = win->height; const Line *line = view_lines_first(view); bool status = win->options & UI_OPTION_STATUSBAR; @@ -250,9 +249,10 @@ static void ui_window_draw(UiWin *w) { Selection *sel = view_selections_primary_get(view); const Line *cursor_line = view_cursors_line_get(sel); size_t cursor_lineno = cursor_line->lineno; - char buf[sidebar_width+1]; + char buf[(sizeof(size_t) * CHAR_BIT + 2) / 3 + 1]; int x = win->x, y = win->y; int view_width = view_width_get(view); + Cell *cells = ui->cells + y * ui->width; if (x + sidebar_width + view_width > ui->width) view_width = ui->width - x - sidebar_width; for (const Line *l = line; l; l = l->next) { @@ -276,7 +276,8 @@ static void ui_window_draw(UiWin *w) { prev_lineno = l->lineno; } debug("draw-window: [%d][%d] ... cells[%d][%d]\n", y, x+sidebar_width, y, view_width); - memcpy(&cells[y++][x+sidebar_width], l->cells, sizeof(Cell) * view_width); + memcpy(&cells[x+sidebar_width], l->cells, sizeof(Cell) * view_width); + cells += ui->width; } } @@ -299,7 +300,6 @@ static void ui_arrange(Ui *ui, enum UiLayout layout) { debug("ui-arrange\n"); UiTerm *tui = (UiTerm*)ui; tui->layout = layout; - Cell (*cells)[tui->width] = (void*)tui->cells; int n = 0, m = !!tui->info[0], x = 0, y = 0; for (UiTermWin *win = tui->windows; win; win = win->next) { if (win->options & UI_OPTION_ONELINE) @@ -325,9 +325,11 @@ static void ui_arrange(Ui *ui, enum UiLayout layout) { ui_window_move(win, x, y); x += w; if (n) { + Cell *cells = tui->cells; for (int i = 0; i < max_height; i++) { - strcpy(cells[i][x].data,"│"); - cells[i][x].style = tui->styles[UI_STYLE_SEPARATOR]; + strcpy(cells[x].data,"│"); + cells[x].style = tui->styles[UI_STYLE_SEPARATOR]; + cells += tui->width; } x++; } diff --git a/view.c b/view.c index 1bffb4f..d69f488 100644 --- a/view.c +++ b/view.c @@ -55,6 +55,7 @@ struct Selection { struct View { Text *text; /* underlying text management */ + char *textbuf; /* scratch buffer used for drawing */ UiWin *ui; /* corresponding ui window */ Cell cell_blank; /* used for empty/blank cells */ int width, height; /* size of display area */ @@ -328,7 +329,7 @@ void view_draw(View *view) { /* read a screenful of text considering each character as 4-byte UTF character*/ const size_t size = view->width * view->height * 4; /* current buffer to work with */ - char text[size+1]; + char *text = view->textbuf; /* remaining bytes to process in buffer */ size_t rem = text_bytes_get(view->text, view->start, size, text); /* NUL terminate text section */ @@ -454,14 +455,21 @@ bool view_resize(View *view, int width, int height) { view->need_update = true; return true; } + char *textbuf = malloc(width * height * 4 + 1); + if (!textbuf) + return false; size_t lines_size = height*(sizeof(Line) + width*sizeof(Cell)); if (lines_size > view->lines_size) { Line *lines = realloc(view->lines, lines_size); - if (!lines) + if (!lines) { + free(textbuf); return false; + } view->lines = lines; view->lines_size = lines_size; } + free(view->textbuf); + view->textbuf = textbuf; view->width = width; view->height = height; memset(view->lines, 0, view->lines_size); @@ -482,6 +490,7 @@ void view_free(View *view) { return; while (view->selections) selection_free(view->selections); + free(view->textbuf); free(view->lines); free(view); } diff --git a/vis-digraph.c b/vis-digraph.c index 452ede3..35a5a17 100644 --- a/vis-digraph.c +++ b/vis-digraph.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -1993,8 +1994,11 @@ int main(int argc, char *argv[]) { return 1; } - wchar_t runes[argc-1]; - memset(runes, 0, sizeof(runes)); + wchar_t *runes = calloc(argc-1, sizeof(runes[0])); + if (!runes) { + perror(NULL); + return 1; + } for (int i = 1; i < argc; i++) { int l = lookup(argv[i], &runes[i-1]); -- 2.11.4.GIT