sha1_file: replace PATH_MAX buffer with strbuf in prepare_packed_git_one()

Instead of using strbuf to create a message string in case a path is
too long for our fixed-size buffer, replace that buffer with a strbuf
and thus get rid of the limitation.

Helped-by: Duy Nguyen <pclouds@gmail.com>
Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
René Scharfe
2014-06-30 12:55:52 -04:00
committed by Junio C Hamano
parent 341e7e8eda
commit 880fb8de67

View File

@ -1177,48 +1177,37 @@ static void report_pack_garbage(struct string_list *list)
static void prepare_packed_git_one(char *objdir, int local) static void prepare_packed_git_one(char *objdir, int local)
{ {
/* Ensure that this buffer is large enough so that we can struct strbuf path = STRBUF_INIT;
append "/pack/" without clobbering the stack even if size_t dirnamelen;
strlen(objdir) were PATH_MAX. */
char path[PATH_MAX + 1 + 4 + 1 + 1];
int len;
DIR *dir; DIR *dir;
struct dirent *de; struct dirent *de;
struct string_list garbage = STRING_LIST_INIT_DUP; struct string_list garbage = STRING_LIST_INIT_DUP;
sprintf(path, "%s/pack", objdir); strbuf_addstr(&path, objdir);
len = strlen(path); strbuf_addstr(&path, "/pack");
dir = opendir(path); dir = opendir(path.buf);
if (!dir) { if (!dir) {
if (errno != ENOENT) if (errno != ENOENT)
error("unable to open object pack directory: %s: %s", error("unable to open object pack directory: %s: %s",
path, strerror(errno)); path.buf, strerror(errno));
strbuf_release(&path);
return; return;
} }
path[len++] = '/'; strbuf_addch(&path, '/');
dirnamelen = path.len;
while ((de = readdir(dir)) != NULL) { while ((de = readdir(dir)) != NULL) {
int namelen = strlen(de->d_name);
struct packed_git *p; struct packed_git *p;
if (len + namelen + 1 > sizeof(path)) {
if (report_garbage) {
struct strbuf sb = STRBUF_INIT;
strbuf_addf(&sb, "%.*s/%s", len - 1, path, de->d_name);
report_garbage("path too long", sb.buf);
strbuf_release(&sb);
}
continue;
}
if (is_dot_or_dotdot(de->d_name)) if (is_dot_or_dotdot(de->d_name))
continue; continue;
strcpy(path + len, de->d_name); strbuf_setlen(&path, dirnamelen);
strbuf_addstr(&path, de->d_name);
if (has_extension(de->d_name, ".idx")) { if (has_extension(de->d_name, ".idx")) {
/* Don't reopen a pack we already have. */ /* Don't reopen a pack we already have. */
for (p = packed_git; p; p = p->next) { for (p = packed_git; p; p = p->next) {
if (!memcmp(path, p->pack_name, len + namelen - 4)) if (!memcmp(path.buf, p->pack_name, path.len - 4))
break; break;
} }
if (p == NULL && if (p == NULL &&
@ -1226,7 +1215,7 @@ static void prepare_packed_git_one(char *objdir, int local)
* See if it really is a valid .idx file with * See if it really is a valid .idx file with
* corresponding .pack file that we can map. * corresponding .pack file that we can map.
*/ */
(p = add_packed_git(path, len + namelen, local)) != NULL) (p = add_packed_git(path.buf, path.len, local)) != NULL)
install_packed_git(p); install_packed_git(p);
} }
@ -1237,13 +1226,14 @@ static void prepare_packed_git_one(char *objdir, int local)
has_extension(de->d_name, ".pack") || has_extension(de->d_name, ".pack") ||
has_extension(de->d_name, ".bitmap") || has_extension(de->d_name, ".bitmap") ||
has_extension(de->d_name, ".keep")) has_extension(de->d_name, ".keep"))
string_list_append(&garbage, path); string_list_append(&garbage, path.buf);
else else
report_garbage("garbage found", path); report_garbage("garbage found", path.buf);
} }
closedir(dir); closedir(dir);
report_pack_garbage(&garbage); report_pack_garbage(&garbage);
string_list_clear(&garbage, 0); string_list_clear(&garbage, 0);
strbuf_release(&path);
} }
static int sort_pack(const void *a_, const void *b_) static int sort_pack(const void *a_, const void *b_)