I need help, I have lost the ability to follow logic and count above five. The follow gives me garbled output almost all of the time. I can not see where I went wrong, can anyone point me in the right direction?
Australia Forum Administrator
#1
Australia Forum Administrator
#2
USA
#3
void write_to_buffer( DESCRIPTOR_DATA *d, const char *txt, ... ) {
int length = 0;
bool inColor = IS_SET(d->telOpts, 15);
char outTemp[MAX_STRING_LENGTH];
char outColor[MAX_STRING_LENGTH];
char colBuf[16];
char *pnt = NULL, *lst = NULL;
int first = 0, jump = 0, oCtop = 0;
int fore = 0, back = 0;
if( d == NULL ) {
bug("Write_to_buffer: NULL descriptor");
return;
}
if( d->outbuf == NULL ) // Should never happen, but create if it is
CREATE(d->outbuf, char, d->outsize);
strcpy(outTemp, "");
{
va_list param;
va_start(param, txt);
vsprintf(outTemp + strlen(outTemp), txt, param);
va_end(param);
}
lst = outTemp;
if( inColor ) { //colorize output
first = 0; jump = 0; oCtop = 0;
while( (pnt = strchr(lst, '&')) != NULL ) {
if( pnt > lst ) {
first = pnt - lst;
fore = 9; back = 9;
if( *(pnt + 1) == '(' ) {
fore = getColor(*(pnt + 2));
if( *(pnt + 3) != ')' )
back = getColor(*(pnt + 3));
else
jump = 4;
if( jump == 0 && *(pnt + 4) == ')' )
jump = 5;
else
jump = 4;
} else {
fore = getColor(*(pnt + 1));
jump = 2;
}
strncpy(outColor + oCtop, lst, first);
oCtop += first;
sprintf(colBuf, "\033[0;3%d;4%dm", fore, back);
strncpy(outColor + oCtop, colBuf, 10);
oCtop += 10;
lst = pnt + jump;
} else {
break;
}
}
if( oCtop == 0 ) {
strcat(outColor, outTemp);
oCtop = strlen(outTemp);
} else {
strcat(outColor, "\033[0m");
oCtop += 4;
}
outColor[oCtop] = '\0';
} else { //strip color codes
first = 0; jump = 0; oCtop = 0;
while( (pnt = strchr(lst, '&')) != NULL ) {
if( pnt > lst ) {
first = pnt - lst;
if( *(pnt + 1) == '(' ) {
if( *(pnt + 3) == ')' )
jump = 4;
else if( *(pnt + 4) == ')' )
jump = 5;
} else {
jump = 2;
}
strncpy(outColor + oCtop, lst, first);
oCtop += first;
lst = pnt + jump;
} else {
break;
}
}
if( oCtop == 0 ) {
strcat(outColor, outTemp);
oCtop = strlen(outTemp);
}
outColor[oCtop] = '\0';
}
length = strlen(outColor);
// Expand the buffer as needed.
// This is not released until close_socket.
while( d->outtop + length >= d->outsize ) {
if( d->outsize > MAXOUTSIZE ) {
bug("Buffer overflow. Closing (%d).", d->uniqueNumber);
clear_outbuf(d);
close_socket(d, TRUE);
return;
}
d->outsize *= 2;
RECREATE(d->outbuf, char, d->outsize);
}
// Copy.
strncpy(d->outbuf + d->outtop, outColor, length);
d->outtop += length;
d->outbuf[d->outtop] = '\0';
return;
}
[\code]
Before I look at your code, the forum code to end a code block is [/code] not [\code].
This is an ideal candidate for gdb you know - rather than puzzling out what the code is doing wrong, run it through gdb and check that, at each point, it is doing what you expect.
For example, what is the point of this?
Now, outTemp has a zero length, right? You just moved an empty string into it. So why do "+ strlen(outTemp)"? That will always add zero. That is not your bug, but stuff like that is confusing.
For example, what is the point of this?
strcpy(outTemp, "");
{
va_list param;
va_start(param, txt);
vsprintf(outTemp + strlen(outTemp), txt, param);
va_end(param);
}
Now, outTemp has a zero length, right? You just moved an empty string into it. So why do "+ strlen(outTemp)"? That will always add zero. That is not your bug, but stuff like that is confusing.
After lots and lots of gdb time, it ended up being expression changes as well as using strncpy vs strcpy. Changes to the above function as follows for those interested. Also, for that comment on vsprintf, Nick, I wrote that so fast I just defaulted to habit, but good eye, thanks.
strcpy(outColor, "");
if( inColor ) { //colorize output
first = 0; jump = 0; oCtop = 0;
while( (pnt = strchr(lst, '&')) != NULL ) {
if( pnt >= lst ) {
first = pnt - lst;
fore = -1; back = -1;
if( *(pnt + 1) == '(' ) {
fore = getColor(*(pnt + 2));
if( *(pnt + 3) != ')' )
back = getColor(*(pnt + 3));
else
jump = 4;
if( jump == 0 && *(pnt + 4) == ')' )
jump = 5;
else
jump = 4;
} else {
fore = getColor(*(pnt + 1));
jump = 2;
}
strncpy(outColor + oCtop, lst, first);
oCtop += first;
snprintf(outColor + oCtop, 3, "\033[0");
oCtop += 3;
if( fore != -1 ) {
snprintf(outColor + oCtop, 3, ";3%d", fore);
oCtop += 3;
}
if( back != -1 ) {
snprintf(outColor + oCtop, 3, ";4%d", back);
oCtop += 3;
}
snprintf(outColor + oCtop, 1, "m");
oCtop += 1;
lst = pnt + jump;
}
}
if( oCtop == 0 ) {
strcpy(outColor, outTemp);
oCtop = strlen(outTemp);
} else if( (length = strlen(lst)) > 0 ) {
strncpy(outColor + oCtop, lst, length);
oCtop += length;
snprintf(outColor + oCtop, 4, "\033[0m");
oCtop += 4;
}
outColor[oCtop] = '\0';
} else { //strip color codes
first = 0; jump = 0; oCtop = 0;
while( (pnt = strchr(lst, '&')) != NULL ) {
if( pnt >= lst ) {
first = pnt - lst;
if( *(pnt + 1) == '(' ) {
if( *(pnt + 3) == ')' )
jump = 4;
else if( *(pnt + 4) == ')' )
jump = 5;
} else {
jump = 2;
}
strncpy(outColor + oCtop, lst, first);
oCtop += first;
lst = pnt + jump;
}
}
if( oCtop == 0 ) {
strcpy(outColor, outTemp);
oCtop = strlen(outTemp);
} else if( (length = strlen(lst)) > 0 ) {
strncpy(outColor + oCtop, lst, length);
oCtop += length;
}
outColor[oCtop] = '\0';
}