ref-filter.c: find disjoint pattern prefixes
[gitweb.git] / dir.c
diff --git a/dir.c b/dir.c
index 2ccd4db66440ac3b030049571a0cb0a560dfcb3d..ba4a51c296efcad9861ebfb4b318fbd5cb3025a4 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -2738,54 +2738,49 @@ static int read_one_dir(struct untracked_cache_dir **untracked_,
                        struct read_data *rd)
 {
        struct untracked_cache_dir ud, *untracked;
-       const unsigned char *next, *data = rd->data, *end = rd->end;
+       const unsigned char *data = rd->data, *end = rd->end;
+       const unsigned char *eos;
        unsigned int value;
-       int i, len;
+       int i;
 
        memset(&ud, 0, sizeof(ud));
 
-       next = data;
-       value = decode_varint(&next);
-       if (next > end)
+       value = decode_varint(&data);
+       if (data > end)
                return -1;
        ud.recurse         = 1;
        ud.untracked_alloc = value;
        ud.untracked_nr    = value;
        if (ud.untracked_nr)
                ALLOC_ARRAY(ud.untracked, ud.untracked_nr);
-       data = next;
 
-       next = data;
-       ud.dirs_alloc = ud.dirs_nr = decode_varint(&next);
-       if (next > end)
+       ud.dirs_alloc = ud.dirs_nr = decode_varint(&data);
+       if (data > end)
                return -1;
        ALLOC_ARRAY(ud.dirs, ud.dirs_nr);
-       data = next;
 
-       len = strlen((const char *)data);
-       next = data + len + 1;
-       if (next > rd->end)
+       eos = memchr(data, '\0', end - data);
+       if (!eos || eos == end)
                return -1;
-       *untracked_ = untracked = xmalloc(st_add3(sizeof(*untracked), len, 1));
+
+       *untracked_ = untracked = xmalloc(st_add3(sizeof(*untracked), eos - data, 1));
        memcpy(untracked, &ud, sizeof(ud));
-       memcpy(untracked->name, data, len + 1);
-       data = next;
+       memcpy(untracked->name, data, eos - data + 1);
+       data = eos + 1;
 
        for (i = 0; i < untracked->untracked_nr; i++) {
-               len = strlen((const char *)data);
-               next = data + len + 1;
-               if (next > rd->end)
+               eos = memchr(data, '\0', end - data);
+               if (!eos || eos == end)
                        return -1;
-               untracked->untracked[i] = xstrdup((const char*)data);
-               data = next;
+               untracked->untracked[i] = xmemdupz(data, eos - data);
+               data = eos + 1;
        }
 
        rd->ucd[rd->index++] = untracked;
        rd->data = data;
 
        for (i = 0; i < untracked->dirs_nr; i++) {
-               len = read_one_dir(untracked->dirs + i, rd);
-               if (len < 0)
+               if (read_one_dir(untracked->dirs + i, rd) < 0)
                        return -1;
        }
        return 0;