read_packed_refs(): only check for a header at the top of the file
authorMichael Haggerty <mhagger@alum.mit.edu>
Wed, 13 Sep 2017 17:16:00 +0000 (19:16 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 14 Sep 2017 06:19:07 +0000 (15:19 +0900)
This tightens up the parsing a bit; previously, stray header-looking
lines would have been processed.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
refs/packed-backend.c
index 154abbd83a5d9e0d54cef8b1f9e7479da0c6d456..141f02b9c8933c0908f4e35ea141c3b32b39ce18 100644 (file)
@@ -255,11 +255,34 @@ static struct packed_ref_cache *read_packed_refs(struct packed_ref_store *refs)
        pos = buf;
        eof = buf + size;
 
        pos = buf;
        eof = buf + size;
 
+       /* If the file has a header line, process it: */
+       if (pos < eof && *pos == '#') {
+               const char *traits;
+
+               eol = memchr(pos, '\n', eof - pos);
+               if (!eol)
+                       die_unterminated_line(refs->path, pos, eof - pos);
+
+               strbuf_add(&line, pos, eol + 1 - pos);
+
+               if (!skip_prefix(line.buf, "# pack-refs with:", &traits))
+                       die_invalid_line(refs->path, pos, eof - pos);
+
+               if (strstr(traits, " fully-peeled "))
+                       peeled = PEELED_FULLY;
+               else if (strstr(traits, " peeled "))
+                       peeled = PEELED_TAGS;
+               /* perhaps other traits later as well */
+
+               /* The "+ 1" is for the LF character. */
+               pos = eol + 1;
+               strbuf_reset(&line);
+       }
+
        dir = get_ref_dir(packed_refs->cache->root);
        while (pos < eof) {
                struct object_id oid;
                const char *refname;
        dir = get_ref_dir(packed_refs->cache->root);
        while (pos < eof) {
                struct object_id oid;
                const char *refname;
-               const char *traits;
 
                eol = memchr(pos, '\n', eof - pos);
                if (!eol)
 
                eol = memchr(pos, '\n', eof - pos);
                if (!eol)
@@ -267,15 +290,6 @@ static struct packed_ref_cache *read_packed_refs(struct packed_ref_store *refs)
 
                strbuf_add(&line, pos, eol + 1 - pos);
 
 
                strbuf_add(&line, pos, eol + 1 - pos);
 
-               if (skip_prefix(line.buf, "# pack-refs with:", &traits)) {
-                       if (strstr(traits, " fully-peeled "))
-                               peeled = PEELED_FULLY;
-                       else if (strstr(traits, " peeled "))
-                               peeled = PEELED_TAGS;
-                       /* perhaps other traits later as well */
-                       goto next_line;
-               }
-
                refname = parse_ref_line(&line, &oid);
                if (refname) {
                        int flag = REF_ISPACKED;
                refname = parse_ref_line(&line, &oid);
                if (refname) {
                        int flag = REF_ISPACKED;
@@ -307,7 +321,6 @@ static struct packed_ref_cache *read_packed_refs(struct packed_ref_store *refs)
                        die_invalid_line(refs->path, line.buf, line.len);
                }
 
                        die_invalid_line(refs->path, line.buf, line.len);
                }
 
-       next_line:
                /* The "+ 1" is for the LF character. */
                pos = eol + 1;
                strbuf_reset(&line);
                /* The "+ 1" is for the LF character. */
                pos = eol + 1;
                strbuf_reset(&line);