# HG changeset patch # User Bram Moolenaar # Date 1556396105 -7200 # Node ID a1229400434a2b309c17101ebebd8dfe8b81d6f7 # Parent 6f69ef2913d74a03308fcf6a12c7c1c0e66ee7f0 patch 8.1.1219: not checking for NULL return from alloc() commit https://github.com/vim/vim/commit/6ee9658774942f7448af700fc04df0335796a3db Author: Bram Moolenaar Date: Sat Apr 27 22:06:37 2019 +0200 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 https://github.com/vim/vim/issues/4303, closes https://github.com/vim/vim/issues/4174) diff --git a/src/beval.c b/src/beval.c --- 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 --- 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 --- 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 --- 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 --- 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 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -1576,12 +1576,15 @@ selection_get_cb(GtkWidget *widget U 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 U 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 --- a/src/libvterm/src/state.c +++ b/src/libvterm/src/state.c @@ -253,6 +253,8 @@ static int on_text(const char bytes[], s // 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[], s 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, 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, 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 --- a/src/libvterm/src/termscreen.c +++ b/src/libvterm/src/termscreen.c @@ -83,6 +83,8 @@ static ScreenCell *realloc_buffer(VTermS 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 --- a/src/ops.c +++ b/src/ops.c @@ -6170,21 +6170,25 @@ handle_viminfo_register(garray_T *values y_ptr->y_size = linecount; y_ptr->y_time_set = timestamp; if (linecount == 0) + { y_ptr->y_array = NULL; - else - { - y_ptr->y_array = - (char_u **)alloc((unsigned)(linecount * sizeof(char_u *))); - for (i = 0; i < linecount; i++) - { - 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); - } + 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++) + { + 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); } } diff --git a/src/option.c b/src/option.c --- 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 --- a/src/popupmnu.c +++ b/src/popupmnu.c @@ -1102,12 +1102,19 @@ split_message(char_u *mesg, pumitem_T ** 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 --- 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 --- 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 --- a/src/version.c +++ b/src/version.c @@ -768,6 +768,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1219, +/**/ 1218, /**/ 1217,