*/
has_error = FALSE;
+ // Verify the cached block's actual size matches the
+ // pointer entry's pe_page_count. mf_get() cache hits
+ // return the original block without resizing, so a
+ // crafted swap file referencing the same block twice
+ // with different pe_page_count values would cause an
+ // OOB write below.
+ if (hp->bh_page_count != page_count)
+ {
+ ++error;
+ ml_append(lnum++, (char_u *)_("??? BLOCK PAGE COUNT MISMATCH"),
+ (colnr_T)0, TRUE);
+ page_count = hp->bh_page_count;
+ }
+
// 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)
msgstr ""
"Project-Id-Version: Vim\n"
"Report-Msgid-Bugs-To: vim-dev@vim.org\n"
-"POT-Creation-Date: 2026-06-24 17:52+0000\n"
+"POT-Creation-Date: 2026-06-27 08:41+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "???BLOCK MISSING"
msgstr ""
+msgid "??? BLOCK PAGE COUNT MISMATCH"
+msgstr ""
+
msgid "??? from here until ???END lines may be messed up"
msgstr ""
call assert_match('???ILLEGAL BLOCK NUMBER', content)
call delete(target)
bw!
-"
-" " Test 2: Segfault
+
+ " Test 2: Segfault
new
let sample = 'samples/recover-crash2.swp'
let target = 'Xpoc2.swp'
call assert_match('???LINES MISSING', content)
call delete(target)
bw!
+
+ " Test 3: wrong page_count header
+ new
+ let sample = 'samples/recover-mismatch-pc.swp'
+ let target = 'Xmismatch-pc.swp'
+ call writefile(readblob(sample), target, 'bD')
+ try
+ sil noa recover! Xmismatch-pc.swp
+ catch
+ endtry
+ " Verifies no crash occurs. The OOB write is only reliably triggered
+ " interactively due to memory pressure evicting blocks in the test runner.
+ bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 738,
/**/
737,
/**/