summary refs log tree commit diff
path: root/nix/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'nix/libutil')
-rw-r--r--nix/libutil/gcrypt-hash.cc1
-rw-r--r--nix/libutil/gcrypt-hash.hh17
2 files changed, 15 insertions, 3 deletions
diff --git a/nix/libutil/gcrypt-hash.cc b/nix/libutil/gcrypt-hash.cc
index 553f633b93..c4ae7bfcc2 100644
--- a/nix/libutil/gcrypt-hash.cc
+++ b/nix/libutil/gcrypt-hash.cc
@@ -45,6 +45,7 @@ guix_hash_final (void *resbuf, struct guix_hash_context *ctx,
   memcpy (resbuf, gcry_md_read (ctx->md_handle, algo),
 	  gcry_md_get_algo_dlen (algo));
   gcry_md_close (ctx->md_handle);
+  ctx->md_handle = NULL;
 }
 
 }
diff --git a/nix/libutil/gcrypt-hash.hh b/nix/libutil/gcrypt-hash.hh
index d93a6eb881..11f061159f 100644
--- a/nix/libutil/gcrypt-hash.hh
+++ b/nix/libutil/gcrypt-hash.hh
@@ -23,17 +23,28 @@
 #include <gcrypt.h>
 #include <unistd.h>
 
-extern "C" {
-
 struct guix_hash_context
 {
+  /* This copy constructor is needed in 'HashSink::currentHash()' where we
+     expect the copy of a 'Ctx' object to yield a truly different context.  */
+  guix_hash_context (guix_hash_context &ref)
+  {
+    if (ref.md_handle == NULL)
+      md_handle = NULL;
+    else
+      gcry_md_copy (&md_handle, ref.md_handle);
+  }
+
+  /* Make sure 'md_handle' is always initialized.  */
+  guix_hash_context (): md_handle (NULL) { };
+
   gcry_md_hd_t md_handle;
 };
 
+extern "C" {
 extern void guix_hash_init (struct guix_hash_context *ctx, int algo);
 extern void guix_hash_update (struct guix_hash_context *ctx, const void *buffer,
 			      size_t len);
 extern void guix_hash_final (void *resbuf, struct guix_hash_context *ctx,
 			     int algo);
-
 }