mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	terminal: Fix potential invalid local 'scrollback' (#9605)
TermOpen autocmd may set local 'scrollback' to -1, this needs to be adjusted as in on_scrollback_option_changed(). fixes #9588 (OOM, out of memory)
This commit is contained in:
		| @@ -236,7 +236,8 @@ Terminal *terminal_open(TerminalOptions opts) | ||||
|   // Default settings for terminal buffers | ||||
|   curbuf->b_p_ma = false;     // 'nomodifiable' | ||||
|   curbuf->b_p_ul = -1;        // 'undolevels' | ||||
|   curbuf->b_p_scbk = (p_scbk == -1) ? 10000 : MAX(1, p_scbk);  // 'scrollback' | ||||
|   curbuf->b_p_scbk =          // 'scrollback' (initialize local from global) | ||||
|     (p_scbk < 0) ? 10000 : MAX(1, p_scbk); | ||||
|   curbuf->b_p_tw = 0;         // 'textwidth' | ||||
|   set_option_value("wrap", false, NULL, OPT_LOCAL); | ||||
|   set_option_value("list", false, NULL, OPT_LOCAL); | ||||
| @@ -244,9 +245,10 @@ Terminal *terminal_open(TerminalOptions opts) | ||||
|   RESET_BINDING(curwin); | ||||
|   // Reset cursor in current window. | ||||
|   curwin->w_cursor = (pos_T){ .lnum = 1, .col = 0, .coladd = 0 }; | ||||
|  | ||||
|   // Apply TermOpen autocmds _before_ configuring the scrollback buffer. | ||||
|   apply_autocmds(EVENT_TERMOPEN, NULL, NULL, false, curbuf); | ||||
|   // Local 'scrollback' _after_ autocmds. | ||||
|   curbuf->b_p_scbk = (curbuf->b_p_scbk < 1) ? SB_MAX : curbuf->b_p_scbk; | ||||
|  | ||||
|   // Configure the scrollback buffer. | ||||
|   rv->sb_size = (size_t)curbuf->b_p_scbk; | ||||
| @@ -1161,7 +1163,7 @@ static void refresh_size(Terminal *term, buf_T *buf) | ||||
| /// Adjusts scrollback storage after 'scrollback' option changed. | ||||
| static void on_scrollback_option_changed(Terminal *term, buf_T *buf) | ||||
| { | ||||
|   if (buf->b_p_scbk < 1) { | ||||
|   if (buf->b_p_scbk < 1) {  // Local 'scrollback' was set to -1. | ||||
|     buf->b_p_scbk = SB_MAX; | ||||
|   } | ||||
|   const size_t scbk = (size_t)buf->b_p_scbk; | ||||
|   | ||||
| @@ -10,6 +10,7 @@ local wait = helpers.wait | ||||
| local retry = helpers.retry | ||||
| local curbufmeths = helpers.curbufmeths | ||||
| local nvim = helpers.nvim | ||||
| local expect_err = helpers.expect_err | ||||
| local feed_data = thelpers.feed_data | ||||
|  | ||||
| describe(':terminal scrollback', function() | ||||
| @@ -467,13 +468,8 @@ describe("'scrollback' option", function() | ||||
|   end) | ||||
|  | ||||
|   it('error if set to invalid value', function() | ||||
|     local status, rv = pcall(command, 'set scrollback=-2') | ||||
|     eq(false, status)  -- assert failure | ||||
|     eq('E474:', string.match(rv, "E%d*:")) | ||||
|  | ||||
|     status, rv = pcall(command, 'set scrollback=100001') | ||||
|     eq(false, status)  -- assert failure | ||||
|     eq('E474:', string.match(rv, "E%d*:")) | ||||
|     expect_err('E474:', command, 'set scrollback=-2') | ||||
|     expect_err('E474:', command, 'set scrollback=100001') | ||||
|   end) | ||||
|  | ||||
|   it('defaults to -1 on normal buffers', function() | ||||
| @@ -481,6 +477,37 @@ describe("'scrollback' option", function() | ||||
|     eq(-1, curbufmeths.get_option('scrollback')) | ||||
|   end) | ||||
|  | ||||
|   it(':setlocal in a :terminal buffer', function() | ||||
|     set_fake_shell() | ||||
|  | ||||
|     -- _Global_ scrollback=-1 defaults :terminal to 10_000. | ||||
|     command('setglobal scrollback=-1') | ||||
|     command('terminal') | ||||
|     eq(10000, curbufmeths.get_option('scrollback')) | ||||
|  | ||||
|     -- _Local_ scrollback=-1 in :terminal forces the _maximum_. | ||||
|     command('setlocal scrollback=-1') | ||||
|     retry(nil, nil, function()  -- Fixup happens on refresh, not immediately. | ||||
|       eq(100000, curbufmeths.get_option('scrollback')) | ||||
|     end) | ||||
|  | ||||
|     -- _Local_ scrollback=-1 during TermOpen forces the maximum. #9605 | ||||
|     command('setglobal scrollback=-1') | ||||
|     command('autocmd TermOpen * setlocal scrollback=-1') | ||||
|     command('terminal') | ||||
|     eq(100000, curbufmeths.get_option('scrollback')) | ||||
|   end) | ||||
|  | ||||
|   it(':setlocal in a normal buffer', function() | ||||
|     command('new') | ||||
|     -- :setlocal to -1. | ||||
|     command('setlocal scrollback=-1') | ||||
|     eq(-1, curbufmeths.get_option('scrollback')) | ||||
|     -- :setlocal to anything except -1. Currently, this just has no effect. | ||||
|     command('setlocal scrollback=42') | ||||
|     eq(42, curbufmeths.get_option('scrollback')) | ||||
|   end) | ||||
|  | ||||
|   it(':set updates local value and global default', function() | ||||
|     set_fake_shell() | ||||
|     command('set scrollback=42')                  -- set global value | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Justin M. Keyes
					Justin M. Keyes