comparison src/diff.c @ 29367:cc4b36422ecb v9.0.0026

patch 9.0.0026: accessing freed memory with diff put Commit: https://github.com/vim/vim/commit/c5274dd12224421f2430b30c53b881b9403d649e Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jul 2 15:10:00 2022 +0100 patch 9.0.0026: accessing freed memory with diff put Problem: Accessing freed memory with diff put. Solution: Bail out when diff pointer is no longer valid.
author Bram Moolenaar <Bram@vim.org>
date Sat, 02 Jul 2022 16:15:03 +0200
parents 92dd6fef5ace
children 3afe997f4415
comparison
equal deleted inserted replaced
29366:d937ba61d344 29367:cc4b36422ecb
2641 ea.line2 = curwin->w_cursor.lnum; 2641 ea.line2 = curwin->w_cursor.lnum;
2642 ex_diffgetput(&ea); 2642 ex_diffgetput(&ea);
2643 } 2643 }
2644 2644
2645 /* 2645 /*
2646 * Return TRUE if "diff" appears in the list of diff blocks of the current tab.
2647 */
2648 static int
2649 valid_diff(diff_T *diff)
2650 {
2651 diff_T *dp;
2652
2653 for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
2654 if (dp == diff)
2655 return TRUE;
2656 return FALSE;
2657 }
2658
2659 /*
2646 * ":diffget" 2660 * ":diffget"
2647 * ":diffput" 2661 * ":diffput"
2648 */ 2662 */
2649 void 2663 void
2650 ex_diffgetput(exarg_T *eap) 2664 ex_diffgetput(exarg_T *eap)
2897 else 2911 else
2898 dprev->df_next = dp; 2912 dprev->df_next = dp;
2899 } 2913 }
2900 } 2914 }
2901 2915
2902 // Adjust marks. This will change the following entries!
2903 if (added != 0) 2916 if (added != 0)
2904 { 2917 {
2918 // Adjust marks. This will change the following entries!
2905 mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added); 2919 mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added);
2906 if (curwin->w_cursor.lnum >= lnum) 2920 if (curwin->w_cursor.lnum >= lnum)
2907 { 2921 {
2908 // Adjust the cursor position if it's in/after the changed 2922 // Adjust the cursor position if it's in/after the changed
2909 // lines. 2923 // lines.
2921 #ifdef FEAT_FOLDING 2935 #ifdef FEAT_FOLDING
2922 diff_fold_update(dfree, idx_to); 2936 diff_fold_update(dfree, idx_to);
2923 #endif 2937 #endif
2924 vim_free(dfree); 2938 vim_free(dfree);
2925 } 2939 }
2926 else 2940
2941 // mark_adjust() may have made "dp" invalid. We don't know where
2942 // to continue then, bail out.
2943 if (added != 0 && !valid_diff(dp))
2944 break;
2945
2946 if (dfree == NULL)
2927 // mark_adjust() may have changed the count in a wrong way 2947 // mark_adjust() may have changed the count in a wrong way
2928 dp->df_count[idx_to] = new_count; 2948 dp->df_count[idx_to] = new_count;
2929 2949
2930 // When changing the current buffer, keep track of line numbers 2950 // When changing the current buffer, keep track of line numbers
2931 if (idx_cur == idx_to) 2951 if (idx_cur == idx_to)