From 0ef4ecefc73f2813ae60bb787dee5c2cbffc0234 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 6 May 2008 21:33:10 +0000 Subject: 24957: better sanity checking of colour ranges always use termcap for numeric ranges where available --- ChangeLog | 4 ++++ Doc/Zsh/zle.yo | 14 ++++++-------- Src/Zle/zle_refresh.c | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 323466fb4..676aa1f56 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2008-05-06 Peter Stephenson + * 24957: Doc/Zsh/zle.yo, Src/Zle/zle_refresh.c: better sanity + checking of colour ranges, always use termcap for numeric + colours where available. + * 24911 (tweaked): Doc/Zsh/zle.yo: missed this bit, somehow. 2008-05-06 Peter Stephenson diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 95d1d7ae9..b7b4676a7 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -2180,18 +2180,16 @@ or the name of one of the eight most widely-supported colours. Not all terminals support this and, of those that do, not all provide facilities to test the support, hence the user should decide based on the -terminal type. Most terminals with colour support accept the numbers 0 to -7, and may generate additional colours if the tt(bold) attributes is also -present. Most terminals also have a standard range of colours for those -numbers (though the interpretation of the colour can vary); these colours -can be set by one of the names tt(black), tt(red), tt(green), tt(yellow), -tt(blue), tt(magenta), tt(cyan) and tt(white). Abbreviations are -allowed; tt(b) or tt(bl) selects black. +terminal type. Most terminals support the colours tt(black), tt(red), +tt(green), tt(yellow), tt(blue), tt(magenta), tt(cyan) and tt(white), +which can be set by name. Abbreviations are allowed; tt(b) or tt(bl) +selects black. Some terminals may generate additional colours if the +tt(bold) attribute is also present. On recent terminals and on systems with an up-to-date terminal database the number of colours supported may be tested by with the command `tt(echotc Co)'; if this succeeds, it indicates a limit on the number of colours which -will be enforced by the line editor. The number of colours is in case +will be enforced by the line editor. The number of colours is in any case limited to 256 (i.e. the range 0 to 255). Colour is also known as color. diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 6275d2cf3..6127c1248 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -460,10 +460,10 @@ match_highlight(const char *teststr, int *on_var) found = 0; if (strpfx("fg=", teststr) || strpfx("bg=", teststr)) { int is_fg = (teststr[0] == 'f'); - int colour, shft, on; + int colour, shft, on, named, tc; teststr += 3; - if (ialpha(*teststr)) + if ((named = ialpha(*teststr))) colour = match_colour(&teststr); else colour = (int)zstrtol(teststr, (char **)&teststr, 10); @@ -478,9 +478,33 @@ match_highlight(const char *teststr, int *on_var) if (is_fg) { shft = TXT_ATTR_FG_COL_SHIFT; on = TXTFGCOLOUR; + tc = TCFGCOLOUR; } else { shft = TXT_ATTR_BG_COL_SHIFT; on = TXTBGCOLOUR; + tc = TCBGCOLOUR; + } + /* + * Try termcap for numbered characters if posible. + * 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) + continue; /* No. */ + } else { + /* + * We can handle termcap colours and the number + * is in range, so use termcap. + */ + *on_var |= is_fg ? TXT_ATTR_FG_TERMCAP : + TXT_ATTR_BG_TERMCAP; + } } *on_var |= on | (colour << shft); } else { @@ -1137,8 +1161,11 @@ setcolourattribute(int colour, int fg_bg, int tc, int def, /* * 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 (which at the time of writing - * we never are), try to use the termcap sequence. + * to use the termcap sequence, 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 && (colour > 7 || use_termcap)) { /* -- cgit 1.4.1