26
{ "error", GIT_COLOR_BOLD_RED },
27
};
28
29
-static int allow_control_characters;
29
+static enum {
30
+ ALLOW_NO_CONTROL_CHARACTERS = 0,
31
+ ALLOW_ANSI_COLOR_SEQUENCES = 1<<0,
32
+ ALLOW_DEFAULT_ANSI_SEQUENCES = ALLOW_ANSI_COLOR_SEQUENCES,
33
+ ALLOW_ALL_CONTROL_CHARACTERS = 1<<1,
34
+} allow_control_characters = ALLOW_ANSI_COLOR_SEQUENCES;
35
36
/* Returns a color setting (GIT_COLOR_NEVER, etc). */
37
static enum git_colorbool use_sideband_colors(void)
46
if (use_sideband_colors_cached != GIT_COLOR_UNKNOWN)
47
return use_sideband_colors_cached;
48
44
- repo_config_get_bool(the_repository, "sideband.allowcontrolcharacters",
45
- &allow_control_characters);
49
+ switch (repo_config_get_maybe_bool(the_repository, "sideband.allowcontrolcharacters", &i)) {
50
+ case 0: /* Boolean value */
51
+ allow_control_characters = i ? ALLOW_ALL_CONTROL_CHARACTERS :
52
+ ALLOW_NO_CONTROL_CHARACTERS;
53
+ break;
54
+ case -1: /* non-Boolean value */
55
+ if (repo_config_get_string_tmp(the_repository, "sideband.allowcontrolcharacters",
56
+ &value))
57
+ ; /* huh? `get_maybe_bool()` returned -1 */
58
+ else if (!strcmp(value, "default"))
59
+ allow_control_characters = ALLOW_DEFAULT_ANSI_SEQUENCES;
60
+ else if (!strcmp(value, "color"))
61
+ allow_control_characters = ALLOW_ANSI_COLOR_SEQUENCES;
62
+ else
63
+ warning(_("unrecognized value for `sideband."
64
+ "allowControlCharacters`: '%s'"), value);
65
+ break;
66
+ default:
67
+ break; /* not configured */
68
+ }
69
70
if (!repo_config_get_string_tmp(the_repository, key, &value))
71
use_sideband_colors_cached = git_config_colorbool(key, value);
94
list_config_item(list, prefix, keywords[i].keyword);
95
}
96
97
+static int handle_ansi_color_sequence(struct strbuf *dest, const char *src, int n)
98
+{
99
+ int i;
100
+
101
+ /*
102
+ * Valid ANSI color sequences are of the form
103
+ *
104
+ * ESC [ [<n> [; <n>]*] m
105
+ *
106
+ * These are part of the Select Graphic Rendition sequences which
107
+ * contain more than just color sequences, for more details see
108
+ * https://en.wikipedia.org/wiki/ANSI_escape_code#SGR.
109
+ */
110
+
111
+ if (allow_control_characters != ALLOW_ANSI_COLOR_SEQUENCES ||
112
+ n < 3 || src[0] != '\x1b' || src[1] != '[')
113
+ return 0;
114
+
115
+ for (i = 2; i < n; i++) {
116
+ if (src[i] == 'm') {
117
+ strbuf_add(dest, src, i + 1);
118
+ return i;
119
+ }
120
+ if (!isdigit(src[i]) && src[i] != ';')
121
+ break;
122
+ }
123
+
124
+ return 0;
125
+}
126
+
127
static void strbuf_add_sanitized(struct strbuf *dest, const char *src, int n)
128
{
76
- if (allow_control_characters) {
129
+ int i;
130
+
131
+ if (allow_control_characters == ALLOW_ALL_CONTROL_CHARACTERS) {
132
strbuf_add(dest, src, n);
133
return;
134
}
137
for (; n && *src; src++, n--) {
138
if (!iscntrl(*src) || *src == '\t' || *src == '\n') {
139
strbuf_addch(dest, *src);
140
+ } else if ((i = handle_ansi_color_sequence(dest, src, n))) {
141
+ src += i;
142
+ n -= i;
143
} else {
144
strbuf_addch(dest, '^');
145
strbuf_addch(dest, *src == 0x7f ? '?' : 0x40 + *src);