{
        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';
 }
 
 /*
                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));
        }
 
                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);
 
 /* 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);
 
 
        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;
+}