mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	:recover : Fix crash on non-existent *.swp #9504
Reverts d2944e6a29. mf_open() _can_ fail if the file does not exist.
closes #9503
closes #9504
			
			
This commit is contained in:
		@@ -76,7 +76,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// @param flags  Flags for open() call.
 | 
					/// @param flags  Flags for open() call.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// @return The open memory file.
 | 
					/// @return - The open memory file, on success.
 | 
				
			||||||
 | 
					///         - NULL, on failure (e.g. file does not exist).
 | 
				
			||||||
memfile_T *mf_open(char_u *fname, int flags)
 | 
					memfile_T *mf_open(char_u *fname, int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  memfile_T *mfp = xmalloc(sizeof(memfile_T));
 | 
					  memfile_T *mfp = xmalloc(sizeof(memfile_T));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -277,6 +277,9 @@ int ml_open(buf_T *buf)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // Open the memfile.  No swap file is created yet.
 | 
					  // Open the memfile.  No swap file is created yet.
 | 
				
			||||||
  memfile_T *mfp = mf_open(NULL, 0);
 | 
					  memfile_T *mfp = mf_open(NULL, 0);
 | 
				
			||||||
 | 
					  if (mfp == NULL) {
 | 
				
			||||||
 | 
					    goto error;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  buf->b_ml.ml_mfp = mfp;
 | 
					  buf->b_ml.ml_mfp = mfp;
 | 
				
			||||||
  buf->b_ml.ml_flags = ML_EMPTY;
 | 
					  buf->b_ml.ml_flags = ML_EMPTY;
 | 
				
			||||||
@@ -360,10 +363,12 @@ int ml_open(buf_T *buf)
 | 
				
			|||||||
  return OK;
 | 
					  return OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error:
 | 
					error:
 | 
				
			||||||
 | 
					  if (mfp != NULL) {
 | 
				
			||||||
    if (hp) {
 | 
					    if (hp) {
 | 
				
			||||||
      mf_put(mfp, hp, false, false);
 | 
					      mf_put(mfp, hp, false, false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    mf_close(mfp, true);  // will also xfree(mfp->mf_fname)
 | 
					    mf_close(mfp, true);  // will also xfree(mfp->mf_fname)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  buf->b_ml.ml_mfp = NULL;
 | 
					  buf->b_ml.ml_mfp = NULL;
 | 
				
			||||||
  return FAIL;
 | 
					  return FAIL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -839,7 +844,7 @@ void ml_recover(void)
 | 
				
			|||||||
                                    mf_open() will consume "fname_used"! */
 | 
					                                    mf_open() will consume "fname_used"! */
 | 
				
			||||||
  mfp = mf_open(fname_used, O_RDONLY);
 | 
					  mfp = mf_open(fname_used, O_RDONLY);
 | 
				
			||||||
  fname_used = p;
 | 
					  fname_used = p;
 | 
				
			||||||
  if (mfp->mf_fd < 0) {
 | 
					  if (mfp == NULL || mfp->mf_fd < 0) {
 | 
				
			||||||
    EMSG2(_("E306: Cannot open %s"), fname_used);
 | 
					    EMSG2(_("E306: Cannot open %s"), fname_used);
 | 
				
			||||||
    goto theend;
 | 
					    goto theend;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2510,7 +2510,7 @@ buf_T *open_spellbuf(void)
 | 
				
			|||||||
  buf->b_spell = true;
 | 
					  buf->b_spell = true;
 | 
				
			||||||
  buf->b_p_swf = true;        // may create a swap file
 | 
					  buf->b_p_swf = true;        // may create a swap file
 | 
				
			||||||
  if (ml_open(buf) == FAIL) {
 | 
					  if (ml_open(buf) == FAIL) {
 | 
				
			||||||
    abort();
 | 
					    ELOG("Error opening a new memline");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  ml_open_file(buf);          // create swap file now
 | 
					  ml_open_file(buf);          // create swap file now
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,11 @@
 | 
				
			|||||||
local Screen = require('test.functional.ui.screen')
 | 
					local Screen = require('test.functional.ui.screen')
 | 
				
			||||||
local helpers = require('test.functional.helpers')(after_each)
 | 
					local helpers = require('test.functional.helpers')(after_each)
 | 
				
			||||||
local lfs = require('lfs')
 | 
					local lfs = require('lfs')
 | 
				
			||||||
local feed_command, eq, eval, expect, source =
 | 
					local eq, eval, expect, source =
 | 
				
			||||||
  helpers.feed_command, helpers.eq, helpers.eval, helpers.expect, helpers.source
 | 
					  helpers.eq, helpers.eval, helpers.expect, helpers.source
 | 
				
			||||||
local clear = helpers.clear
 | 
					local clear = helpers.clear
 | 
				
			||||||
local command = helpers.command
 | 
					local command = helpers.command
 | 
				
			||||||
 | 
					local expect_err = helpers.expect_err
 | 
				
			||||||
local feed = helpers.feed
 | 
					local feed = helpers.feed
 | 
				
			||||||
local nvim_prog = helpers.nvim_prog
 | 
					local nvim_prog = helpers.nvim_prog
 | 
				
			||||||
local ok = helpers.ok
 | 
					local ok = helpers.ok
 | 
				
			||||||
@@ -17,9 +18,14 @@ describe(':recover', function()
 | 
				
			|||||||
  before_each(clear)
 | 
					  before_each(clear)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('fails if given a non-existent swapfile', function()
 | 
					  it('fails if given a non-existent swapfile', function()
 | 
				
			||||||
    local swapname = 'bogus-swapfile'
 | 
					    local swapname = 'bogus_swapfile'
 | 
				
			||||||
    feed_command('recover '..swapname) -- This should not segfault. #2117
 | 
					    local swapname2 = 'bogus_swapfile.swp'
 | 
				
			||||||
    eq('E305: No swap file found for '..swapname, eval('v:errmsg'))
 | 
					    expect_err('E305: No swap file found for '..swapname,
 | 
				
			||||||
 | 
					               command, 'recover '..swapname)  -- Should not segfault. #2117
 | 
				
			||||||
 | 
					    -- Also check filename ending with ".swp". #9504
 | 
				
			||||||
 | 
					    expect_err('Vim%(recover%):E306: Cannot open '..swapname2,
 | 
				
			||||||
 | 
					               command, 'recover '..swapname2)  -- Should not segfault. #2117
 | 
				
			||||||
 | 
					    eq(2, eval('1+1'))  -- Still alive?
 | 
				
			||||||
  end)
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
end)
 | 
					end)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user