Browse Source

Merge branch 'np/compress-loose-object-memsave' into maint

* np/compress-loose-object-memsave:
  sha1_file: be paranoid when creating loose objects
  sha1_file: don't malloc the whole compressed result when writing out objects
maint
Junio C Hamano 15 years ago
parent
commit
035aa7678b
  1. 33
      sha1_file.c

33
sha1_file.c

@ -2281,9 +2281,10 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
void *buf, unsigned long len, time_t mtime) void *buf, unsigned long len, time_t mtime)
{ {
int fd, ret; int fd, ret;
size_t size; unsigned char compressed[4096];
unsigned char *compressed;
z_stream stream; z_stream stream;
git_SHA_CTX c;
unsigned char parano_sha1[20];
char *filename; char *filename;
static char tmpfile[PATH_MAX]; static char tmpfile[PATH_MAX];


@ -2301,36 +2302,40 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
/* Set it up */ /* Set it up */
memset(&stream, 0, sizeof(stream)); memset(&stream, 0, sizeof(stream));
deflateInit(&stream, zlib_compression_level); deflateInit(&stream, zlib_compression_level);
size = 8 + deflateBound(&stream, len+hdrlen);
compressed = xmalloc(size);

/* Compress it */
stream.next_out = compressed; stream.next_out = compressed;
stream.avail_out = size; stream.avail_out = sizeof(compressed);
git_SHA1_Init(&c);


/* First header.. */ /* First header.. */
stream.next_in = (unsigned char *)hdr; stream.next_in = (unsigned char *)hdr;
stream.avail_in = hdrlen; stream.avail_in = hdrlen;
while (deflate(&stream, 0) == Z_OK) while (deflate(&stream, 0) == Z_OK)
/* nothing */; /* nothing */;
git_SHA1_Update(&c, hdr, hdrlen);


/* Then the data itself.. */ /* Then the data itself.. */
stream.next_in = buf; stream.next_in = buf;
stream.avail_in = len; stream.avail_in = len;
ret = deflate(&stream, Z_FINISH); do {
unsigned char *in0 = stream.next_in;
ret = deflate(&stream, Z_FINISH);
git_SHA1_Update(&c, in0, stream.next_in - in0);
if (write_buffer(fd, compressed, stream.next_out - compressed) < 0)
die("unable to write sha1 file");
stream.next_out = compressed;
stream.avail_out = sizeof(compressed);
} while (ret == Z_OK);

if (ret != Z_STREAM_END) if (ret != Z_STREAM_END)
die("unable to deflate new object %s (%d)", sha1_to_hex(sha1), ret); die("unable to deflate new object %s (%d)", sha1_to_hex(sha1), ret);

ret = deflateEnd(&stream); ret = deflateEnd(&stream);
if (ret != Z_OK) if (ret != Z_OK)
die("deflateEnd on object %s failed (%d)", sha1_to_hex(sha1), ret); die("deflateEnd on object %s failed (%d)", sha1_to_hex(sha1), ret);
git_SHA1_Final(parano_sha1, &c);
if (hashcmp(sha1, parano_sha1) != 0)
die("confused by unstable object source data for %s", sha1_to_hex(sha1));


size = stream.total_out;

if (write_buffer(fd, compressed, size) < 0)
die("unable to write sha1 file");
close_sha1_file(fd); close_sha1_file(fd);
free(compressed);


if (mtime) { if (mtime) {
struct utimbuf utb; struct utimbuf utb;

Loading…
Cancel
Save