Patch 9.0.1494
Problem: Crash when recovering from corrupted swap file.
Solution: Bail out when the line index looks wrong. (closes #12276)
Files: src/memline.c, src/testdir/test_recover.vim
*** ../vim-9.0.1493/src/memline.c 2023-04-24 18:11:32.156258651 +0100
--- src/memline.c 2023-04-27 21:11:19.684101797 +0100
***************
*** 1637,1650 ****
else
{
/*
! * it is a data block
! * Append all the lines in this block
*/
has_error = FALSE;
! /*
! * check length of block
! * if wrong, use length in pointer block
! */
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"),
--- 1637,1649 ----
else
{
/*
! * It is a data block.
! * Append all the lines in this block.
*/
has_error = FALSE;
!
! // Check the length of the block.
! // If wrong, use the length given in the pointer block.
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"),
***************
*** 1654,1666 ****
dp->db_txt_end = page_count * mfp->mf_page_size;
}
! // make sure there is a NUL at the end of the block
*((char_u *)dp + dp->db_txt_end - 1) = NUL;
! /*
! * check number of lines in block
! * if wrong, use count in data block
! */
if (line_count != dp->db_line_count)
{
ml_append(lnum++, (char_u *)_("??? from here until
???END lines may have been inserted/deleted"),
--- 1653,1664 ----
dp->db_txt_end = page_count * mfp->mf_page_size;
}
! // 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;
! // Check the number of lines in the block.
! // If wrong, use the count in the data block.
if (line_count != dp->db_line_count)
{
ml_append(lnum++, (char_u *)_("??? from here until
???END lines may have been inserted/deleted"),
***************
*** 1669,1685 ****
has_error = TRUE;
}
for (i = 0; i < dp->db_line_count; ++i)
{
txt_start = (dp->db_index[i] & DB_INDEX_MASK);
if (txt_start <= (int)HEADER_SIZE
|| txt_start >= (int)dp->db_txt_end)
{
- p = (char_u *)"???";
++error;
}
else
p = (char_u *)dp + txt_start;
ml_append(lnum++, p, (colnr_T)0, TRUE);
}
if (has_error)
--- 1667,1702 ----
has_error = TRUE;
}
+ int did_questions = FALSE;
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);
if (txt_start <= (int)HEADER_SIZE
|| txt_start >= (int)dp->db_txt_end)
{
++error;
+ // avoid lots of lines with "???"
+ if (did_questions)
+ continue;
+ did_questions = TRUE;
+ p = (char_u *)"???";
}
else
+ {
+ did_questions = FALSE;
p = (char_u *)dp + txt_start;
+ }
ml_append(lnum++, p, (colnr_T)0, TRUE);
}
if (has_error)
*** ../vim-9.0.1493/src/testdir/test_recover.vim 2023-04-22
21:14:21.585140551 +0100
--- src/testdir/test_recover.vim 2023-04-27 21:07:56.991869044 +0100
***************
*** 293,298 ****
--- 293,313 ----
\ '???END'], getline(1, '$'))
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
let b = copy(save_b)
if system_64bit
*** ../vim-9.0.1493/src/version.c 2023-04-27 19:36:36.561904172 +0100
--- src/version.c 2023-04-27 20:19:39.217394472 +0100
***************
*** 697,698 ****
--- 697,700 ----
{ /* Add new patch number below this line */
+ /**/
+ 1494,
/**/
--
OLD WOMAN: King of the WHO?
ARTHUR: The Britons.
OLD WOMAN: Who are the Britons?
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/20230427201342.4BC481C09E0%40moolenaar.net.