From dd6e702ee49c7292c39037843b1b1b2b080f9fda Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Thu, 25 Jun 2020 11:41:21 +0000 Subject: 46068 (tweaked) (was: github #57): region_highlight: Add memo= support. This is useful when multiple plugins add region_highlight entries and subsequently want to remove only their own entries. Without this functionality, recognizing one's region_highlight entries is not trivial because the 'start' and 'end' offsets are modified by editing of $BUFFER and the highlight specification may not be unique or distinctive. The tweaks are as follows: - Change zfree() to zsfree() per workers/46070. - Remove the mem.c hunk, as it changed the signature of only one out of two alternative definitions of zsfree(). (The definition that hunk touched is the one that's not used by default.) --- Src/prompt.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'Src/prompt.c') diff --git a/Src/prompt.c b/Src/prompt.c index b65bfb86b..bc9734720 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -1724,10 +1724,11 @@ match_colour(const char **teststrp, int is_fg, int colour) /* * Match a set of highlights in the given teststr. * Set *on_var to reflect the values found. + * Return a pointer to the first character not consumed. */ /**/ -mod_export void +mod_export const char * match_highlight(const char *teststr, zattr *on_var) { int found = 1; @@ -1745,7 +1746,7 @@ match_highlight(const char *teststr, zattr *on_var) atr = match_colour(&teststr, is_fg, 0); if (*teststr == ',') teststr++; - else if (*teststr) + else if (*teststr && *teststr != ' ') break; found = 1; /* skip out of range colours but keep scanning attributes */ @@ -1758,7 +1759,7 @@ match_highlight(const char *teststr, zattr *on_var) if (*val == ',') val++; - else if (*val) + else if (*val && *val != ' ') break; *on_var |= hl->mask_on; @@ -1769,6 +1770,8 @@ match_highlight(const char *teststr, zattr *on_var) } } } + + return teststr; } /* -- cgit v1.2.3 From 24a82b9dad1cbe109d9fb5753c429fd37b1618cd Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Wed, 9 Sep 2020 11:27:47 +0100 Subject: 47352 (+ extra test cases): fix %K prompt expansion Fixed a regression introduced by workers/30496 (5.0.3) whereby %2K would no longer be the equivalent of %K{2} (%K{green}) in prompt expansion. That was one missing case where the is_fg flag was not passed along to match_colour() after code factorisation. Add tests for the different syntax variants, using echoti as a reference. --- ChangeLog | 5 +++++ Src/prompt.c | 2 +- Test/D01prompt.ztst | 28 ++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) (limited to 'Src/prompt.c') diff --git a/ChangeLog b/ChangeLog index e97ac7eb3..399bc76c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2020-09-09 Stephane Chazelas + + * 47352 (+ extra test cases): Src/prompt.c, Test/D01prompt.ztst: + fix %K prompt expansion (regression introduced in 5.0.3). + 2020-09-05 Doug Kearns * unposted: Completion/Unix/Command/_lp, diff --git a/Src/prompt.c b/Src/prompt.c index bc9734720..997327e18 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -258,7 +258,7 @@ parsecolorchar(zattr arg, int is_fg) bv->fm--; } } else - arg = match_colour(NULL, 1, arg); + arg = match_colour(NULL, is_fg, arg); return arg; } diff --git a/Test/D01prompt.ztst b/Test/D01prompt.ztst index 7ff478e68..3fb27e620 100644 --- a/Test/D01prompt.ztst +++ b/Test/D01prompt.ztst @@ -229,3 +229,31 @@ Ffoo=${(%):-'%F{foo}'} # Unrecognised [[ $f == $Fdefault && $Fdefault == $Freset && $Freset == $Ffoo ]] 0:Regression test for workers/44029 + + if + zmodload zsh/terminfo >& /dev/null && + (( terminfo[colors] >= 8 )) + then + F1=$(echoti setaf 2) + F2=${(%):-%2F} + F3=${(%):-%F{2}} + F4=${(%):-%F{green}} + [[ -n $F1 && $F1 = $F2 && $F2 = $F3 && $F3 = $F4 ]] + else + ZTST_skip='Missing terminfo module or non-colour terminal' + fi +0:Equivalence of terminal colour settings (foreground colour) + + if + zmodload zsh/terminfo >& /dev/null && + (( terminfo[colors] >= 8 )) + then + K1=$(echoti setab 2) + K2=${(%):-%2K} + K3=${(%):-%K{2}} + K4=${(%):-%K{green}} + [[ -n $K1 && $K1 = $K2 && $K2 = $K3 && $K3 = $K4 ]] + else + ZTST_skip='Missing terminfo module or non-colour terminal' + fi +0:Equivalence of terminal colour settings (background colour) -- cgit v1.2.3 From 0721060f3616deac84f82c4a97d75987e276fe0a Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 2 Apr 2021 22:41:07 +0200 Subject: 47510: drop code that avoided termcap for named colours The inconsistency caused test failures where TERM is e.g. rxvt-unicode. This also makes a couple of bits available in zattr by removing flags indicating whether to use termcap which is not an attribute as such. --- ChangeLog | 3 +++ Src/prompt.c | 47 +++++++++++------------------------------------ Src/zsh.h | 10 ++-------- 3 files changed, 16 insertions(+), 44 deletions(-) (limited to 'Src/prompt.c') diff --git a/ChangeLog b/ChangeLog index 8c97f651c..03ea15ad4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2021-04-02 Oliver Kiddle + * 47510: Src/prompt.c, Src/zsh.h: drop code that avoided + termcap for named colours + * 48356: Doc/Zsh/compwid.yo: clarify (the intended) behaviour for the two anchor forms of matching control diff --git a/Src/prompt.c b/Src/prompt.c index 997327e18..6943eabc3 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -1696,28 +1696,11 @@ match_colour(const char **teststrp, int is_fg, int colour) return TXT_ERROR; } } - /* - * Try termcap for numbered characters if possible. - * Don't for named characters, since our best bet - * of getting the names right is with ANSI sequences. - */ - if (!named && tccan(tc)) { - if (tccolours >= 0 && colour >= tccolours) { - /* - * Out of range of termcap colours. - * Can we assume ANSI colours work? - */ - if (colour > 7) - return TXT_ERROR; /* No. */ - } else { - /* - * We can handle termcap colours and the number - * is in range, so use termcap. - */ - on |= is_fg ? TXT_ATTR_FG_TERMCAP : - TXT_ATTR_BG_TERMCAP; - } - } + + /* Out of range of termcap colours and basic ANSI set. */ + if (tccan(tc) && colour > 7 && colour >= tccolours) + return TXT_ERROR; + return on | (zattr)colour << shft; } @@ -1781,7 +1764,7 @@ match_highlight(const char *teststr, zattr *on_var) */ static int -output_colour(int colour, int fg_bg, int use_tc, int truecol, char *buf) +output_colour(int colour, int fg_bg, int truecol, char *buf) { int atrlen = 3, len; char *ptr = buf; @@ -1799,7 +1782,7 @@ output_colour(int colour, int fg_bg, int use_tc, int truecol, char *buf) * used instead of termcap even for colour > 7. Here this just emits the * color number, so it works fine for both zle_highlight and tercap cases */ - } else if (use_tc || colour > 7) { + } else if (colour > 7) { char digbuf[DIGBUFSIZE]; sprintf(digbuf, "%d", colour); len = strlen(digbuf); @@ -1836,7 +1819,6 @@ output_highlight(zattr atr, char *buf) if (atr & TXTFGCOLOUR) { len = output_colour(txtchangeget(atr, TXT_ATTR_FG_COL), COL_SEQ_FG, - (atr & TXT_ATTR_FG_TERMCAP), (atr & TXT_ATTR_FG_24BIT), ptr); atrlen += len; @@ -1853,7 +1835,6 @@ output_highlight(zattr atr, char *buf) } len = output_colour(txtchangeget(atr, TXT_ATTR_BG_COL), COL_SEQ_BG, - (atr & TXT_ATTR_BG_TERMCAP), (atr & TXT_ATTR_BG_24BIT), ptr); atrlen += len; @@ -2018,7 +1999,6 @@ free_colour_buffer(void) * fg_bg indicates if we're changing the foreground or background. * tc indicates the termcap code to use, if appropriate. * def indicates if we're resetting the default colour. - * use_termcap indicates if we should use termcap to output colours. * flags is either 0 or TSC_PROMPT. */ @@ -2028,7 +2008,7 @@ set_colour_attribute(zattr atr, int fg_bg, int flags) { char *ptr; int do_free, is_prompt = (flags & TSC_PROMPT) ? 1 : 0; - int colour, tc, def, use_termcap, use_truecolor; + int colour, tc, def, use_truecolor; int is_default_zle_highlight = 1; if (fg_bg == COL_SEQ_FG) { @@ -2036,13 +2016,11 @@ set_colour_attribute(zattr atr, int fg_bg, int flags) tc = TCFGCOLOUR; def = txtchangeisset(atr, TXTNOFGCOLOUR); use_truecolor = txtchangeisset(atr, TXT_ATTR_FG_24BIT); - use_termcap = txtchangeisset(atr, TXT_ATTR_FG_TERMCAP); } else { colour = txtchangeget(atr, TXT_ATTR_BG_COL); tc = TCBGCOLOUR; def = txtchangeisset(atr, TXTNOBGCOLOUR); use_truecolor = txtchangeisset(atr, TXT_ATTR_BG_24BIT); - use_termcap = txtchangeisset(atr, TXT_ATTR_BG_TERMCAP); } /* Test if current zle_highlight settings are customized, or @@ -2057,17 +2035,14 @@ set_colour_attribute(zattr atr, int fg_bg, int flags) } /* - * If we're not restoring the default, and either have a - * colour value that is too large for ANSI, or have been told - * to use the termcap sequence, try to use the termcap sequence. - * True color is not covered by termcap. + * If we're not restoring the default or applying true color, + * try to use the termcap sequence. * * We have already sanitised the values we allow from the * highlighting variables, so much of this shouldn't be * necessary at this point, but we might as well be safe. */ - if (!def && !use_truecolor && - (is_default_zle_highlight && (colour > 7 || use_termcap))) + if (!def && !use_truecolor && is_default_zle_highlight) { /* * We can if it's available, and either we couldn't get diff --git a/Src/zsh.h b/Src/zsh.h index 6cf1b4186..a26b2d05b 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2726,11 +2726,6 @@ struct ttyinfo { /* Bits to shift the background colour */ #define TXT_ATTR_BG_COL_SHIFT (40) -/* Flag to use termcap AF sequence to set colour, if available */ -#define TXT_ATTR_FG_TERMCAP 0x1000 -/* Flag to use termcap AB sequence to set colour, if available */ -#define TXT_ATTR_BG_TERMCAP 0x2000 - /* Flag to indicate that foreground is a 24-bit colour */ #define TXT_ATTR_FG_24BIT 0x4000 /* Flag to indicate that background is a 24-bit colour */ @@ -2739,16 +2734,15 @@ struct ttyinfo { /* Things to turn on, including values for the colour elements */ #define TXT_ATTR_ON_VALUES_MASK \ (TXT_ATTR_ON_MASK|TXT_ATTR_FG_COL_MASK|TXT_ATTR_BG_COL_MASK|\ - TXT_ATTR_FG_TERMCAP|TXT_ATTR_BG_TERMCAP|\ TXT_ATTR_FG_24BIT|TXT_ATTR_BG_24BIT) /* Mask out everything to do with setting a foreground colour */ #define TXT_ATTR_FG_ON_MASK \ - (TXTFGCOLOUR|TXT_ATTR_FG_COL_MASK|TXT_ATTR_FG_TERMCAP|TXT_ATTR_FG_24BIT) + (TXTFGCOLOUR|TXT_ATTR_FG_COL_MASK|TXT_ATTR_FG_24BIT) /* Mask out everything to do with setting a background colour */ #define TXT_ATTR_BG_ON_MASK \ - (TXTBGCOLOUR|TXT_ATTR_BG_COL_MASK|TXT_ATTR_BG_TERMCAP|TXT_ATTR_BG_24BIT) + (TXTBGCOLOUR|TXT_ATTR_BG_COL_MASK|TXT_ATTR_BG_24BIT) /* Mask out everything to do with activating colours */ #define TXT_ATTR_COLOUR_ON_MASK \ -- cgit v1.2.3 From 91b7baf25929a20ee776100f406021a422d56e98 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 13 Dec 2021 21:06:57 +0100 Subject: 49646: allow colors in WATCHFMT with %F/%K --- ChangeLog | 3 +++ Doc/Zsh/mod_watch.yo | 6 ++++++ Src/Modules/watch.c | 35 +++++++++++++++++++++++++++++++++++ Src/prompt.c | 9 +++++---- 4 files changed, 49 insertions(+), 4 deletions(-) (limited to 'Src/prompt.c') diff --git a/ChangeLog b/ChangeLog index cb5d4564e..2fd7926ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2021-12-13 Oliver Kiddle + * 49646: Doc/Zsh/mod_watch.yo, Src/Modules/watch.c, Src/prompt.c: + allow colors in WATCHFMT with %F/%K + * 49645: Completion/Unix/Type/_path_commands: when completing for the path_dirs option, add a / suffix and follow symlinks diff --git a/Doc/Zsh/mod_watch.yo b/Doc/Zsh/mod_watch.yo index 4eea89e23..d97a41d13 100644 --- a/Doc/Zsh/mod_watch.yo +++ b/Doc/Zsh/mod_watch.yo @@ -65,6 +65,12 @@ The `tt(%m)' and `tt(%M)' escapes will work only if there is a host name field in the utmp on your machine. Otherwise they are treated as ordinary strings. ) +item(tt(%F{)var(color)tt(}) LPAR()tt(%f)RPAR())( +Start (stop) using a different foreground color. +) +item(tt(%K{)var(color)tt(}) LPAR()tt(%k)RPAR())( +Start (stop) using a different background color. +) item(tt(%S) LPAR()tt(%s)RPAR())( Start (stop) standout mode. ) diff --git a/Src/Modules/watch.c b/Src/Modules/watch.c index 95d591a67..d45c3cf3d 100644 --- a/Src/Modules/watch.c +++ b/Src/Modules/watch.c @@ -246,6 +246,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) struct tm *tm; char *fm2; int len; + zattr atr; # ifdef WATCH_UTMP_UT_HOST char *p; int i; @@ -347,6 +348,40 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) case '%': putchar('%'); break; + case 'F': + if (*fmt == '{') { + fmt++; + atr = match_colour((const char**)&fmt, 1, 0); + if (*fmt == '}') + fmt++; + if (!(atr & (TXT_ERROR | TXTNOFGCOLOUR))) { + txtunset(TXT_ATTR_FG_COL_MASK); + txtset(atr & TXT_ATTR_FG_ON_MASK); + set_colour_attribute(atr, COL_SEQ_FG, TSC_RAW); + } + } + break; + case 'f': + txtunset(TXT_ATTR_FG_ON_MASK); + set_colour_attribute(TXTNOFGCOLOUR, COL_SEQ_FG, TSC_RAW); + break; + case 'K': + if (*fmt == '{') { + fmt++; + atr = match_colour((const char**)&fmt, 0, 0); + if (*fmt == '}') + fmt++; + if (!(atr & (TXT_ERROR | TXTNOBGCOLOUR))) { + txtunset(TXT_ATTR_BG_COL_MASK); + txtset(atr & TXT_ATTR_BG_ON_MASK); + set_colour_attribute(atr, COL_SEQ_BG, TSC_RAW); + } + } + break; + case 'k': + txtunset(TXT_ATTR_BG_ON_MASK); + set_colour_attribute(TXTNOBGCOLOUR, COL_SEQ_BG, TSC_RAW); + break; case 'S': txtset(TXTSTANDOUT); tsetcap(TCSTANDOUTBEG, TSC_RAW); diff --git a/Src/prompt.c b/Src/prompt.c index 6943eabc3..d6b378539 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -1045,9 +1045,9 @@ tsetcap(int cap, int flags) if (txtisset(TXTUNDERLINE)) tsetcap(TCUNDERLINEBEG, flags); if (txtisset(TXTFGCOLOUR)) - set_colour_attribute(txtattrmask, COL_SEQ_FG, TSC_PROMPT); + set_colour_attribute(txtattrmask, COL_SEQ_FG, flags); if (txtisset(TXTBGCOLOUR)) - set_colour_attribute(txtattrmask, COL_SEQ_BG, TSC_PROMPT); + set_colour_attribute(txtattrmask, COL_SEQ_BG, flags); } } } @@ -2062,7 +2062,8 @@ set_colour_attribute(zattr atr, int fg_bg, int flags) *bv->bp++ = Outpar; } } else { - tputs(tgoto(tcstr[tc], colour, colour), 1, putshout); + tputs(tgoto(tcstr[tc], colour, colour), 1, + (flags & TSC_RAW) ? putraw : putshout); } /* That worked. */ return; @@ -2121,7 +2122,7 @@ set_colour_attribute(zattr atr, int fg_bg, int flags) *bv->bp++ = Outpar; } } else - tputs(colseq_buf, 1, putshout); + tputs(colseq_buf, 1, (flags & TSC_RAW) ? putraw : putshout); if (do_free) free_colour_buffer(); -- cgit v1.2.3 From c3ea1e5d52eff8b7b172fa8c1ccc3462b43b2790 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 15 Dec 2021 01:56:40 +0100 Subject: security/41: Don't perform PROMPT_SUBST evaluation on %F/%K arguments Mitigates CVE-2021-45444 (cherry picked from commit c187154f47697cdbf822c2f9d714d570ed4a0fd1) --- ChangeLog | 5 +++++ Src/prompt.c | 10 ++++++++++ 2 files changed, 15 insertions(+) (limited to 'Src/prompt.c') diff --git a/ChangeLog b/ChangeLog index 94e15474b..55030d37f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2022-02-12 dana + + * Oliver Kiddle: security/41: Src/prompt.c: Prevent recursive + PROMPT_SUBST + 2022-02-04 Jun-ichi Takimoto * 49730: Completion/Unix/Command/_csplit, diff --git a/Src/prompt.c b/Src/prompt.c index d6b378539..738c7fc7a 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -244,6 +244,12 @@ parsecolorchar(zattr arg, int is_fg) bv->fm += 2; /* skip over F{ */ if ((ep = strchr(bv->fm, '}'))) { char oc = *ep, *col, *coll; + int ops = opts[PROMPTSUBST], opb = opts[PROMPTBANG]; + int opp = opts[PROMPTPERCENT]; + + opts[PROMPTPERCENT] = 1; + opts[PROMPTSUBST] = opts[PROMPTBANG] = 0; + *ep = '\0'; /* expand the contents of the argument so you can use * %v for example */ @@ -252,6 +258,10 @@ parsecolorchar(zattr arg, int is_fg) arg = match_colour((const char **)&coll, is_fg, 0); free(col); bv->fm = ep; + + opts[PROMPTSUBST] = ops; + opts[PROMPTBANG] = opb; + opts[PROMPTPERCENT] = opp; } else { arg = match_colour((const char **)&bv->fm, is_fg, 0); if (*bv->fm != '}') -- cgit v1.2.3