Patch 8.1.0633
Problem: Crash when out of memory while opening a terminal window.
Solution: Handle out-of-memory more gracefully.
Files: src/terminal.c, src/libvterm/src/vterm.c,
src/libvterm/src/state.c, src/libvterm/src/termscreen.c
*** ../vim-8.1.0632/src/terminal.c 2018-12-21 20:55:18.892739645 +0100
--- src/terminal.c 2018-12-24 21:22:28.150773840 +0100
***************
*** 3430,3435 ****
--- 3430,3436 ----
{
int index = 0;
VTermState *state = vterm_obtain_state(vterm);
+
for (; index < 16; index++)
{
VTermColor color;
***************
*** 3703,3710 ****
/*
* Create a new vterm and initialize it.
*/
! static void
create_vterm(term_T *term, int rows, int cols)
{
VTerm *vterm;
--- 3704,3712 ----
/*
* Create a new vterm and initialize it.
+ * Return FAIL when out of memory.
*/
! static int
create_vterm(term_T *term, int rows, int cols)
{
VTerm *vterm;
***************
*** 3714,3720 ****
--- 3716,3733 ----
vterm = vterm_new_with_allocator(rows, cols, &vterm_allocator, NULL);
term->tl_vterm = vterm;
+ if (vterm == NULL)
+ return FAIL;
+
+ // Allocate screen and state here, so we can bail out if that fails.
+ state = vterm_obtain_state(vterm);
screen = vterm_obtain_screen(vterm);
+ if (state == NULL || screen == NULL)
+ {
+ vterm_free(vterm);
+ return FAIL;
+ }
+
vterm_screen_set_callbacks(screen, &screen_callbacks, term);
/* TODO: depends on 'encoding'. */
vterm_set_utf8(vterm, 1);
***************
*** 3722,3728 ****
init_default_colors(term);
vterm_state_set_default_colors(
! vterm_obtain_state(vterm),
&term->tl_default_color.fg,
&term->tl_default_color.bg);
--- 3735,3741 ----
init_default_colors(term);
vterm_state_set_default_colors(
! state,
&term->tl_default_color.fg,
&term->tl_default_color.bg);
***************
*** 3746,3754 ****
#else
value.boolean = 0;
#endif
- state = vterm_obtain_state(vterm);
vterm_state_set_termprop(state, VTERM_PROP_CURSORBLINK, &value);
vterm_state_set_unrecognised_fallbacks(state, &parser_fallbacks, term);
}
/*
--- 3759,3768 ----
#else
value.boolean = 0;
#endif
vterm_state_set_termprop(state, VTERM_PROP_CURSORBLINK, &value);
vterm_state_set_unrecognised_fallbacks(state, &parser_fallbacks, term);
+
+ return OK;
}
/*
***************
*** 5629,5635 ****
vim_free(cwd_wchar);
vim_free(env_wchar);
! create_vterm(term, term->tl_rows, term->tl_cols);
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
if (opt->jo_set2 & JO2_ANSI_COLORS)
--- 5643,5650 ----
vim_free(cwd_wchar);
vim_free(env_wchar);
! if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
! goto failed;
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
if (opt->jo_set2 & JO2_ANSI_COLORS)
***************
*** 5710,5716 ****
char in_name[80], out_name[80];
channel_T *channel = NULL;
! create_vterm(term, term->tl_rows, term->tl_cols);
vim_snprintf(in_name, sizeof(in_name), "\\\\.\\pipe\\vim-%d-in-%d",
GetCurrentProcessId(),
--- 5725,5732 ----
char in_name[80], out_name[80];
channel_T *channel = NULL;
! if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
! return FAIL;
vim_snprintf(in_name, sizeof(in_name), "\\\\.\\pipe\\vim-%d-in-%d",
GetCurrentProcessId(),
***************
*** 5822,5828 ****
jobopt_T *opt,
jobopt_T *orig_opt UNUSED)
{
! create_vterm(term, term->tl_rows, term->tl_cols);
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
if (opt->jo_set2 & JO2_ANSI_COLORS)
--- 5838,5845 ----
jobopt_T *opt,
jobopt_T *orig_opt UNUSED)
{
! if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
! return FAIL;
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
if (opt->jo_set2 & JO2_ANSI_COLORS)
***************
*** 5844,5850 ****
static int
create_pty_only(term_T *term, jobopt_T *opt)
{
! create_vterm(term, term->tl_rows, term->tl_cols);
term->tl_job = job_alloc();
if (term->tl_job == NULL)
--- 5861,5868 ----
static int
create_pty_only(term_T *term, jobopt_T *opt)
{
! if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
! return FAIL;
term->tl_job = job_alloc();
if (term->tl_job == NULL)
*** ../vim-8.1.0632/src/libvterm/src/vterm.c 2018-12-15 14:49:30.800096933
+0100
--- src/libvterm/src/vterm.c 2018-12-24 21:26:14.100725256 +0100
***************
*** 1,5 ****
--- 1,6 ----
#define DEFINE_INLINES
+ /* vim: set sw=2 : */
#include "vterm_internal.h"
#include <stdio.h>
***************
*** 41,46 ****
--- 42,49 ----
/* Need to bootstrap using the allocator function directly */
VTerm *vt = (*funcs->malloc)(sizeof(VTerm), allocdata);
+ if (vt == NULL)
+ return NULL;
vt->allocator = funcs;
vt->allocdata = allocdata;
***************
*** 55,64 ****
--- 58,78 ----
vt->parser.strbuffer_len = 500; /* should be able to hold an OSC string */
vt->parser.strbuffer_cur = 0;
vt->parser.strbuffer = vterm_allocator_malloc(vt, vt->parser.strbuffer_len);
+ if (vt->parser.strbuffer == NULL)
+ {
+ vterm_allocator_free(vt, vt);
+ return NULL;
+ }
vt->outbuffer_len = 200;
vt->outbuffer_cur = 0;
vt->outbuffer = vterm_allocator_malloc(vt, vt->outbuffer_len);
+ if (vt->outbuffer == NULL)
+ {
+ vterm_allocator_free(vt, vt->parser.strbuffer);
+ vterm_allocator_free(vt, vt);
+ return NULL;
+ }
return vt;
}
***************
*** 82,90 ****
return (*vt->allocator->malloc)(size, vt->allocdata);
}
INTERNAL void vterm_allocator_free(VTerm *vt, void *ptr)
{
! (*vt->allocator->free)(ptr, vt->allocdata);
}
void vterm_get_size(const VTerm *vt, int *rowsp, int *colsp)
--- 96,108 ----
return (*vt->allocator->malloc)(size, vt->allocdata);
}
+ /*
+ * Free "ptr" unless it is NULL.
+ */
INTERNAL void vterm_allocator_free(VTerm *vt, void *ptr)
{
! if (ptr)
! (*vt->allocator->free)(ptr, vt->allocdata);
}
void vterm_get_size(const VTerm *vt, int *rowsp, int *colsp)
*** ../vim-8.1.0632/src/libvterm/src/state.c 2018-07-09 20:39:12.824845063
+0200
--- src/libvterm/src/state.c 2018-12-24 20:45:42.697972984 +0100
***************
*** 53,58 ****
--- 53,60 ----
{
VTermState *state = vterm_allocator_malloc(vt, sizeof(VTermState));
+ if (state == NULL)
+ return NULL;
state->vt = vt;
state->rows = vt->rows;
***************
*** 1693,1698 ****
--- 1695,1704 ----
on_resize /* resize */
};
+ /*
+ * Return the existing state or create a new one.
+ * Returns NULL when out of memory.
+ */
VTermState *vterm_obtain_state(VTerm *vt)
{
VTermState *state;
***************
*** 1700,1705 ****
--- 1706,1713 ----
return vt->state;
state = vterm_state_new(vt);
+ if (state == NULL)
+ return NULL;
vt->state = state;
state->combine_chars_size = 16;
*** ../vim-8.1.0632/src/libvterm/src/termscreen.c 2018-09-13
17:23:05.169150892 +0200
--- src/libvterm/src/termscreen.c 2018-12-24 21:29:52.730781805 +0100
***************
*** 1,5 ****
--- 1,6 ----
#include "vterm_internal.h"
+ /* vim: set sw=2 : */
#include <stdio.h>
#include <string.h>
***************
*** 95,102 ****
}
}
! if(buffer)
! vterm_allocator_free(screen->vt, buffer);
return new_buffer;
}
--- 96,102 ----
}
}
! vterm_allocator_free(screen->vt, buffer);
return new_buffer;
}
***************
*** 518,525 ****
screen->rows = new_rows;
screen->cols = new_cols;
! if(screen->sb_buffer)
! vterm_allocator_free(screen->vt, screen->sb_buffer);
screen->sb_buffer = vterm_allocator_malloc(screen->vt,
sizeof(VTermScreenCell) * new_cols);
--- 518,524 ----
screen->rows = new_rows;
screen->cols = new_cols;
! vterm_allocator_free(screen->vt, screen->sb_buffer);
screen->sb_buffer = vterm_allocator_malloc(screen->vt,
sizeof(VTermScreenCell) * new_cols);
***************
*** 619,634 ****
&setlineinfo /* setlineinfo */
};
static VTermScreen *screen_new(VTerm *vt)
{
VTermState *state = vterm_obtain_state(vt);
VTermScreen *screen;
int rows, cols;
! if(!state)
return NULL;
-
screen = vterm_allocator_malloc(vt, sizeof(VTermScreen));
vterm_get_size(vt, &rows, &cols);
--- 618,638 ----
&setlineinfo /* setlineinfo */
};
+ /*
+ * Allocate a new screen and return it.
+ * Return NULL when out of memory.
+ */
static VTermScreen *screen_new(VTerm *vt)
{
VTermState *state = vterm_obtain_state(vt);
VTermScreen *screen;
int rows, cols;
! if (state == NULL)
return NULL;
screen = vterm_allocator_malloc(vt, sizeof(VTermScreen));
+ if (screen == NULL)
+ return NULL;
vterm_get_size(vt, &rows, &cols);
***************
*** 646,655 ****
screen->cbdata = NULL;
screen->buffers[0] = realloc_buffer(screen, NULL, rows, cols);
-
screen->buffer = screen->buffers[0];
-
screen->sb_buffer = vterm_allocator_malloc(screen->vt,
sizeof(VTermScreenCell) * cols);
vterm_state_set_callbacks(screen->state, &state_cbs, screen);
--- 650,662 ----
screen->cbdata = NULL;
screen->buffers[0] = realloc_buffer(screen, NULL, rows, cols);
screen->buffer = screen->buffers[0];
screen->sb_buffer = vterm_allocator_malloc(screen->vt,
sizeof(VTermScreenCell) * cols);
+ if (screen->buffer == NULL || screen->sb_buffer == NULL)
+ {
+ vterm_screen_free(screen);
+ return NULL;
+ }
vterm_state_set_callbacks(screen->state, &state_cbs, screen);
***************
*** 659,669 ****
INTERNAL void vterm_screen_free(VTermScreen *screen)
{
vterm_allocator_free(screen->vt, screen->buffers[0]);
! if(screen->buffers[1])
! vterm_allocator_free(screen->vt, screen->buffers[1]);
!
vterm_allocator_free(screen->vt, screen->sb_buffer);
-
vterm_allocator_free(screen->vt, screen);
}
--- 666,673 ----
INTERNAL void vterm_screen_free(VTermScreen *screen)
{
vterm_allocator_free(screen->vt, screen->buffers[0]);
! vterm_allocator_free(screen->vt, screen->buffers[1]);
vterm_allocator_free(screen->vt, screen->sb_buffer);
vterm_allocator_free(screen->vt, screen);
}
*** ../vim-8.1.0632/src/version.c 2018-12-24 20:23:39.440716979 +0100
--- src/version.c 2018-12-24 21:34:22.808414341 +0100
***************
*** 801,802 ****
--- 801,804 ----
{ /* Add new patch number below this line */
+ /**/
+ 633,
/**/
--
"Oh, no! NOT the Spanish Inquisition!"
"NOBODY expects the Spanish Inquisition!!!"
-- Monty Python sketch --
"Oh, no! NOT another option!"
"EVERYBODY expects another option!!!"
-- Discussion in vim-dev mailing list --
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.