vim-patch:9.0.0026: accessing freed memory with diff put (#19564)

Problem:    Accessing freed memory with diff put.
Solution:   Bail out when diff pointer is no longer valid.
c5274dd122
This commit is contained in:
zeertzjq 2022-07-29 06:53:32 +08:00 committed by GitHub
parent b25abbf4b8
commit 352a177dae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2487,6 +2487,17 @@ void nv_diffgetput(bool put, size_t count)
ex_diffgetput(&ea); ex_diffgetput(&ea);
} }
/// Return true if "diff" appears in the list of diff blocks of the current tab.
static bool valid_diff(diff_T *diff)
{
for (diff_T *dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next) {
if (dp == diff) {
return true;
}
}
return false;
}
/// ":diffget" and ":diffput" /// ":diffget" and ":diffput"
/// ///
/// @param eap /// @param eap
@ -2744,10 +2755,9 @@ void ex_diffgetput(exarg_T *eap)
} }
} }
// Adjust marks. This will change the following entries!
if (added != 0) { if (added != 0) {
mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, added, // Adjust marks. This will change the following entries!
kExtmarkUndo); mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, added, kExtmarkUndo);
if (curwin->w_cursor.lnum >= lnum) { if (curwin->w_cursor.lnum >= lnum) {
// Adjust the cursor position if it's in/after the changed // Adjust the cursor position if it's in/after the changed
// lines. // lines.
@ -2764,7 +2774,15 @@ void ex_diffgetput(exarg_T *eap)
// Diff is deleted, update folds in other windows. // Diff is deleted, update folds in other windows.
diff_fold_update(dfree, idx_to); diff_fold_update(dfree, idx_to);
xfree(dfree); xfree(dfree);
} else { }
// mark_adjust() may have made "dp" invalid. We don't know where
// to continue then, bail out.
if (added != 0 && !valid_diff(dp)) {
break;
}
if (dfree == NULL) {
// mark_adjust() may have changed the count in a wrong way // mark_adjust() may have changed the count in a wrong way
dp->df_count[idx_to] = new_count; dp->df_count[idx_to] = new_count;
} }