Mercurial > vim
comparison src/indent.c @ 21070:87e85a13e9cf v8.2.1086
patch 8.2.1086: possibly using freed memory when text properties used
Commit: https://github.com/vim/vim/commit/cf30643ae607ae1a97b50e19c622dc8303723fa2
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Jun 29 20:40:37 2020 +0200
patch 8.2.1086: possibly using freed memory when text properties used
Problem: Possibly using freed memory when text properties used when
changing indent of a line.
Solution: Compute the offset before calling ml_replace().
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 29 Jun 2020 20:45:04 +0200 |
parents | 06a1dd50463e |
children | e82579016863 |
comparison
equal
deleted
inserted
replaced
21069:bb3674ff2c25 | 21070:87e85a13e9cf |
---|---|
755 mch_memmove(s, p, (size_t)line_len); | 755 mch_memmove(s, p, (size_t)line_len); |
756 | 756 |
757 // Replace the line (unless undo fails). | 757 // Replace the line (unless undo fails). |
758 if (!(flags & SIN_UNDO) || u_savesub(curwin->w_cursor.lnum) == OK) | 758 if (!(flags & SIN_UNDO) || u_savesub(curwin->w_cursor.lnum) == OK) |
759 { | 759 { |
760 colnr_T old_offset = (colnr_T)(p - oldline); | |
761 colnr_T new_offset = (colnr_T)(s - newline); | |
762 | |
763 // this may free "newline" | |
760 ml_replace(curwin->w_cursor.lnum, newline, FALSE); | 764 ml_replace(curwin->w_cursor.lnum, newline, FALSE); |
761 if (flags & SIN_CHANGED) | 765 if (flags & SIN_CHANGED) |
762 changed_bytes(curwin->w_cursor.lnum, 0); | 766 changed_bytes(curwin->w_cursor.lnum, 0); |
763 | 767 |
764 // Correct saved cursor position if it is in this line. | 768 // Correct saved cursor position if it is in this line. |
765 if (saved_cursor.lnum == curwin->w_cursor.lnum) | 769 if (saved_cursor.lnum == curwin->w_cursor.lnum) |
766 { | 770 { |
767 if (saved_cursor.col >= (colnr_T)(p - oldline)) | 771 if (saved_cursor.col >= old_offset) |
768 // cursor was after the indent, adjust for the number of | 772 // cursor was after the indent, adjust for the number of |
769 // bytes added/removed | 773 // bytes added/removed |
770 saved_cursor.col += ind_len - (colnr_T)(p - oldline); | 774 saved_cursor.col += ind_len - old_offset; |
771 else if (saved_cursor.col >= (colnr_T)(s - newline)) | 775 else if (saved_cursor.col >= new_offset) |
772 // cursor was in the indent, and is now after it, put it back | 776 // cursor was in the indent, and is now after it, put it back |
773 // at the start of the indent (replacing spaces with TAB) | 777 // at the start of the indent (replacing spaces with TAB) |
774 saved_cursor.col = (colnr_T)(s - newline); | 778 saved_cursor.col = new_offset; |
775 } | 779 } |
776 #ifdef FEAT_PROP_POPUP | 780 #ifdef FEAT_PROP_POPUP |
777 { | 781 { |
778 int added = ind_len - (colnr_T)(p - oldline); | 782 int added = ind_len - old_offset; |
779 | 783 |
780 // When increasing indent this behaves like spaces were inserted at | 784 // When increasing indent this behaves like spaces were inserted at |
781 // the old indent, when decreasing indent it behaves like spaces | 785 // the old indent, when decreasing indent it behaves like spaces |
782 // were deleted at the new indent. | 786 // were deleted at the new indent. |
783 adjust_prop_columns(curwin->w_cursor.lnum, | 787 adjust_prop_columns(curwin->w_cursor.lnum, |
784 (colnr_T)(added > 0 ? (p - oldline) : ind_len), added, 0); | 788 added > 0 ? old_offset : (colnr_T)ind_len, added, 0); |
785 } | 789 } |
786 #endif | 790 #endif |
787 retval = TRUE; | 791 retval = TRUE; |
788 } | 792 } |
789 else | 793 else |