aboutsummaryrefslogtreecommitdiff
path: root/nix/libutil
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2013-12-18 21:48:57 +0100
committerLudovic Courtès <ludo@gnu.org>2013-12-19 00:02:49 +0100
commit0c5028faea7e5c08c920f8ea31f02e7923b8c2d8 (patch)
treeeb48ffdc6c937bed19a81091dcd5d4cfad1e86b8 /nix/libutil
parent37dd969c2eff527e21e2d277b3f4433111a0ca9e (diff)
downloadguix-0c5028faea7e5c08c920f8ea31f02e7923b8c2d8.tar
guix-0c5028faea7e5c08c920f8ea31f02e7923b8c2d8.tar.gz
daemon: Fix 'HashSink::currentHash()'.
Before that, calls to 'HashSink::currentHash()' would eventually lead to a segfault because the underlying gcrypt handle has been closed. (Note that this method is only used via 'importPaths' and 'exportPath', though.) * nix/libutil/gcrypt-hash.hh (struct guix_hash_context): Add a constructor and a copy constructor; move out of 'extern "C"'. * nix/libutil/gcrypt-hash.cc (guix_hash_final): Clear 'md_handle' upon exit. * nix/sync-with-upstream (top_srcdir): Change hash.{cc,hh} to read 'struct Ctx' instead of 'union Ctx'.
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);
-
}