summaryrefslogtreecommitdiffstats
path: root/src/memline.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2023-04-22 21:14:26 +0100
committerBram Moolenaar <Bram@vim.org>2023-04-22 21:14:26 +0100
commitb67ba03d3ef2e6c5f207d508e85fc6906f938028 (patch)
treeec9c376833880f135b7391e2db774e5509996788 /src/memline.c
parente7f05a8780426dc7af247419c6d02d5f1e896689 (diff)
patch 9.0.1477: crash when recovering from corrupted swap filev9.0.1477
Problem: Crash when recovering from corrupted swap file. Solution: Check for a valid page count. (closes #12275)
Diffstat (limited to 'src/memline.c')
-rw-r--r--src/memline.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/memline.c b/src/memline.c
index 7acea1346c..ea08d324ce 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -98,6 +98,9 @@ struct pointer_block
// followed by empty space until end of page
};
+// Value for pb_count_max.
+#define PB_COUNT_MAX(mfp) (short_u)(((mfp)->mf_page_size - offsetof(PTR_BL, pb_pointer)) / sizeof(PTR_EN))
+
/*
* A data block is a leaf in the tree.
*
@@ -1525,6 +1528,20 @@ ml_recover(int checkext)
pp = (PTR_BL *)(hp->bh_data);
if (pp->pb_id == PTR_ID) // it is a pointer block
{
+ int ptr_block_error = FALSE;
+ if (pp->pb_count_max != PB_COUNT_MAX(mfp))
+ {
+ ptr_block_error = TRUE;
+ pp->pb_count_max = PB_COUNT_MAX(mfp);
+ }
+ if (pp->pb_count > pp->pb_count_max)
+ {
+ ptr_block_error = TRUE;
+ pp->pb_count = pp->pb_count_max;
+ }
+ if (ptr_block_error)
+ emsg(_(e_warning_pointer_block_corrupted));
+
// check line count when using pointer block first time
if (idx == 0 && line_count != 0)
{
@@ -4162,9 +4179,7 @@ ml_new_ptr(memfile_T *mfp)
pp = (PTR_BL *)(hp->bh_data);
pp->pb_id = PTR_ID;
pp->pb_count = 0;
- pp->pb_count_max =
- (short_u)((mfp->mf_page_size - offsetof(PTR_BL, pb_pointer))
- / sizeof(PTR_EN));
+ pp->pb_count_max = PB_COUNT_MAX(mfp);
return hp;
}