diff options
-rw-r--r-- | archive-tar.c | 16 | ||||
-rw-r--r-- | archive-zip.c | 2 | ||||
-rw-r--r-- | cache.h | 1 | ||||
-rw-r--r-- | convert.c | 15 |
4 files changed, 26 insertions, 8 deletions
diff --git a/archive-tar.c b/archive-tar.c index 56ff35696..33e76576f 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -82,12 +82,13 @@ static void strbuf_append_string(struct strbuf *sb, const char *s) { int slen = strlen(s); int total = sb->len + slen; - if (total > sb->alloc) { - sb->buf = xrealloc(sb->buf, total); - sb->alloc = total; + if (total + 1 > sb->alloc) { + sb->buf = xrealloc(sb->buf, total + 1); + sb->alloc = total + 1; } memcpy(sb->buf + sb->len, s, slen); sb->len = total; + sb->buf[total] = '\0'; } /* @@ -270,20 +271,21 @@ static int write_tar_entry(const unsigned char *sha1, path.alloc = PATH_MAX; path.len = path.eof = 0; } - if (path.alloc < baselen + filenamelen) { + if (path.alloc < baselen + filenamelen + 1) { free(path.buf); - path.buf = xmalloc(baselen + filenamelen); - path.alloc = baselen + filenamelen; + path.buf = xmalloc(baselen + filenamelen + 1); + path.alloc = baselen + filenamelen + 1; } memcpy(path.buf, base, baselen); memcpy(path.buf + baselen, filename, filenamelen); path.len = baselen + filenamelen; + path.buf[path.len] = '\0'; if (S_ISDIR(mode) || S_ISDIRLNK(mode)) { strbuf_append_string(&path, "/"); buffer = NULL; size = 0; } else { - buffer = read_sha1_file(sha1, &type, &size); + buffer = convert_sha1_file(path.buf, sha1, mode, &type, &size); if (!buffer) die("cannot read %s", sha1_to_hex(sha1)); } diff --git a/archive-zip.c b/archive-zip.c index 1eaf262b7..3cbf6bb8a 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -195,7 +195,7 @@ static int write_zip_entry(const unsigned char *sha1, if (S_ISREG(mode) && zlib_compression_level != 0) method = 8; result = 0; - buffer = read_sha1_file(sha1, &type, &size); + buffer = convert_sha1_file(path, sha1, mode, &type, &size); if (!buffer) die("cannot read %s", sha1_to_hex(sha1)); crc = crc32(crc, buffer, size); @@ -548,6 +548,7 @@ extern void trace_argv_printf(const char **argv, int count, const char *format, /* convert.c */ extern char *convert_to_git(const char *path, const char *src, unsigned long *sizep); extern char *convert_to_working_tree(const char *path, const char *src, unsigned long *sizep); +extern void *convert_sha1_file(const char *path, const unsigned char *sha1, unsigned int mode, enum object_type *type, unsigned long *size); /* match-trees.c */ void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int); @@ -652,3 +652,18 @@ char *convert_to_working_tree(const char *path, const char *src, unsigned long * return buf; } + +void *convert_sha1_file(const char *path, const unsigned char *sha1, + unsigned int mode, enum object_type *type, + unsigned long *size) +{ + void *buffer = read_sha1_file(sha1, type, size); + if (S_ISREG(mode) && buffer) { + void *converted = convert_to_working_tree(path, buffer, size); + if (converted) { + free(buffer); + buffer = converted; + } + } + return buffer; +} |