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'.
This commit is contained in:
parent
37dd969c2e
commit
0c5028faea
|
@ -45,6 +45,7 @@ guix_hash_final (void *resbuf, struct guix_hash_context *ctx,
|
||||||
memcpy (resbuf, gcry_md_read (ctx->md_handle, algo),
|
memcpy (resbuf, gcry_md_read (ctx->md_handle, algo),
|
||||||
gcry_md_get_algo_dlen (algo));
|
gcry_md_get_algo_dlen (algo));
|
||||||
gcry_md_close (ctx->md_handle);
|
gcry_md_close (ctx->md_handle);
|
||||||
|
ctx->md_handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,17 +23,28 @@
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
struct guix_hash_context
|
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;
|
gcry_md_hd_t md_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
extern void guix_hash_init (struct guix_hash_context *ctx, int algo);
|
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,
|
extern void guix_hash_update (struct guix_hash_context *ctx, const void *buffer,
|
||||||
size_t len);
|
size_t len);
|
||||||
extern void guix_hash_final (void *resbuf, struct guix_hash_context *ctx,
|
extern void guix_hash_final (void *resbuf, struct guix_hash_context *ctx,
|
||||||
int algo);
|
int algo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,3 +70,11 @@ cp -v "$top_srcdir/nix-upstream/AUTHORS" "$top_srcdir/nix"
|
||||||
# Substitutions.
|
# Substitutions.
|
||||||
sed -i "$top_srcdir/nix/libstore/gc.cc" \
|
sed -i "$top_srcdir/nix/libstore/gc.cc" \
|
||||||
-e 's|/nix/find-runtime-roots\.pl|/guix/list-runtime-roots|g'
|
-e 's|/nix/find-runtime-roots\.pl|/guix/list-runtime-roots|g'
|
||||||
|
|
||||||
|
# Our 'guix_hash_context' structure has a copy constructor, specifically to
|
||||||
|
# handle the use case in 'HashSink::currentHash()' where the copy of the
|
||||||
|
# context is expected to truly copy the underlying hash context. The copy
|
||||||
|
# constructor cannot be used in 'Ctx' if that's a union, so turn it into a
|
||||||
|
# structure (we can afford to two wasted words.)
|
||||||
|
sed -i "$top_srcdir/nix/libutil/hash".{cc,hh} \
|
||||||
|
-e 's|union Ctx|struct Ctx|g'
|
||||||
|
|
Loading…
Reference in New Issue