Skip to content

Commit 10c497a

Browse files
peffgitster
authored andcommitted
read_packed_refs: use a strbuf for reading lines
Current code uses a fixed PATH_MAX-sized buffer for reading packed-refs lines. This is a reasonable guess, in the sense that git generally cannot work with refs larger than PATH_MAX. However, there are a few cases where it is not great: 1. Some systems may have a low value of PATH_MAX, but can actually handle larger paths in practice. Fixing this code path probably isn't enough to make them work completely with long refs, but it is a step in the right direction. 2. We use fgets, which will happily give us half a line on the first read, and then the rest of the line on the second. This is probably OK in practice, because our refline parser is careful enough to look for the trailing newline on the first line. The second line may look like a peeled line to us, but since "^" is illegal in refnames, it is not likely to come up. Still, it does not hurt to be more careful. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7fa1365 commit 10c497a

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

refs.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,16 +1031,16 @@ static const char *parse_ref_line(char *line, unsigned char *sha1)
10311031
static void read_packed_refs(FILE *f, struct ref_dir *dir)
10321032
{
10331033
struct ref_entry *last = NULL;
1034-
char refline[PATH_MAX];
1034+
struct strbuf line = STRBUF_INIT;
10351035
enum { PEELED_NONE, PEELED_TAGS, PEELED_FULLY } peeled = PEELED_NONE;
10361036

1037-
while (fgets(refline, sizeof(refline), f)) {
1037+
while (strbuf_getwholeline(&line, f, '\n') != EOF) {
10381038
unsigned char sha1[20];
10391039
const char *refname;
10401040
static const char header[] = "# pack-refs with:";
10411041

1042-
if (!strncmp(refline, header, sizeof(header)-1)) {
1043-
const char *traits = refline + sizeof(header) - 1;
1042+
if (!strncmp(line.buf, header, sizeof(header)-1)) {
1043+
const char *traits = line.buf + sizeof(header) - 1;
10441044
if (strstr(traits, " fully-peeled "))
10451045
peeled = PEELED_FULLY;
10461046
else if (strstr(traits, " peeled "))
@@ -1049,7 +1049,7 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
10491049
continue;
10501050
}
10511051

1052-
refname = parse_ref_line(refline, sha1);
1052+
refname = parse_ref_line(line.buf, sha1);
10531053
if (refname) {
10541054
last = create_ref_entry(refname, sha1, REF_ISPACKED, 1);
10551055
if (peeled == PEELED_FULLY ||
@@ -1059,10 +1059,10 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
10591059
continue;
10601060
}
10611061
if (last &&
1062-
refline[0] == '^' &&
1063-
strlen(refline) == PEELED_LINE_LENGTH &&
1064-
refline[PEELED_LINE_LENGTH - 1] == '\n' &&
1065-
!get_sha1_hex(refline + 1, sha1)) {
1062+
line.buf[0] == '^' &&
1063+
line.len == PEELED_LINE_LENGTH &&
1064+
line.buf[PEELED_LINE_LENGTH - 1] == '\n' &&
1065+
!get_sha1_hex(line.buf + 1, sha1)) {
10661066
hashcpy(last->u.value.peeled, sha1);
10671067
/*
10681068
* Regardless of what the file header said,
@@ -1072,6 +1072,8 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
10721072
last->flag |= REF_KNOWS_PEELED;
10731073
}
10741074
}
1075+
1076+
strbuf_release(&line);
10751077
}
10761078

10771079
/*

0 commit comments

Comments
 (0)