changeset 6130:86fb698a38d5 v7.4.403

updated for version 7.4.403 Problem: Valgrind reports errors when running test 72. (Dominique Pelle) Solution: Reset the local 'cryptmethod' option before storing the seed. Set the seed in the memfile even when there is no block0 yet.
author Bram Moolenaar <bram@vim.org>
date Wed, 13 Aug 2014 21:58:28 +0200
parents 6c3ed76a6e89
children b201f6f99781
files src/fileio.c src/memline.c src/option.c src/version.c
diffstat 4 files changed, 43 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2944,6 +2944,7 @@ check_for_cryptkey(cryptkey, ptr, sizep,
 	 * Avoids accidentally overwriting the file with garbage. */
 	curbuf->b_p_ro = TRUE;
 
+	/* Set the cryptmethod local to the buffer. */
 	crypt_set_cm_option(curbuf, method);
 	if (cryptkey == NULL && !*did_ask)
 	{
--- a/src/memline.c
+++ b/src/memline.c
@@ -235,6 +235,7 @@ typedef enum {
 } upd_block0_T;
 
 #ifdef FEAT_CRYPT
+static void ml_set_mfp_crypt __ARGS((buf_T *buf));
 static void ml_set_b0_crypt __ARGS((buf_T *buf, ZERO_BL *b0p));
 #endif
 static int ml_check_b0_id __ARGS((ZERO_BL *b0p));
@@ -433,6 +434,25 @@ error:
 
 #if defined(FEAT_CRYPT) || defined(PROTO)
 /*
+ * Prepare encryption for "buf" for the current key and method.
+ */
+    static void
+ml_set_mfp_crypt(buf)
+    buf_T	*buf;
+{
+    if (*buf->b_p_key != NUL)
+    {
+	int method_nr = crypt_get_method_nr(buf);
+
+	if (method_nr > CRYPT_M_ZIP)
+	{
+	    /* Generate a seed and store it in the memfile. */
+	    sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0);
+	}
+    }
+}
+
+/*
  * Prepare encryption for "buf" with block 0 "b0p".
  */
     static void
@@ -915,8 +935,19 @@ ml_upd_block0(buf, what)
     ZERO_BL	*b0p;
 
     mfp = buf->b_ml.ml_mfp;
-    if (mfp == NULL || (hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL)
+    if (mfp == NULL)
 	return;
+    hp = mf_get(mfp, (blocknr_T)0, 1);
+    if (hp == NULL)
+    {
+#ifdef FEAT_CRYPT
+	/* Possibly update the seed in the memfile before there is a block0. */
+	if (what == UB_CRYPT)
+	    ml_set_mfp_crypt(buf);
+#endif
+	return;
+    }
+
     b0p = (ZERO_BL *)(hp->bh_data);
     if (ml_check_b0_id(b0p) == FAIL)
 	EMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
--- a/src/option.c
+++ b/src/option.c
@@ -6163,6 +6163,14 @@ did_set_string_option(opt_idx, varp, new
 		p_cm = vim_strsave((char_u *)"zip");
 		new_value_alloced = TRUE;
 	    }
+	    /* When using ":set cm=name" the local value is going to be empty.
+	     * Do that here, otherwise the crypt functions will still use the
+	     * local value. */
+	    if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
+	    {
+		free_string_option(curbuf->b_p_cm);
+		curbuf->b_p_cm = empty_option;
+	    }
 
 	    /* Need to update the swapfile when the effective method changed.
 	     * Set "s" to the effective old value, "p" to the effective new
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    403,
+/**/
     402,
 /**/
     401,