mirror of
https://github.com/vim/vim.git
synced 2025-10-16 07:24:23 -04:00
patch 9.0.1494: crash when recovering from corrupted swap file
Problem: Crash when recovering from corrupted swap file. Solution: Bail out when the line index looks wrong. (closes #12276)
This commit is contained in:
@@ -1637,14 +1637,13 @@ ml_recover(int checkext)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* it is a data block
|
* It is a data block.
|
||||||
* Append all the lines in this block
|
* Append all the lines in this block.
|
||||||
*/
|
*/
|
||||||
has_error = FALSE;
|
has_error = FALSE;
|
||||||
/*
|
|
||||||
* check length of block
|
// Check the length of the block.
|
||||||
* if wrong, use length in pointer block
|
// If wrong, use the length given in the pointer block.
|
||||||
*/
|
|
||||||
if (page_count * mfp->mf_page_size != dp->db_txt_end)
|
if (page_count * mfp->mf_page_size != dp->db_txt_end)
|
||||||
{
|
{
|
||||||
ml_append(lnum++, (char_u *)_("??? from here until ???END lines may be messed up"),
|
ml_append(lnum++, (char_u *)_("??? from here until ???END lines may be messed up"),
|
||||||
@@ -1654,13 +1653,12 @@ ml_recover(int checkext)
|
|||||||
dp->db_txt_end = page_count * mfp->mf_page_size;
|
dp->db_txt_end = page_count * mfp->mf_page_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure there is a NUL at the end of the block
|
// Make sure there is a NUL at the end of the block so we
|
||||||
|
// don't go over the end when copying text.
|
||||||
*((char_u *)dp + dp->db_txt_end - 1) = NUL;
|
*((char_u *)dp + dp->db_txt_end - 1) = NUL;
|
||||||
|
|
||||||
/*
|
// Check the number of lines in the block.
|
||||||
* check number of lines in block
|
// If wrong, use the count in the data block.
|
||||||
* if wrong, use count in data block
|
|
||||||
*/
|
|
||||||
if (line_count != dp->db_line_count)
|
if (line_count != dp->db_line_count)
|
||||||
{
|
{
|
||||||
ml_append(lnum++, (char_u *)_("??? from here until ???END lines may have been inserted/deleted"),
|
ml_append(lnum++, (char_u *)_("??? from here until ???END lines may have been inserted/deleted"),
|
||||||
@@ -1669,17 +1667,36 @@ ml_recover(int checkext)
|
|||||||
has_error = TRUE;
|
has_error = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int did_questions = FALSE;
|
||||||
for (i = 0; i < dp->db_line_count; ++i)
|
for (i = 0; i < dp->db_line_count; ++i)
|
||||||
{
|
{
|
||||||
|
if ((char_u *)&(dp->db_index[i])
|
||||||
|
>= (char_u *)dp + dp->db_txt_start)
|
||||||
|
{
|
||||||
|
// line count must be wrong
|
||||||
|
++error;
|
||||||
|
ml_append(lnum++,
|
||||||
|
(char_u *)_("??? lines may be missing"),
|
||||||
|
(colnr_T)0, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
txt_start = (dp->db_index[i] & DB_INDEX_MASK);
|
txt_start = (dp->db_index[i] & DB_INDEX_MASK);
|
||||||
if (txt_start <= (int)HEADER_SIZE
|
if (txt_start <= (int)HEADER_SIZE
|
||||||
|| txt_start >= (int)dp->db_txt_end)
|
|| txt_start >= (int)dp->db_txt_end)
|
||||||
{
|
{
|
||||||
p = (char_u *)"???";
|
|
||||||
++error;
|
++error;
|
||||||
|
// avoid lots of lines with "???"
|
||||||
|
if (did_questions)
|
||||||
|
continue;
|
||||||
|
did_questions = TRUE;
|
||||||
|
p = (char_u *)"???";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
did_questions = FALSE;
|
||||||
p = (char_u *)dp + txt_start;
|
p = (char_u *)dp + txt_start;
|
||||||
|
}
|
||||||
ml_append(lnum++, p, (colnr_T)0, TRUE);
|
ml_append(lnum++, p, (colnr_T)0, TRUE);
|
||||||
}
|
}
|
||||||
if (has_error)
|
if (has_error)
|
||||||
|
@@ -293,6 +293,21 @@ func Test_recover_corrupted_swap_file()
|
|||||||
\ '???END'], getline(1, '$'))
|
\ '???END'], getline(1, '$'))
|
||||||
bw!
|
bw!
|
||||||
|
|
||||||
|
" set the number of lines in the data block to a large value
|
||||||
|
let b = copy(save_b)
|
||||||
|
if system_64bit
|
||||||
|
let b[8208:8215] = 0z00FFFFFF.FFFFFF00
|
||||||
|
else
|
||||||
|
let b[8208:8211] = 0z00FFFF00
|
||||||
|
endif
|
||||||
|
call writefile(b, sn)
|
||||||
|
call assert_fails('recover Xfile1', 'E312:')
|
||||||
|
call assert_equal('Xfile1', @%)
|
||||||
|
call assert_equal(['??? from here until ???END lines may have been inserted/deleted',
|
||||||
|
\ '', '???', '??? lines may be missing',
|
||||||
|
\ '???END'], getline(1, '$'))
|
||||||
|
bw!
|
||||||
|
|
||||||
" use an invalid text start for the lines in a data block
|
" use an invalid text start for the lines in a data block
|
||||||
let b = copy(save_b)
|
let b = copy(save_b)
|
||||||
if system_64bit
|
if system_64bit
|
||||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1494,
|
||||||
/**/
|
/**/
|
||||||
1493,
|
1493,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user