@@ -424,6 +424,24 @@ ml_open(buf_T *buf)
424424}
425425
426426#if defined(FEAT_CRYPT ) || defined(PROTO )
427+ /*
428+ * Swapfile encryption is not supported by XChaCha20. If this crypt method is
429+ * used then disable the swapfile, to avoid plain text being written to disk,
430+ * and return TRUE.
431+ * Otherwise return FALSE.
432+ */
433+ static int
434+ crypt_may_close_swapfile (buf_T * buf , char_u * key , int method )
435+ {
436+ if (crypt_method_is_sodium (method ) && * key != NUL )
437+ {
438+ mf_close_file (buf , TRUE);
439+ buf -> b_p_swf = FALSE;
440+ return TRUE;
441+ }
442+ return FALSE;
443+ }
444+
427445/*
428446 * Prepare encryption for "buf" for the current key and method.
429447 */
@@ -440,11 +458,10 @@ ml_set_mfp_crypt(buf_T *buf)
440458 // Generate a seed and store it in the memfile.
441459 sha2_seed (buf -> b_ml .ml_mfp -> mf_seed , MF_SEED_LEN , NULL , 0 );
442460 }
443- #ifdef FEAT_SODIUM
461+ # ifdef FEAT_SODIUM
444462 else if (crypt_method_is_sodium (method_nr ))
445- crypt_sodium_randombytes_buf (buf - > b_ml .ml_mfp - > mf_seed ,
446- MF_SEED_LEN );
447- #endif
463+ crypt_sodium_randombytes_buf (buf - > b_ml .ml_mfp - > mf_seed , MF_SEED_LEN );
464+ # endif
448465}
449466
450467/*
@@ -501,16 +518,10 @@ ml_set_crypt_key(
501518 return ; // no memfile yet, nothing to do
502519 old_method = crypt_method_nr_from_name (old_cm );
503520
504- // Swapfile encryption is not supported by XChaCha20, therefore disable the
505- // swapfile to avoid plain text being written to disk.
506- if (crypt_method_is_sodium (crypt_get_method_nr (buf ))
507- && * buf -> b_p_key != NUL )
508- {
509- // close the swapfile
510- mf_close_file (buf , TRUE);
511- buf -> b_p_swf = FALSE;
521+ #ifdef FEAT_CRYPT
522+ if (crypt_may_close_swapfile (buf , buf -> b_p_key , crypt_get_method_nr (buf )))
512523 return ;
513- }
524+ #endif
514525
515526 // First make sure the swapfile is in a consistent state, using the old
516527 // key and method.
@@ -2494,6 +2505,12 @@ ml_sync_all(int check_file, int check_char)
24942505 || buf -> b_ml .ml_mfp -> mf_fd < 0 )
24952506 continue ; // no file
24962507
2508+ #ifdef FEAT_CRYPT
2509+ if (crypt_may_close_swapfile (buf , buf -> b_p_key ,
2510+ crypt_get_method_nr (buf )))
2511+ continue ;
2512+ #endif
2513+
24972514 ml_flush_line (buf ); // flush buffered line
24982515 // flush locked block
24992516 (void )ml_find_line (buf , (linenr_T )0 , ML_FLUSH );
@@ -2551,6 +2568,10 @@ ml_preserve(buf_T *buf, int message)
25512568 emsg (_ (e_cannot_preserve_there_is_no_swap_file ));
25522569 return ;
25532570 }
2571+ #ifdef FEAT_CRYPT
2572+ if (crypt_may_close_swapfile (buf , buf -> b_p_key , crypt_get_method_nr (buf )))
2573+ return ;
2574+ #endif
25542575
25552576 // We only want to stop when interrupted here, not when interrupted
25562577 // before.
@@ -5571,6 +5592,9 @@ ml_crypt_prepare(memfile_T *mfp, off_T offset, int reading)
55715592 if (* key == NUL )
55725593 return NULL ;
55735594
5595+ if (crypt_may_close_swapfile (buf , key , method_nr ))
5596+ return NULL ;
5597+
55745598 if (method_nr == CRYPT_M_ZIP )
55755599 {
55765600 // For PKzip: Append the offset to the key, so that we use a different
0 commit comments