comparison src/libvterm/src/termscreen.c @ 15249:544490b69e1d v8.1.0633

patch 8.1.0633: crash when out of memory while opening a terminal window commit https://github.com/vim/vim/commit/cd929f7ba8cc5b6d6dcf35c8b34124e969fed6b8 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Dec 24 21:38:45 2018 +0100 patch 8.1.0633: crash when out of memory while opening a terminal window Problem: Crash when out of memory while opening a terminal window. Solution: Handle out-of-memory more gracefully.
author Bram Moolenaar <Bram@vim.org>
date Mon, 24 Dec 2018 21:45:05 +0100
parents 2c72fa16aa70
children a1229400434a
comparison
equal deleted inserted replaced
15248:1e57afb3e8e9 15249:544490b69e1d
1 #include "vterm_internal.h" 1 #include "vterm_internal.h"
2 2
3 /* vim: set sw=2 : */
3 #include <stdio.h> 4 #include <stdio.h>
4 #include <string.h> 5 #include <string.h>
5 6
6 #include "rect.h" 7 #include "rect.h"
7 #include "utf8.h" 8 #include "utf8.h"
93 new_cell->pen = screen->pen; 94 new_cell->pen = screen->pen;
94 } 95 }
95 } 96 }
96 } 97 }
97 98
98 if(buffer) 99 vterm_allocator_free(screen->vt, buffer);
99 vterm_allocator_free(screen->vt, buffer);
100 100
101 return new_buffer; 101 return new_buffer;
102 } 102 }
103 103
104 static void damagerect(VTermScreen *screen, VTermRect rect) 104 static void damagerect(VTermScreen *screen, VTermRect rect)
516 screen->buffer = is_altscreen ? screen->buffers[1] : screen->buffers[0]; 516 screen->buffer = is_altscreen ? screen->buffers[1] : screen->buffers[0];
517 517
518 screen->rows = new_rows; 518 screen->rows = new_rows;
519 screen->cols = new_cols; 519 screen->cols = new_cols;
520 520
521 if(screen->sb_buffer) 521 vterm_allocator_free(screen->vt, screen->sb_buffer);
522 vterm_allocator_free(screen->vt, screen->sb_buffer);
523 522
524 screen->sb_buffer = vterm_allocator_malloc(screen->vt, sizeof(VTermScreenCell) * new_cols); 523 screen->sb_buffer = vterm_allocator_malloc(screen->vt, sizeof(VTermScreenCell) * new_cols);
525 524
526 if(new_cols > old_cols) { 525 if(new_cols > old_cols) {
527 VTermRect rect; 526 VTermRect rect;
617 &bell, /* bell */ 616 &bell, /* bell */
618 &resize, /* resize */ 617 &resize, /* resize */
619 &setlineinfo /* setlineinfo */ 618 &setlineinfo /* setlineinfo */
620 }; 619 };
621 620
621 /*
622 * Allocate a new screen and return it.
623 * Return NULL when out of memory.
624 */
622 static VTermScreen *screen_new(VTerm *vt) 625 static VTermScreen *screen_new(VTerm *vt)
623 { 626 {
624 VTermState *state = vterm_obtain_state(vt); 627 VTermState *state = vterm_obtain_state(vt);
625 VTermScreen *screen; 628 VTermScreen *screen;
626 int rows, cols; 629 int rows, cols;
627 630
628 if(!state) 631 if (state == NULL)
629 return NULL; 632 return NULL;
630
631 screen = vterm_allocator_malloc(vt, sizeof(VTermScreen)); 633 screen = vterm_allocator_malloc(vt, sizeof(VTermScreen));
634 if (screen == NULL)
635 return NULL;
632 636
633 vterm_get_size(vt, &rows, &cols); 637 vterm_get_size(vt, &rows, &cols);
634 638
635 screen->vt = vt; 639 screen->vt = vt;
636 screen->state = state; 640 screen->state = state;
644 648
645 screen->callbacks = NULL; 649 screen->callbacks = NULL;
646 screen->cbdata = NULL; 650 screen->cbdata = NULL;
647 651
648 screen->buffers[0] = realloc_buffer(screen, NULL, rows, cols); 652 screen->buffers[0] = realloc_buffer(screen, NULL, rows, cols);
649
650 screen->buffer = screen->buffers[0]; 653 screen->buffer = screen->buffers[0];
651
652 screen->sb_buffer = vterm_allocator_malloc(screen->vt, sizeof(VTermScreenCell) * cols); 654 screen->sb_buffer = vterm_allocator_malloc(screen->vt, sizeof(VTermScreenCell) * cols);
655 if (screen->buffer == NULL || screen->sb_buffer == NULL)
656 {
657 vterm_screen_free(screen);
658 return NULL;
659 }
653 660
654 vterm_state_set_callbacks(screen->state, &state_cbs, screen); 661 vterm_state_set_callbacks(screen->state, &state_cbs, screen);
655 662
656 return screen; 663 return screen;
657 } 664 }
658 665
659 INTERNAL void vterm_screen_free(VTermScreen *screen) 666 INTERNAL void vterm_screen_free(VTermScreen *screen)
660 { 667 {
661 vterm_allocator_free(screen->vt, screen->buffers[0]); 668 vterm_allocator_free(screen->vt, screen->buffers[0]);
662 if(screen->buffers[1]) 669 vterm_allocator_free(screen->vt, screen->buffers[1]);
663 vterm_allocator_free(screen->vt, screen->buffers[1]);
664
665 vterm_allocator_free(screen->vt, screen->sb_buffer); 670 vterm_allocator_free(screen->vt, screen->sb_buffer);
666
667 vterm_allocator_free(screen->vt, screen); 671 vterm_allocator_free(screen->vt, screen);
668 } 672 }
669 673
670 void vterm_screen_reset(VTermScreen *screen, int hard) 674 void vterm_screen_reset(VTermScreen *screen, int hard)
671 { 675 {