Coverage Report

Created: 2026-01-10 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/alias.c
Line
Count
Source
1
#define USE_THE_REPOSITORY_VARIABLE
2
3
#include "git-compat-util.h"
4
#include "alias.h"
5
#include "config.h"
6
#include "gettext.h"
7
#include "strbuf.h"
8
#include "string-list.h"
9
10
struct config_alias_data {
11
  const char *alias;
12
  char *v;
13
  struct string_list *list;
14
};
15
16
static int config_alias_cb(const char *key, const char *value,
17
         const struct config_context *ctx UNUSED, void *d)
18
0
{
19
0
  struct config_alias_data *data = d;
20
0
  const char *p;
21
22
0
  if (!skip_prefix(key, "alias.", &p))
23
0
    return 0;
24
25
0
  if (data->alias) {
26
0
    if (!strcasecmp(p, data->alias)) {
27
0
      FREE_AND_NULL(data->v);
28
0
      return git_config_string(&data->v,
29
0
             key, value);
30
0
    }
31
0
  } else if (data->list) {
32
0
    string_list_append(data->list, p);
33
0
  }
34
35
0
  return 0;
36
0
}
37
38
char *alias_lookup(const char *alias)
39
0
{
40
0
  struct config_alias_data data = { alias, NULL };
41
42
0
  read_early_config(the_repository, config_alias_cb, &data);
43
44
0
  return data.v;
45
0
}
46
47
void list_aliases(struct string_list *list)
48
0
{
49
0
  struct config_alias_data data = { NULL, NULL, list };
50
51
0
  read_early_config(the_repository, config_alias_cb, &data);
52
0
}
53
54
void quote_cmdline(struct strbuf *buf, const char **argv)
55
0
{
56
0
  for (const char **argp = argv; *argp; argp++) {
57
0
    if (argp != argv)
58
0
      strbuf_addch(buf, ' ');
59
0
    strbuf_addch(buf, '"');
60
0
    for (const char *p = *argp; *p; p++) {
61
0
      const char c = *p;
62
63
0
      if (c == '"' || c =='\\')
64
0
        strbuf_addch(buf, '\\');
65
0
      strbuf_addch(buf, c);
66
0
    }
67
0
    strbuf_addch(buf, '"');
68
0
  }
69
0
}
70
71
0
#define SPLIT_CMDLINE_BAD_ENDING 1
72
0
#define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
73
0
#define SPLIT_CMDLINE_ARGC_OVERFLOW 3
74
static const char *split_cmdline_errors[] = {
75
  N_("cmdline ends with \\"),
76
  N_("unclosed quote"),
77
  N_("too many arguments"),
78
};
79
80
int split_cmdline(char *cmdline, const char ***argv)
81
0
{
82
0
  size_t src, dst, count = 0, size = 16;
83
0
  char quoted = 0;
84
85
0
  ALLOC_ARRAY(*argv, size);
86
87
  /* split alias_string */
88
0
  (*argv)[count++] = cmdline;
89
0
  for (src = dst = 0; cmdline[src];) {
90
0
    char c = cmdline[src];
91
0
    if (!quoted && isspace(c)) {
92
0
      cmdline[dst++] = 0;
93
0
      while (cmdline[++src]
94
0
          && isspace(cmdline[src]))
95
0
        ; /* skip */
96
0
      ALLOC_GROW(*argv, count + 1, size);
97
0
      (*argv)[count++] = cmdline + dst;
98
0
    } else if (!quoted && (c == '\'' || c == '"')) {
99
0
      quoted = c;
100
0
      src++;
101
0
    } else if (c == quoted) {
102
0
      quoted = 0;
103
0
      src++;
104
0
    } else {
105
0
      if (c == '\\' && quoted != '\'') {
106
0
        src++;
107
0
        c = cmdline[src];
108
0
        if (!c) {
109
0
          FREE_AND_NULL(*argv);
110
0
          return -SPLIT_CMDLINE_BAD_ENDING;
111
0
        }
112
0
      }
113
0
      cmdline[dst++] = c;
114
0
      src++;
115
0
    }
116
0
  }
117
118
0
  cmdline[dst] = 0;
119
120
0
  if (quoted) {
121
0
    FREE_AND_NULL(*argv);
122
0
    return -SPLIT_CMDLINE_UNCLOSED_QUOTE;
123
0
  }
124
125
0
  if (count >= INT_MAX) {
126
0
    FREE_AND_NULL(*argv);
127
0
    return -SPLIT_CMDLINE_ARGC_OVERFLOW;
128
0
  }
129
130
0
  ALLOC_GROW(*argv, count + 1, size);
131
0
  (*argv)[count] = NULL;
132
133
0
  return count;
134
0
}
135
136
const char *split_cmdline_strerror(int split_cmdline_errno)
137
0
{
138
0
  return split_cmdline_errors[-split_cmdline_errno - 1];
139
0
}