Mercurial > vim
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 { |