path-list.con commit gitweb: Secure against commit-ish/tree-ish with the same name as path (45bd0c8)
   1#include <stdio.h>
   2#include "cache.h"
   3#include "path-list.h"
   4
   5/* if there is no exact match, point to the index where the entry could be
   6 * inserted */
   7static int get_entry_index(const struct path_list *list, const char *path,
   8                int *exact_match)
   9{
  10        int left = -1, right = list->nr;
  11
  12        while (left + 1 < right) {
  13                int middle = (left + right) / 2;
  14                int compare = strcmp(path, list->items[middle].path);
  15                if (compare < 0)
  16                        right = middle;
  17                else if (compare > 0)
  18                        left = middle;
  19                else {
  20                        *exact_match = 1;
  21                        return middle;
  22                }
  23        }
  24
  25        *exact_match = 0;
  26        return right;
  27}
  28
  29/* returns -1-index if already exists */
  30static int add_entry(struct path_list *list, const char *path)
  31{
  32        int exact_match;
  33        int index = get_entry_index(list, path, &exact_match);
  34
  35        if (exact_match)
  36                return -1 - index;
  37
  38        if (list->nr + 1 >= list->alloc) {
  39                list->alloc += 32;
  40                list->items = xrealloc(list->items, list->alloc
  41                                * sizeof(struct path_list_item));
  42        }
  43        if (index < list->nr)
  44                memmove(list->items + index + 1, list->items + index,
  45                                (list->nr - index)
  46                                * sizeof(struct path_list_item));
  47        list->items[index].path = list->strdup_paths ?
  48                xstrdup(path) : (char *)path;
  49        list->items[index].util = NULL;
  50        list->nr++;
  51
  52        return index;
  53}
  54
  55struct path_list_item *path_list_insert(const char *path, struct path_list *list)
  56{
  57        int index = add_entry(list, path);
  58
  59        if (index < 0)
  60                index = 1 - index;
  61
  62        return list->items + index;
  63}
  64
  65int path_list_has_path(const struct path_list *list, const char *path)
  66{
  67        int exact_match;
  68        get_entry_index(list, path, &exact_match);
  69        return exact_match;
  70}
  71
  72struct path_list_item *path_list_lookup(const char *path, struct path_list *list)
  73{
  74        int exact_match, i = get_entry_index(list, path, &exact_match);
  75        if (!exact_match)
  76                return NULL;
  77        return list->items + i;
  78}
  79
  80void path_list_clear(struct path_list *list, int free_items)
  81{
  82        if (list->items) {
  83                int i;
  84                if (free_items)
  85                        for (i = 0; i < list->nr; i++) {
  86                                if (list->strdup_paths)
  87                                        free(list->items[i].path);
  88                                free(list->items[i].util);
  89                        }
  90                free(list->items);
  91        }
  92        list->items = NULL;
  93        list->nr = list->alloc = 0;
  94}
  95
  96void print_path_list(const char *text, const struct path_list *p)
  97{
  98        int i;
  99        if ( text )
 100                printf("%s\n", text);
 101        for (i = 0; i < p->nr; i++)
 102                printf("%s:%p\n", p->items[i].path, p->items[i].util);
 103}
 104