Don't configure remote "." to fetch everything to itself
[gitweb.git] / sha1_file.c
index f2b1ae0325ea16e4e46152c3d3d2d3d7f2b32e3d..9978a58da68bbf6f3482545d9f290fbfa3f3fe34 100644 (file)
@@ -352,10 +352,14 @@ static void read_info_alternates(const char * relative_base, int depth)
        char *map;
        size_t mapsz;
        struct stat st;
-       char path[PATH_MAX];
+       const char alt_file_name[] = "info/alternates";
+       /* Given that relative_base is no longer than PATH_MAX,
+          ensure that "path" has enough space to append "/", the
+          file name, "info/alternates", and a trailing NUL.  */
+       char path[PATH_MAX + 1 + sizeof alt_file_name];
        int fd;
 
-       sprintf(path, "%s/info/alternates", relative_base);
+       sprintf(path, "%s/%s", relative_base, alt_file_name);
        fd = open(path, O_RDONLY);
        if (fd < 0)
                return;
@@ -493,7 +497,7 @@ static int check_packed_git_idx(const char *path,  struct packed_git *p)
                 */
                if (idx_size != 4*256 + nr * 24 + 20 + 20) {
                        munmap(idx_map, idx_size);
-                       return error("wrong index file size in %s", path);
+                       return error("wrong index v1 file size in %s", path);
                }
        } else if (version == 2) {
                /*
@@ -515,7 +519,7 @@ static int check_packed_git_idx(const char *path,  struct packed_git *p)
                        max_size += (nr - 1)*8;
                if (idx_size < min_size || idx_size > max_size) {
                        munmap(idx_map, idx_size);
-                       return error("wrong index file size in %s", path);
+                       return error("wrong index v2 file size in %s", path);
                }
                if (idx_size != min_size) {
                        /* make sure we can deal with large pack offsets */
@@ -836,7 +840,10 @@ void install_packed_git(struct packed_git *pack)
 
 static void prepare_packed_git_one(char *objdir, int local)
 {
-       char path[PATH_MAX];
+       /* Ensure that this buffer is large enough so that we can
+          append "/pack/" without clobbering the stack even if
+          strlen(objdir) were PATH_MAX.  */
+       char path[PATH_MAX + 1 + 4 + 1 + 1];
        int len;
        DIR *dir;
        struct dirent *de;
@@ -858,6 +865,9 @@ static void prepare_packed_git_one(char *objdir, int local)
                if (!has_extension(de->d_name, ".idx"))
                        continue;
 
+               if (len + namelen + 1 > sizeof(path))
+                       continue;
+
                /* Don't reopen a pack we already have. */
                strcpy(path + len, de->d_name);
                for (p = packed_git; p; p = p->next) {
@@ -1560,6 +1570,10 @@ static void *unpack_delta_entry(struct packed_git *p,
                    (uintmax_t)base_offset, p->pack_name);
 
        delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size);
+       if (!delta_data)
+               die("failed to unpack compressed delta"
+                   " at %"PRIuMAX" from %s",
+                   (uintmax_t)curpos, p->pack_name);
        result = patch_delta(base, base_size,
                             delta_data, delta_size,
                             sizep);
@@ -2294,27 +2308,36 @@ int has_sha1_file(const unsigned char *sha1)
  *
  * returns 0 if anything went fine and -1 otherwise
  *
+ * The buffer is always NUL-terminated, not including it in returned size.
+ *
  * NOTE: both buf and size may change, but even when -1 is returned
  * you still have to free() it yourself.
  */
-int read_pipe(int fd, char** return_buf, unsigned long* return_size)
+int read_fd(int fd, char **return_buf, unsigned long *return_size)
 {
-       charbuf = *return_buf;
+       char *buf = *return_buf;
        unsigned long size = *return_size;
        ssize_t iret;
        unsigned long off = 0;
 
+       if (!buf || size <= 1) {
+               size = 1024;
+               buf = xrealloc(buf, size);
+       }
+
        do {
-               iret = xread(fd, buf + off, size - off);
+               iret = xread(fd, buf + off, (size - 1) - off);
                if (iret > 0) {
                        off += iret;
-                       if (off == size) {
-                               size *= 2;
+                       if (off == size - 1) {
+                               size = alloc_nr(size);
                                buf = xrealloc(buf, size);
                        }
                }
        } while (iret > 0);
 
+       buf[off] = '\0';
+
        *return_buf = buf;
        *return_size = off;
 
@@ -2329,7 +2352,7 @@ int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object)
        char *buf = xmalloc(size);
        int ret;
 
-       if (read_pipe(fd, &buf, &size)) {
+       if (read_fd(fd, &buf, &size)) {
                free(buf);
                return -1;
        }