Skip to content

Commit db64eb6

Browse files
artagnongitster
authored andcommitted
for-each-ref: avoid color leakage
To make sure that an invocation like the following doesn't leak color, $ git for-each-ref --format='%(subject)%(color:green)' auto-reset at the end of the format string when the last color token seen in the format string isn't a color-reset. Signed-off-by: Ramkumar Ramachandra <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fddb74c commit db64eb6

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

builtin/for-each-ref.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ static struct {
9393
static const char **used_atom;
9494
static cmp_type *used_atom_type;
9595
static int used_atom_cnt, sort_atom_limit, need_tagged, need_symref;
96+
static int need_color_reset_at_eol;
9697

9798
/*
9899
* Used to parse format string and sort specifiers
@@ -179,13 +180,21 @@ static const char *find_next(const char *cp)
179180
static int verify_format(const char *format)
180181
{
181182
const char *cp, *sp;
183+
static const char color_reset[] = "color:reset";
184+
185+
need_color_reset_at_eol = 0;
182186
for (cp = format; *cp && (sp = find_next(cp)); ) {
183187
const char *ep = strchr(sp, ')');
188+
int at;
189+
184190
if (!ep)
185191
return error("malformed format string %s", sp);
186192
/* sp points at "%(" and ep points at the closing ")" */
187-
parse_atom(sp + 2, ep);
193+
at = parse_atom(sp + 2, ep);
188194
cp = ep + 1;
195+
196+
if (!memcmp(used_atom[at], "color:", 6))
197+
need_color_reset_at_eol = !!strcmp(used_atom[at], color_reset);
189198
}
190199
return 0;
191200
}
@@ -914,11 +923,9 @@ static void sort_refs(struct ref_sort *sort, struct refinfo **refs, int num_refs
914923
qsort(refs, num_refs, sizeof(struct refinfo *), compare_refs);
915924
}
916925

917-
static void print_value(struct refinfo *ref, int atom, int quote_style)
926+
static void print_value(struct atom_value *v, int quote_style)
918927
{
919-
struct atom_value *v;
920928
struct strbuf sb = STRBUF_INIT;
921-
get_value(ref, atom, &v);
922929
switch (quote_style) {
923930
case QUOTE_NONE:
924931
fputs(v->s, stdout);
@@ -985,15 +992,26 @@ static void show_ref(struct refinfo *info, const char *format, int quote_style)
985992
const char *cp, *sp, *ep;
986993

987994
for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) {
995+
struct atom_value *atomv;
996+
988997
ep = strchr(sp, ')');
989998
if (cp < sp)
990999
emit(cp, sp);
991-
print_value(info, parse_atom(sp + 2, ep), quote_style);
1000+
get_value(info, parse_atom(sp + 2, ep), &atomv);
1001+
print_value(atomv, quote_style);
9921002
}
9931003
if (*cp) {
9941004
sp = cp + strlen(cp);
9951005
emit(cp, sp);
9961006
}
1007+
if (need_color_reset_at_eol) {
1008+
struct atom_value resetv;
1009+
char color[COLOR_MAXLEN] = "";
1010+
1011+
color_parse("reset", "--format", color);
1012+
resetv.s = color;
1013+
print_value(&resetv, quote_style);
1014+
}
9971015
putchar('\n');
9981016
}
9991017

t/t6300-for-each-ref.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ $(git rev-parse --short refs/tags/two) $(get_color green)two$(get_color reset)
356356
EOF
357357

358358
test_expect_success 'Check %(color:...) ' '
359-
git for-each-ref --format="%(objectname:short) %(color:green)%(refname:short)%(color:reset)" >actual &&
359+
git for-each-ref --format="%(objectname:short) %(color:green)%(refname:short)" >actual &&
360360
test_cmp expected actual
361361
'
362362

0 commit comments

Comments
 (0)