From f9ffa7ba4cff7d9818782d9bc88f2bebef9a50b9 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Sat, 5 Oct 2024 10:04:21 +0200 Subject: [PATCH] fix: several memory faults in REPL --- build/linux.mk | 2 +- src/cjit.c | 33 ++++++++++++++++++--------- src/kilo.c | 61 +++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/build/linux.mk b/build/linux.mk index 2a6b9f8..6675c6a 100644 --- a/build/linux.mk +++ b/build/linux.mk @@ -6,7 +6,7 @@ ldadd+=lib/tinycc/libtcc.a ifdef ASAN cflags += -O0 -ggdb -DDEBUG=1 -fno-omit-frame-pointer -fsanitize=address - ldflags += -fsanitize=address + ldflags += -fsanitize=address -static-libasan # tinycc_config += --extra-ldflags="${ldflags}" endif diff --git a/src/cjit.c b/src/cjit.c index be2fb8d..31338bc 100644 --- a/src/cjit.c +++ b/src/cjit.c @@ -187,6 +187,7 @@ static int cjit_compile_buffer(void *tcs, char *code, int argc, char **argv) _err("\n\n\n\nPress any key to continue....\n"); getchar(); disableGetCharMode(STDIN_FILENO); + free(code); enableRawMode(STDIN_FILENO); editorRefreshScreen(); @@ -206,19 +207,23 @@ static int cjit_check_buffer(void *tcs, char *code, char **err_msg) { TCCState *TCC = (TCCState *)tcs; int res = 0; + if(err_msg) + *err_msg = NULL; // run the code from main // disableRawMode(STDIN_FILENO); res = cjit_compile_and_run(TCC, code, 0, NULL, 0, err_msg); if (res != 0) { - if(err_msg) { + if(*err_msg) { if (strlen(err_msg) > ERR_MAX -1) { - err_msg[ERR_MAX - 1] = 0; + (*err_msg)[ERR_MAX - 1] = 0; } - char *p = strchr(err_msg, '\n'); + char *p = strchr(*err_msg, '\n'); if (p) *p = 0; - if (*err_msg) + if (*err_msg) { editorSetStatusMessage(*err_msg); + } + } } else { editorSetStatusMessage("No errors."); @@ -260,14 +265,22 @@ static int cjit_cli(TCCState *TCC) _err(err_msg); } else { int row = 0; + int i = 0; initEditor(); - editorInsertRow(row++, "#include ", 18); - editorInsertRow(row++, "#include ", 19); - editorInsertRow(row++, "", 0); - editorInsertRow(row++, "int main(int argc, char **argv) {", 33); - editorInsertRow(row++, "", 0); - editorInsertRow(row++, "}", 1); + const char editor_rows[6][40] = { + "#include ", + "#include ", + "", + "int main(int argc, char **argv) {", + "", + "}" + }; + + for (i = 0; i < 6; i++) { + editorInsertRow(row++, editor_rows[i], strlen(editor_rows[i])); + } + enableRawMode(STDIN_FILENO); editorSetStatusMessage( "HELP: Cx-S = save | Cx-Q = quit | Cx-F = find | Cx-R = run | Cx-E = editor"); diff --git a/src/kilo.c b/src/kilo.c index c23b1dd..fe81caa 100644 --- a/src/kilo.c +++ b/src/kilo.c @@ -430,9 +430,15 @@ int is_separator(int c) { * that starts at this row or at one before, and does not end at the end * of the row but spawns to the next row. */ int editorRowHasOpenComment(erow *row) { - if (row->hl && row->rsize && row->hl[row->rsize-1] == HL_MLCOMMENT && - (row->rsize < 2 || (row->render[row->rsize-2] != '*' || - row->render[row->rsize-1] != '/'))) return 1; + if ((!row->rsize < 3) || (sizeof(row->hl) < row->rsize - 1)) + return 0; + if (row->hl) { + if ((row->hl[row->size - 1] == HL_MLCOMMENT)) { + if (row->rsize < 2 || (row->render[row->rsize-2] != '*' || + row->render[row->rsize-1] != '/')) + return 1; + } + } return 0; } @@ -447,7 +453,8 @@ void editorUpdateSyntax(erow *row) { if (E.syntax == NULL) return; /* No syntax, everything is HL_NORMAL. */ int i, prev_sep, in_string, in_comment; - char *p; + int oc = 0; + char *p = NULL; char **keywords = E.syntax->keywords; char *scs = E.syntax->singleline_comment_start; char *mcs = E.syntax->multiline_comment_start; @@ -469,7 +476,10 @@ void editorUpdateSyntax(erow *row) { if (row->idx > 0 && editorRowHasOpenComment(&E.row[row->idx-1])) in_comment = 1; - while(*p) { + while((i < row->rsize) && *p) { + if (sizeof(row->hl) < row->rsize) { + row->hl = realloc(row->hl, row->rsize); + } /* Handle // comments. */ if (prev_sep && *p == scs[0] && *(p+1) == scs[1]) { /* From here to end is a comment */ @@ -479,8 +489,16 @@ void editorUpdateSyntax(erow *row) { /* Handle multi line comments. */ if (in_comment) { + if (sizeof(row->hl) < i + 2) { + row->hl = realloc(row->hl, i + 2); + row->hl[i + 1] = 0; + } row->hl[i] = HL_MLCOMMENT; if (*p == mce[0] && *(p+1) == mce[1]) { + if (sizeof(row->hl) < i + 2) { + row->hl = realloc(row->hl, i + 2); + row->hl[i + 1] = 0; + } row->hl[i+1] = HL_MLCOMMENT; p += 2; i += 2; in_comment = 0; @@ -492,6 +510,10 @@ void editorUpdateSyntax(erow *row) { continue; } } else if (*p == mcs[0] && *(p+1) == mcs[1]) { + if (sizeof(row->hl) < i + 2) { + row->hl = realloc(row->hl, i + 2); + row->hl[i + 1] = 0; + } row->hl[i] = HL_MLCOMMENT; row->hl[i+1] = HL_MLCOMMENT; p += 2; i += 2; @@ -502,8 +524,16 @@ void editorUpdateSyntax(erow *row) { if (in_string) { + if (sizeof(row->hl) < i + 2) { + row->hl = realloc(row->hl, i + 2); + row->hl[i + 1] = 0; + } row->hl[i] = HL_STRING; if (*p == '\\') { + if (sizeof(row->hl) < i + 3) { + row->hl = realloc(row->hl, i + 3); + row->hl[i + 2] = 0; + } row->hl[i+1] = HL_STRING; p += 2; i += 2; prev_sep = 0; @@ -516,6 +546,10 @@ void editorUpdateSyntax(erow *row) { } else { if (*p == '"' || *p == '\'') { in_string = *p; + if (sizeof(row->hl) < i + 2) { + row->hl = realloc(row->hl, i + 2); + row->hl[i + 1] = 0; + } row->hl[i] = HL_STRING; p++; i++; prev_sep = 0; @@ -548,8 +582,9 @@ void editorUpdateSyntax(erow *row) { int kw2 = keywords[j][klen-1] == '|'; if (kw2) klen--; - if (!memcmp(p,keywords[j],klen) && - is_separator(*(p+klen))) + + if ((strlen(p) >= klen) && (!memcmp(p,keywords[j],klen) && + is_separator(*(p+klen)))) { /* Keyword */ memset(row->hl+i,kw2 ? HL_KEYWORD2 : HL_KEYWORD1,klen); @@ -572,7 +607,7 @@ void editorUpdateSyntax(erow *row) { /* Propagate syntax change to the next row if the open commen * state changed. This may recursively affect all the following rows * in the file. */ - int oc = editorRowHasOpenComment(row); + oc = editorRowHasOpenComment(row); if (row->hl_oc != oc && row->idx+1 < E.numrows) editorUpdateSyntax(&E.row[row->idx+1]); row->hl_oc = oc; @@ -631,7 +666,7 @@ void editorUpdateRow(erow *row) { printf("Some line of the edited file is too long for kilo\n"); exit(1); } - row->render = malloc(row->size + tabs*8 + nonprint*9 + 1); + row->render = malloc(row->size + tabs*8 + nonprint + 1); idx = 0; for (j = 0; j < row->size; j++) { if (row->chars[j] == TAB) { @@ -696,10 +731,8 @@ void editorDelRow(int at) { /* Clear the entire buffer */ void editorReset(void) { int j; - for (j = E.numrows - 1; j > 0; j--) { - editorDelRow(E.row+j); - } - E.numrows = 0; + while (E.numrows > 0) + editorDelRow(E.numrows-1); E.dirty = 0; } @@ -1123,6 +1156,8 @@ void editorRefreshScreen(void) { memset(E.row[at].hl, HL_ERROR, E.row[at].rsize); editorUpdateSyntax(row); } + free(err_msg); + err_msg = NULL; } free(buf); }