changeset 25052:965d97f8208b v8.2.3063

patch 8.2.3063: crash when switching 'cryptmethod' to xchaha20 with undo file Commit: https://github.com/vim/vim/commit/65aee0b714e809b9f19862f3decd35055ed4de10 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jun 27 14:08:24 2021 +0200 patch 8.2.3063: crash when switching 'cryptmethod' to xchaha20 with undo file Problem: Crash when switching 'cryptmethod' to xchaha20 with an existing undo file. (Martin Tournoij) Solution: Disable reading undo file when decoding can't be done inplace. (issue #8467)
author Bram Moolenaar <Bram@vim.org>
date Sun, 27 Jun 2021 14:15:03 +0200
parents bffb0c617c1c
children ce8252036ab0
files src/bufwrite.c src/fileio.c src/version.c
diffstat 3 files changed, 22 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/bufwrite.c
+++ b/src/bufwrite.c
@@ -494,14 +494,16 @@ buf_write_bytes(struct bw_info *ip)
 	if (crypt_works_inplace(ip->bw_buffer->b_cryptstate))
 	{
 # endif
-	    crypt_encode_inplace(ip->bw_buffer->b_cryptstate, buf, len, ip->bw_finish);
+	    crypt_encode_inplace(ip->bw_buffer->b_cryptstate, buf, len,
+								ip->bw_finish);
 # ifdef CRYPT_NOT_INPLACE
 	}
 	else
 	{
 	    char_u *outbuf;
 
-	    len = crypt_encode_alloc(curbuf->b_cryptstate, buf, len, &outbuf, ip->bw_finish);
+	    len = crypt_encode_alloc(curbuf->b_cryptstate, buf, len, &outbuf,
+								ip->bw_finish);
 	    if (len == 0)
 		return OK;  // Crypt layer is buffering, will flush later.
 	    wlen = write_eintr(ip->bw_fd, outbuf, len);
@@ -1980,10 +1982,18 @@ restore_backup:
 	write_info.bw_start_lnum = start;
 
 #ifdef FEAT_PERSISTENT_UNDO
+	// TODO: if the selected crypt method prevents the undo file from being
+	// written, and existing undo file should be deleted.
 	write_undo_file = (buf->b_p_udf
 			    && overwriting
 			    && !append
 			    && !filtering
+# ifdef CRYPT_NOT_INPLACE
+			    // writing undo file requires
+			    // crypt_encode_inplace()
+			    && (curbuf->b_cryptstate == NULL
+				|| crypt_works_inplace(curbuf->b_cryptstate))
+# endif
 			    && reset_changed
 			    && !checking_conversion);
 	if (write_undo_file)
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1298,9 +1298,17 @@ retry:
 		 * At start of file: Check for magic number of encryption.
 		 */
 		if (filesize == 0 && size > 0)
+		{
 		    cryptkey = check_for_cryptkey(cryptkey, ptr, &size,
 						  &filesize, newfile, sfname,
 						  &did_ask_for_key);
+# ifdef CRYPT_NOT_INPLACE
+		    if (curbuf->b_cryptstate != NULL
+				 && !crypt_works_inplace(curbuf->b_cryptstate))
+			// reading undo file requires crypt_decode_inplace()
+			read_undo_file = FALSE;
+# endif
+		}
 		/*
 		 * Decrypt the read bytes.  This is done before checking for
 		 * EOF because the crypt layer may be buffering.
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3063,
+/**/
     3062,
 /**/
     3061,