From ec310a3ab41586a768d435baa1c3be43095e26d0 Mon Sep 17 00:00:00 2001 From: rswindell <> Date: Sat, 21 Jan 2006 01:31:15 +0000 Subject: [PATCH] Use xp_printf module for Baja/PCMS printf/sprintf/fprintf functions: * eliminates segfaults/AVs on incorrect usage * auto-converts arguments to correct format type * eliminates portability problems with non-x86 platforms Hurrah for Deuce! --- src/sbbs3/execmisc.cpp | 94 +++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 56 deletions(-) diff --git a/src/sbbs3/execmisc.cpp b/src/sbbs3/execmisc.cpp index c3dc320a93..792cd7e989 100644 --- a/src/sbbs3/execmisc.cpp +++ b/src/sbbs3/execmisc.cpp @@ -8,7 +8,7 @@ * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -37,6 +37,32 @@ #include "sbbs.h" #include "cmdshell.h" +#include "xpprintf.h" + +static char* format_string(sbbs_t* sbbs, csi_t* csi) +{ + char* fmt; + void* vp; + long* lp; + unsigned i; + unsigned args; + + fmt=xp_asprintf_start((char*)csi->ip); + while(*(csi->ip++)); /* Find '\0' terminator */ + args=*(csi->ip++); /* total args */ + for(i=0;i<args;i++) { + if((vp=sbbs->getstrvar(csi,*(long *)csi->ip))==NULL) { + if((lp=sbbs->getintvar(csi,*(long *)csi->ip))==NULL) + fmt=xp_asprintf_next(fmt,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_INT,0); + else + fmt=xp_asprintf_next(fmt,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_INT,*lp); + } + else + fmt=xp_asprintf_next(fmt,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_CHARP,*(char **)vp); + csi->ip+=4; + } + return xp_asprintf_end(fmt); +} int sbbs_t::exec_misc(csi_t* csi, char *path) { @@ -45,7 +71,6 @@ int sbbs_t::exec_misc(csi_t* csi, char *path) uint i=0,j; long l,*lp=NULL,*lp1=NULL,*lp2=NULL; void *vp; - va_list arglist[64]; struct dirent *de; struct tm tm; @@ -66,30 +91,16 @@ int sbbs_t::exec_misc(csi_t* csi, char *path) case VAR_PRINTF: case VAR_PRINTF_LOCAL: op=*(csi->ip-1); - strcpy(str,(char*)csi->ip); - while(*(csi->ip++)); /* Find NULL */ - j=*(csi->ip++); /* total args */ - for(i=0;i<j;i++) { - vp=getstrvar(csi,*(long *)csi->ip); - if(!vp) { - lp=getintvar(csi,*(long *)csi->ip); - if(!lp) - arglist[i]=0; - else - arglist[i]=(char *)*lp; } - else - arglist[i]=*(char **)vp; - csi->ip+=4; } - vsnprintf(tmp,sizeof(tmp),str,(char*)arglist); - tmp[sizeof(tmp)-1]=0; + p=format_string(this, csi); if(op==VAR_PRINTF) - putmsg(cmdstr(tmp,path,csi->str,buf),P_SAVEATR|P_NOABORT|P_NOATCODES); + putmsg(cmdstr(p,path,csi->str,buf),P_SAVEATR|P_NOABORT|P_NOATCODES); else { if(online==ON_LOCAL) - eprintf(LOG_INFO,"%s",cmdstr(tmp,path,csi->str,buf)); + eprintf(LOG_INFO,"%s",cmdstr(p,path,csi->str,buf)); else - lputs(LOG_INFO,cmdstr(tmp,path,csi->str,buf)); + lputs(LOG_INFO,cmdstr(p,path,csi->str,buf)); } + free(p); return(0); case SHOW_VARS: bprintf("shell str=(%08lX) %s\r\n" @@ -490,25 +501,11 @@ int sbbs_t::exec_misc(csi_t* csi, char *path) case FORMAT_STR_VAR: pp=getstrvar(csi,*(long *)csi->ip); csi->ip+=4; /* Skip variable name */ - strcpy(str,(char *)csi->ip); - while(*(csi->ip++)); /* Find NULL */ - j=*(csi->ip++); /* total args */ - for(i=0;i<j;i++) { - vp=getstrvar(csi,*(long *)csi->ip); - if(!vp) { - lp=getintvar(csi,*(long *)csi->ip); - if(!lp) - arglist[i]=0; - else - arglist[i]=(char *)*lp; } - else - arglist[i]=*(char **)vp; - csi->ip+=4; } - vsnprintf(tmp,sizeof(tmp),str,(char *)arglist); - tmp[sizeof(tmp)-1]=0; - cmdstr(tmp,path,csi->str,str); + p=format_string(this, csi); + cmdstr(p,path,csi->str,str); if(pp) *pp=copystrvar(csi,*pp,str); + free(p); return(0); case FORMAT_TIME_STR: pp=getstrvar(csi,*(long *)csi->ip); @@ -1299,27 +1296,12 @@ int sbbs_t::exec_misc(csi_t* csi, char *path) case FIO_PRINTF: lp1=getintvar(csi,*(long *)csi->ip); csi->ip+=4; - strcpy(str,(char *)csi->ip); - while(*(csi->ip++)); /* Find NULL */ - j=*(csi->ip++); /* total args */ - for(i=0;i<j;i++) { - vp=getstrvar(csi,*(long *)csi->ip); - if(!vp) { - lp2=getintvar(csi,*(long *)csi->ip); - if(!lp2) - arglist[i]=0; - else - arglist[i]=(char *)*lp2; - } else - arglist[i]=*(char **)vp; - csi->ip+=4; - } - vsnprintf(tmp,sizeof(tmp),str,(char *)arglist); - tmp[sizeof(tmp)-1]=0; + p=format_string(this, csi); if(lp1 && *lp1) { - cmdstr(tmp,path,csi->str,str); + cmdstr(p,path,csi->str,str); fwrite(str,1,strlen(str),(FILE *)*lp1); } + free(p); return(0); case FIO_SET_ETX: csi->etx=*(csi->ip++); -- GitLab