To: vim_dev@googlegroups.com Subject: Patch 9.0.1494 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///