~ruther/guix-local

0c5028faea7e5c08c920f8ea31f02e7923b8c2d8 — Ludovic Courtès 12 years ago 37dd969
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'.
3 files changed, 23 insertions(+), 3 deletions(-)

M nix/libutil/gcrypt-hash.cc
M nix/libutil/gcrypt-hash.hh
M nix/sync-with-upstream
M nix/libutil/gcrypt-hash.cc => nix/libutil/gcrypt-hash.cc +1 -0
@@ 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;
}

}

M nix/libutil/gcrypt-hash.hh => nix/libutil/gcrypt-hash.hh +14 -3
@@ 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);

}

M nix/sync-with-upstream => nix/sync-with-upstream +8 -0
@@ 70,3 70,11 @@ cp -v "$top_srcdir/nix-upstream/AUTHORS" "$top_srcdir/nix"
# Substitutions.
sed -i "$top_srcdir/nix/libstore/gc.cc"					\
    -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'