aboutsummaryrefslogtreecommitdiff
path: root/sha1_file.c
diff options
context:
space:
mode:
authorSergey Vlasov <vsu@altlinux.ru>2005-08-08 22:45:36 +0400
committerJunio C Hamano <junkio@cox.net>2005-08-08 22:51:45 -0700
commitbfc66daf5c0dcb1a507ff2533760ac5505eee6a3 (patch)
tree9c1182bc1cf0b818f39c777eae225659a872c369 /sha1_file.c
parent1cf58e72225f45472124266c020f8595988374d8 (diff)
downloadgit-bfc66daf5c0dcb1a507ff2533760ac5505eee6a3.tar.gz
git-bfc66daf5c0dcb1a507ff2533760ac5505eee6a3.tar.xz
[PATCH] Plug memory leak in write_sha1_to_fd()
If the object to write was packed, both its uncompressed and compressed data were leaked. If the object was not packed, its file was not unmapped. [jc: I think it still leaks on the write error path of write_sha1_to_fd(), but that should be fixable in a small separate patch.] Signed-off-by: Sergey Vlasov <vsu@altlinux.ru> Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'sha1_file.c')
-rw-r--r--sha1_file.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/sha1_file.c b/sha1_file.c
index a4bf06798..e9285c144 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1297,8 +1297,11 @@ int write_sha1_to_fd(int fd, const unsigned char *sha1)
ssize_t size;
unsigned long objsize;
int posn = 0;
- void *buf = map_sha1_file_internal(sha1, &objsize);
+ void *map = map_sha1_file_internal(sha1, &objsize);
+ void *buf = map;
+ void *temp_obj = NULL;
z_stream stream;
+
if (!buf) {
unsigned char *unpacked;
unsigned long len;
@@ -1314,7 +1317,7 @@ int write_sha1_to_fd(int fd, const unsigned char *sha1)
memset(&stream, 0, sizeof(stream));
deflateInit(&stream, Z_BEST_COMPRESSION);
size = deflateBound(&stream, len + hdrlen);
- buf = xmalloc(size);
+ temp_obj = buf = xmalloc(size);
/* Compress it */
stream.next_out = buf;
@@ -1332,6 +1335,7 @@ int write_sha1_to_fd(int fd, const unsigned char *sha1)
while (deflate(&stream, Z_FINISH) == Z_OK)
/* nothing */;
deflateEnd(&stream);
+ free(unpacked);
objsize = stream.total_out;
}
@@ -1348,6 +1352,12 @@ int write_sha1_to_fd(int fd, const unsigned char *sha1)
}
posn += size;
} while (posn < objsize);
+
+ if (map)
+ munmap(map, objsize);
+ if (temp_obj)
+ free(temp_obj);
+
return 0;
}