Fix for out-of-bounds write in highlight_param

This commit is contained in:
ridiculousfish 2012-02-29 16:14:03 -08:00
parent 52dc415d0b
commit b17dfff3fd

@ -233,27 +233,21 @@ rgb_color_t highlight_get_color( int highlight, bool is_background )
/** /**
Highligt operators (such as $, ~, %, as well as escaped characters. Highligt operators (such as $, ~, %, as well as escaped characters.
*/ */
static void highlight_param( const wchar_t * buff, static void highlight_param( const wcstring &buffstr, std::vector<int> &colors, int pos, wcstring_list_t *error )
int *color, {
int pos, const wchar_t * const buff = buffstr.c_str();
wcstring_list_t *error )
{
int mode = 0; int mode = 0;
int in_pos, len = wcslen( buff ); size_t in_pos, len = buffstr.size();
int bracket_count=0; int bracket_count=0;
wchar_t c; int normal_status = colors.at(0);
int normal_status = *color;
for( in_pos=0; for( in_pos=0;
in_pos<len; in_pos<len;
in_pos++ ) in_pos++ )
{ {
c = buff[in_pos]; wchar_t c = buffstr.at(in_pos);
switch( mode ) switch( mode )
{ {
/* /*
Mode 0 means unquoted string Mode 0 means unquoted string
*/ */
@ -268,27 +262,27 @@ static void highlight_param( const wchar_t * buff,
{ {
if( in_pos == 1 ) if( in_pos == 1 )
{ {
color[start_pos] = HIGHLIGHT_ESCAPE; colors.at(start_pos) = HIGHLIGHT_ESCAPE;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
} }
} }
else if( buff[in_pos]==L',' ) else if( buff[in_pos]==L',' )
{ {
if( bracket_count ) if( bracket_count )
{ {
color[start_pos] = HIGHLIGHT_ESCAPE; colors.at(start_pos) = HIGHLIGHT_ESCAPE;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
} }
} }
else if( wcschr( L"abefnrtv*?$(){}[]'\"<>^ \\#;|&", buff[in_pos] ) ) else if( wcschr( L"abefnrtv*?$(){}[]'\"<>^ \\#;|&", buff[in_pos] ) )
{ {
color[start_pos]=HIGHLIGHT_ESCAPE; colors.at(start_pos)=HIGHLIGHT_ESCAPE;
color[in_pos+1]=normal_status; colors.at(in_pos+1)=normal_status;
} }
else if( wcschr( L"c", buff[in_pos] ) ) else if( wcschr( L"c", buff[in_pos] ) )
{ {
color[start_pos]=HIGHLIGHT_ESCAPE; colors.at(start_pos)=HIGHLIGHT_ESCAPE;
color[in_pos+2]=normal_status; colors.at(in_pos+2)=normal_status;
} }
else if( wcschr( L"uUxX01234567", buff[in_pos] ) ) else if( wcschr( L"uUxX01234567", buff[in_pos] ) )
{ {
@ -352,13 +346,13 @@ static void highlight_param( const wchar_t * buff,
if( (res <= max_val) ) if( (res <= max_val) )
{ {
color[start_pos] = HIGHLIGHT_ESCAPE; colors.at(start_pos) = HIGHLIGHT_ESCAPE;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
} }
else else
{ {
color[start_pos] = HIGHLIGHT_ERROR; colors.at(start_pos) = HIGHLIGHT_ERROR;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
} }
} }
@ -371,8 +365,8 @@ static void highlight_param( const wchar_t * buff,
{ {
if( in_pos == 0 ) if( in_pos == 0 )
{ {
color[in_pos] = HIGHLIGHT_OPERATOR; colors.at(in_pos) = HIGHLIGHT_OPERATOR;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
} }
break; break;
} }
@ -380,8 +374,8 @@ static void highlight_param( const wchar_t * buff,
case L'$': case L'$':
{ {
wchar_t n = buff[in_pos+1]; wchar_t n = buff[in_pos+1];
color[in_pos] = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR; colors.at(in_pos) = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
break; break;
} }
@ -391,23 +385,23 @@ static void highlight_param( const wchar_t * buff,
case L'(': case L'(':
case L')': case L')':
{ {
color[in_pos] = HIGHLIGHT_OPERATOR; colors.at(in_pos) = HIGHLIGHT_OPERATOR;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
break; break;
} }
case L'{': case L'{':
{ {
color[in_pos] = HIGHLIGHT_OPERATOR; colors.at(in_pos) = HIGHLIGHT_OPERATOR;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
bracket_count++; bracket_count++;
break; break;
} }
case L'}': case L'}':
{ {
color[in_pos] = HIGHLIGHT_OPERATOR; colors.at(in_pos) = HIGHLIGHT_OPERATOR;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
bracket_count--; bracket_count--;
break; break;
} }
@ -416,8 +410,8 @@ static void highlight_param( const wchar_t * buff,
{ {
if( bracket_count ) if( bracket_count )
{ {
color[in_pos] = HIGHLIGHT_OPERATOR; colors.at(in_pos) = HIGHLIGHT_OPERATOR;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
} }
break; break;
@ -425,14 +419,14 @@ static void highlight_param( const wchar_t * buff,
case L'\'': case L'\'':
{ {
color[in_pos] = HIGHLIGHT_QUOTE; colors.at(in_pos) = HIGHLIGHT_QUOTE;
mode = 1; mode = 1;
break; break;
} }
case L'\"': case L'\"':
{ {
color[in_pos] = HIGHLIGHT_QUOTE; colors.at(in_pos) = HIGHLIGHT_QUOTE;
mode = 2; mode = 2;
break; break;
} }
@ -455,8 +449,8 @@ static void highlight_param( const wchar_t * buff,
case '\\': case '\\':
case L'\'': case L'\'':
{ {
color[start_pos] = HIGHLIGHT_ESCAPE; colors.at(start_pos) = HIGHLIGHT_ESCAPE;
color[in_pos+1] = HIGHLIGHT_QUOTE; colors.at(in_pos+1) = HIGHLIGHT_QUOTE;
break; break;
} }
@ -471,7 +465,7 @@ static void highlight_param( const wchar_t * buff,
if( c == L'\'' ) if( c == L'\'' )
{ {
mode = 0; mode = 0;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
} }
break; break;
@ -487,7 +481,7 @@ static void highlight_param( const wchar_t * buff,
case '"': case '"':
{ {
mode = 0; mode = 0;
color[in_pos+1] = normal_status; colors.at(in_pos+1) = normal_status;
break; break;
} }
@ -505,8 +499,8 @@ static void highlight_param( const wchar_t * buff,
case L'$': case L'$':
case '"': case '"':
{ {
color[start_pos] = HIGHLIGHT_ESCAPE; colors.at(start_pos) = HIGHLIGHT_ESCAPE;
color[in_pos+1] = HIGHLIGHT_QUOTE; colors.at(in_pos+1) = HIGHLIGHT_QUOTE;
break; break;
} }
} }
@ -516,8 +510,8 @@ static void highlight_param( const wchar_t * buff,
case '$': case '$':
{ {
wchar_t n = buff[in_pos+1]; wchar_t n = buff[in_pos+1];
color[in_pos] = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR; colors.at(in_pos) = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR;
color[in_pos+1] = HIGHLIGHT_QUOTE; colors.at(in_pos+1) = HIGHLIGHT_QUOTE;
break; break;
} }
@ -914,12 +908,15 @@ static void tokenize( const wchar_t * const buff, std::vector<int> &color, const
} }
} }
highlight_param( param, /* Highlight the parameter. highlight_param wants to write one more color than we have characters (hysterical raisins) so allocate one more in the vector. But don't copy it back. */
&color[tok_get_pos( &tok )], const wcstring param_str = param;
pos-tok_get_pos( &tok ), std::vector<int> subcolors;
error ); subcolors.resize(1 + param_str.size());
int tok_pos = tok_get_pos(&tok);
highlight_param(param_str, subcolors, pos-tok_pos, error);
/* Copy the subcolors into our colors array */
std::copy(subcolors.begin(), subcolors.begin() + param_str.size(), color.begin() + tok_pos);
} }
else else
{ {