From 6ee9658774942f7448af700fc04df0335796a3db Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 27 Apr 2019 22:06:37 +0200 Subject: patch 8.1.1219: not checking for NULL return from alloc() Problem: Not checking for NULL return from alloc(). Solution: Add checks. (Martin Kunev, closes #4303, closes #4174) --- src/beval.c | 2 ++ src/blowfish.c | 8 ++++++-- src/crypt.c | 13 +++++++++++-- src/crypt_zip.c | 6 +++++- src/gui_gtk_f.c | 2 ++ src/gui_gtk_x11.c | 21 ++++++++++++--------- src/libvterm/src/state.c | 8 ++++++++ src/libvterm/src/termscreen.c | 2 ++ src/ops.c | 26 +++++++++++++++----------- src/option.c | 13 ++++++------- src/popupmnu.c | 11 +++++++++-- src/proto/blowfish.pro | 2 +- src/proto/crypt_zip.pro | 2 +- src/version.c | 2 ++ 14 files changed, 82 insertions(+), 36 deletions(-) diff --git a/src/beval.c b/src/beval.c index c5fa22014f..d51a3f5d84 100644 --- a/src/beval.c +++ b/src/beval.c @@ -127,6 +127,8 @@ get_beval_info( #ifdef FEAT_VARTABS vim_free(beval->vts); beval->vts = tabstop_copy(wp->w_buffer->b_p_vts_array); + if (wp->w_buffer->b_p_vts_array != NULL && beval->vts == NULL) + return FAIL; #endif beval->ts = wp->w_buffer->b_p_ts; return OK; diff --git a/src/blowfish.c b/src/blowfish.c index 7bc3e31d35..ce49957913 100644 --- a/src/blowfish.c +++ b/src/blowfish.c @@ -636,7 +636,7 @@ crypt_blowfish_decode( } } - void + int crypt_blowfish_init( cryptstate_T *state, char_u* key, @@ -647,6 +647,8 @@ crypt_blowfish_init( { bf_state_T *bfs = (bf_state_T *)alloc_clear(sizeof(bf_state_T)); + if (bfs == NULL) + return FAIL; state->method_state = bfs; /* "blowfish" uses a 64 byte buffer, causing it to repeat 8 byte groups 8 @@ -654,10 +656,12 @@ crypt_blowfish_init( bfs->cfb_len = state->method_nr == CRYPT_M_BF ? BF_MAX_CFB_LEN : BF_BLOCK; if (blowfish_self_test() == FAIL) - return; + return FAIL; bf_key_init(bfs, key, salt, salt_len); bf_cfb_init(bfs, seed, seed_len); + + return OK; } /* diff --git a/src/crypt.c b/src/crypt.c index 085f8bb813..6eb3e21faf 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -43,7 +43,7 @@ typedef struct { int (* self_test_fn)(); // Function pointer for initializing encryption/decryption. - void (* init_fn)(cryptstate_T *state, char_u *key, + int (* init_fn)(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len); /* Function pointers for encoding/decoding from one buffer into another. @@ -243,6 +243,7 @@ crypt_self_test(void) /* * Allocate a crypt state and initialize it. + * Return NULL for failure. */ cryptstate_T * crypt_create( @@ -255,8 +256,16 @@ crypt_create( { cryptstate_T *state = (cryptstate_T *)alloc((int)sizeof(cryptstate_T)); + if (state == NULL) + return state; + state->method_nr = method_nr; - cryptmethods[method_nr].init_fn(state, key, salt, salt_len, seed, seed_len); + if (cryptmethods[method_nr].init_fn( + state, key, salt, salt_len, seed, seed_len) == FAIL) + { + vim_free(state); + return NULL; + } return state; } diff --git a/src/crypt_zip.c b/src/crypt_zip.c index 864812e18d..25b7962a3b 100644 --- a/src/crypt_zip.c +++ b/src/crypt_zip.c @@ -78,7 +78,7 @@ make_crc_tab(void) /* * Initialize for encryption/decryption. */ - void + int crypt_zip_init( cryptstate_T *state, char_u *key, @@ -91,6 +91,8 @@ crypt_zip_init( zip_state_T *zs; zs = (zip_state_T *)alloc(sizeof(zip_state_T)); + if (zs == NULL) + return FAIL; state->method_state = zs; make_crc_tab(); @@ -99,6 +101,8 @@ crypt_zip_init( zs->keys[2] = 878082192L; for (p = key; *p != NUL; ++p) UPDATE_KEYS_ZIP(zs->keys, (int)*p); + + return OK; } /* diff --git a/src/gui_gtk_f.c b/src/gui_gtk_f.c index 6146fe6d9e..1bff14b530 100644 --- a/src/gui_gtk_f.c +++ b/src/gui_gtk_f.c @@ -130,6 +130,8 @@ gtk_form_put(GtkForm *form, /* LINTED: avoid warning: conversion to 'unsigned long' */ child = g_new(GtkFormChild, 1); + if (child == NULL) + return; child->widget = child_widget; child->window = NULL; diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index 5275026f88..f99d1fdcb2 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -1576,12 +1576,15 @@ selection_get_cb(GtkWidget *widget UNUSED, if (string != NULL) { tmpbuf = alloc(length + 2); - tmpbuf[0] = 0xff; - tmpbuf[1] = 0xfe; - mch_memmove(tmpbuf + 2, string, (size_t)length); - vim_free(string); - string = tmpbuf; - length += 2; + if (tmpbuf != NULL) + { + tmpbuf[0] = 0xff; + tmpbuf[1] = 0xfe; + mch_memmove(tmpbuf + 2, string, (size_t)length); + vim_free(string); + string = tmpbuf; + length += 2; + } #if !GTK_CHECK_VERSION(3,0,0) /* Looks redundant even for GTK2 because these values are @@ -1606,10 +1609,10 @@ selection_get_cb(GtkWidget *widget UNUSED, tmpbuf[0] = motion_type; STRCPY(tmpbuf + 1, p_enc); mch_memmove(tmpbuf + l + 2, string, (size_t)length); + length += l + 2; + vim_free(string); + string = tmpbuf; } - length += l + 2; - vim_free(string); - string = tmpbuf; type = vimenc_atom; } diff --git a/src/libvterm/src/state.c b/src/libvterm/src/state.c index a1261455f8..d6ac29deb7 100644 --- a/src/libvterm/src/state.c +++ b/src/libvterm/src/state.c @@ -253,6 +253,8 @@ static int on_text(const char bytes[], size_t len, void *user) // We'll have at most len codepoints, plus one from a previous incomplete // sequence. codepoints = vterm_allocator_malloc(state->vt, (len + 1) * sizeof(uint32_t)); + if (codepoints == NULL) + return 0; encoding = state->gsingle_set ? &state->encoding[state->gsingle_set] : @@ -330,6 +332,8 @@ static int on_text(const char bytes[], size_t len, void *user) break; chars = vterm_allocator_malloc(state->vt, (glyph_ends - glyph_starts + 1) * sizeof(uint32_t)); + if (chars == NULL) + break; for( ; i < glyph_ends; i++) { int this_width; @@ -1626,6 +1630,8 @@ static int on_resize(int rows, int cols, void *user) if(cols != state->cols) { unsigned char *newtabstops = vterm_allocator_malloc(state->vt, (cols + 7) / 8); + if (newtabstops == NULL) + return 0; /* TODO: This can all be done much more efficiently bytewise */ int col; @@ -1651,6 +1657,8 @@ static int on_resize(int rows, int cols, void *user) if(rows != state->rows) { VTermLineInfo *newlineinfo = vterm_allocator_malloc(state->vt, rows * sizeof(VTermLineInfo)); + if (newlineinfo == NULL) + return 0; int row; for(row = 0; row < state->rows && row < rows; row++) { diff --git a/src/libvterm/src/termscreen.c b/src/libvterm/src/termscreen.c index 0cd31cedfe..4e94cfbc6d 100644 --- a/src/libvterm/src/termscreen.c +++ b/src/libvterm/src/termscreen.c @@ -83,6 +83,8 @@ static ScreenCell *realloc_buffer(VTermScreen *screen, ScreenCell *buffer, int n ScreenCell *new_buffer = vterm_allocator_malloc(screen->vt, sizeof(ScreenCell) * new_rows * new_cols); int row, col; + if (new_buffer == NULL) + return NULL; for(row = 0; row < new_rows; row++) { for(col = 0; col < new_cols; col++) { ScreenCell *new_cell = new_buffer + row*new_cols + col; diff --git a/src/ops.c b/src/ops.c index e939f04647..2aa18c437c 100644 --- a/src/ops.c +++ b/src/ops.c @@ -6170,21 +6170,25 @@ handle_viminfo_register(garray_T *values, int force) y_ptr->y_size = linecount; y_ptr->y_time_set = timestamp; if (linecount == 0) + { y_ptr->y_array = NULL; - else + return; + } + y_ptr->y_array = (char_u **)alloc((unsigned)(linecount * sizeof(char_u *))); + if (y_ptr->y_array == NULL) + { + y_ptr->y_size = 0; // ensure object state is consistent + return; + } + for (i = 0; i < linecount; i++) { - y_ptr->y_array = - (char_u **)alloc((unsigned)(linecount * sizeof(char_u *))); - for (i = 0; i < linecount; i++) + if (vp[i + 6].bv_allocated) { - if (vp[i + 6].bv_allocated) - { - y_ptr->y_array[i] = vp[i + 6].bv_string; - vp[i + 6].bv_string = NULL; - } - else - y_ptr->y_array[i] = vim_strsave(vp[i + 6].bv_string); + y_ptr->y_array[i] = vp[i + 6].bv_string; + vp[i + 6].bv_string = NULL; } + else + y_ptr->y_array[i] = vim_strsave(vp[i + 6].bv_string); } } diff --git a/src/option.c b/src/option.c index ba12fd4e65..dfd4587c3d 100644 --- a/src/option.c +++ b/src/option.c @@ -13011,13 +13011,12 @@ tabstop_copy(int *oldts) int *newts; int t; - if (oldts == 0) - return 0; - - newts = (int *) alloc((unsigned) ((oldts[0] + 1) * sizeof(int))); - for (t = 0; t <= oldts[0]; ++t) - newts[t] = oldts[t]; - + if (oldts == NULL) + return NULL; + newts = (int *)alloc((unsigned)((oldts[0] + 1) * sizeof(int))); + if (newts != NULL) + for (t = 0; t <= oldts[0]; ++t) + newts[t] = oldts[t]; return newts; } #endif diff --git a/src/popupmnu.c b/src/popupmnu.c index ba9c7adc75..2639d97d56 100644 --- a/src/popupmnu.c +++ b/src/popupmnu.c @@ -1102,12 +1102,19 @@ split_message(char_u *mesg, pumitem_T **array) else thislen = item->bytelen; - /* put indent at the start */ + // put indent at the start p = alloc(thislen + item->indent * 2 + 1); + if (p == NULL) + { + for (line = 0; line <= height - 1; ++line) + vim_free((*array)[line].pum_text); + vim_free(*array); + goto failed; + } for (ind = 0; ind < item->indent * 2; ++ind) p[ind] = ' '; - /* exclude spaces at the end of the string */ + // exclude spaces at the end of the string for (copylen = thislen; copylen > 0; --copylen) if (item->start[skip + copylen - 1] != ' ') break; diff --git a/src/proto/blowfish.pro b/src/proto/blowfish.pro index d959846105..5998fb3581 100644 --- a/src/proto/blowfish.pro +++ b/src/proto/blowfish.pro @@ -1,6 +1,6 @@ /* blowfish.c */ void crypt_blowfish_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to); void crypt_blowfish_decode(cryptstate_T *state, char_u *from, size_t len, char_u *to); -void crypt_blowfish_init(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len); +int crypt_blowfish_init(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len); int blowfish_self_test(void); /* vim: set ft=c : */ diff --git a/src/proto/crypt_zip.pro b/src/proto/crypt_zip.pro index 74784e1a47..868b131f0f 100644 --- a/src/proto/crypt_zip.pro +++ b/src/proto/crypt_zip.pro @@ -1,5 +1,5 @@ /* crypt_zip.c */ -void crypt_zip_init(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len); +int crypt_zip_init(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len); void crypt_zip_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to); void crypt_zip_decode(cryptstate_T *state, char_u *from, size_t len, char_u *to); /* vim: set ft=c : */ diff --git a/src/version.c b/src/version.c index 25884c3768..638faad308 100644 --- a/src/version.c +++ b/src/version.c @@ -767,6 +767,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1219, /**/ 1218, /**/ -- cgit v1.2.3