From 7ff471f7d145359899a173af34d201a0816108b2 Mon Sep 17 00:00:00 2001 From: rswindell <> Date: Sat, 21 Jan 2006 01:33:32 +0000 Subject: [PATCH] Use xp_printf module for all JS printf/sprintf/fprintf methods: * 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/js_file.c | 33 +++--------------- src/sbbs3/js_global.c | 77 +++--------------------------------------- src/sbbs3/js_sprintf.c | 67 ++++++++++++++++++++++++++++++++++++ src/sbbs3/jsexec.c | 31 +++-------------- src/sbbs3/main.cpp | 27 ++------------- src/sbbs3/objects.mk | 1 + src/sbbs3/sbbs.h | 5 ++- 7 files changed, 88 insertions(+), 153 deletions(-) create mode 100644 src/sbbs3/js_sprintf.c diff --git a/src/sbbs3/js_file.c b/src/sbbs3/js_file.c index c7028fc2c9..7efe86c340 100644 --- a/src/sbbs3/js_file.c +++ b/src/sbbs3/js_file.c @@ -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 2005 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 * @@ -1297,10 +1297,6 @@ static JSBool js_fprintf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { char* cp; - uintN i; - JSString * fmt; - JSString * str; - va_list arglist[64]; private_t* p; *rval = JSVAL_FALSE; @@ -1313,34 +1309,13 @@ js_fprintf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) if(p->fp==NULL) return(JS_TRUE); - if((fmt=JS_ValueToString(cx, argv[0]))==NULL) { - JS_ReportError(cx,"JS_ValueToString failed"); - return(JS_FALSE); - } - - memset(arglist,0,sizeof(arglist)); /* Initialize arglist to NULLs */ - - for (i = 1; i < argc && i<sizeof(arglist)/sizeof(arglist[0]); i++) { - if(JSVAL_IS_DOUBLE(argv[i])) - arglist[i-1]=(char*)(unsigned long)*JSVAL_TO_DOUBLE(argv[i]); - else if(JSVAL_IS_INT(argv[i])) - arglist[i-1]=(char *)JSVAL_TO_INT(argv[i]); - else { - if((str=JS_ValueToString(cx, argv[i]))==NULL) { - JS_ReportError(cx,"JS_ValueToString failed"); - return(JS_FALSE); - } - arglist[i-1]=JS_GetStringBytes(str); - } - } - - if((cp=JS_vsmprintf(JS_GetStringBytes(fmt),(char*)arglist))==NULL) { - JS_ReportError(cx,"JS_vsmprintf failed"); + if((cp=js_sprintf(cx, 0, argc, argv))==NULL) { + JS_ReportError(cx,"js_sprintf failed"); return(JS_FALSE); } *rval = INT_TO_JSVAL(fwrite(cp,1,strlen(cp),p->fp)); - JS_smprintf_free(cp); + free(cp); return(JS_TRUE); } diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c index 5f352d3593..3eca314bb2 100644 --- a/src/sbbs3/js_global.c +++ b/src/sbbs3/js_global.c @@ -42,9 +42,6 @@ #include "base64.h" #include "htmlansi.h" #include "ini_file.h" -#ifdef USE_XP_PRINTF - #include "xpprintf.h" -#endif #define MAX_ANSI_SEQ 16 #define MAX_ANSI_PARAMS 8 @@ -284,82 +281,19 @@ js_load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) return(success); } -#ifdef USE_XP_PRINTF - -static JSBool -js_format(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) -{ - char* fmt; - uintN i; - JSString* str; - - if((fmt=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) - return(JS_FALSE); - - fmt=xp_asprintf_start(fmt); - for(i=1; i<argc; i++) { - if(JSVAL_IS_DOUBLE(argv[i])) - fmt=xp_asprintf_next(fmt,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_DOUBLE,*JSVAL_TO_DOUBLE(argv[i])); - else if(JSVAL_IS_INT(argv[i])) - fmt=xp_asprintf_next(fmt,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_INT,JSVAL_TO_INT(argv[i])); - else if(JSVAL_IS_BOOLEAN(argv[i]) && xp_printf_get_type(fmt)!=XP_PRINTF_TYPE_CHARP) - fmt=xp_asprintf_next(fmt,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_INT,JSVAL_TO_BOOLEAN(argv[i])); - else { - if((str=JS_ValueToString(cx, argv[i]))==NULL) { - JS_ReportError(cx,"JS_ValueToString failed"); - return(JS_FALSE); - } - fmt=xp_asprintf_next(fmt,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_CHARP,JS_GetStringBytes(str)); - } - } - - fmt=xp_asprintf_end(fmt); - - str = JS_NewStringCopyZ(cx, fmt); - free(fmt); - - if(str==NULL) - return(JS_FALSE); - - *rval = STRING_TO_JSVAL(str); - return(JS_TRUE); -} - -#else - static JSBool js_format(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { char* p; - char* fmt; - uintN i; - JSString * str; - va_list arglist[64]; + JSString* str; - if((fmt=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) + if((p=js_sprintf(cx, 0, argc, argv))==NULL) { + JS_ReportError(cx,"js_sprintf failed"); return(JS_FALSE); - - memset(arglist,0,sizeof(arglist)); /* Initialize arglist to NULLs */ - - for (i = 1; i < argc && i<sizeof(arglist)/sizeof(arglist[0]); i++) { - if(JSVAL_IS_DOUBLE(argv[i])) - arglist[i-1]=(char*)(unsigned long)*JSVAL_TO_DOUBLE(argv[i]); - else if(JSVAL_IS_INT(argv[i])) - arglist[i-1]=(char *)JSVAL_TO_INT(argv[i]); - else { - if((str=JS_ValueToString(cx, argv[i]))==NULL) { - JS_ReportError(cx,"JS_ValueToString failed"); - return(JS_FALSE); - } - arglist[i-1]=JS_GetStringBytes(str); - } } - - if((p=JS_vsmprintf(fmt,(char*)arglist))==NULL) - return(JS_FALSE); str = JS_NewStringCopyZ(cx, p); - JS_smprintf_free(p); + free(p); if(str==NULL) return(JS_FALSE); @@ -368,9 +302,6 @@ js_format(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) return(JS_TRUE); } -#endif - - static JSBool js_yield(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { diff --git a/src/sbbs3/js_sprintf.c b/src/sbbs3/js_sprintf.c new file mode 100644 index 0000000000..784284d19d --- /dev/null +++ b/src/sbbs3/js_sprintf.c @@ -0,0 +1,67 @@ +/* js_sprintf.c */ + +/* Synchronet JavaScript "[s]printf" implementation */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.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 * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#include "sbbs.h" +#include "xpprintf.h" /* Hurrah for Deuce! */ + +char* DLLCALL +js_sprintf(JSContext *cx, uint argn, uintN argc, jsval *argv) +{ + char* p; + JSString* str; + + if((p=js_ValueToStringBytes(cx, argv[argn++], NULL))==NULL) + return(NULL); + + p=xp_asprintf_start(p); + for(; argn<argc; argn++) { + if(JSVAL_IS_DOUBLE(argv[argn])) + p=xp_asprintf_next(p,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_DOUBLE,*JSVAL_TO_DOUBLE(argv[argn])); + else if(JSVAL_IS_INT(argv[argn])) + p=xp_asprintf_next(p,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_INT,JSVAL_TO_INT(argv[argn])); + else if(JSVAL_IS_BOOLEAN(argv[argn]) && xp_printf_get_type(p)!=XP_PRINTF_TYPE_CHARP) + p=xp_asprintf_next(p,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_INT,JSVAL_TO_BOOLEAN(argv[argn])); + else { + if((str=JS_ValueToString(cx, argv[argn]))==NULL) + return(NULL); + p=xp_asprintf_next(p,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_CHARP,JS_GetStringBytes(str)); + } + } + + return xp_asprintf_end(p); + +} diff --git a/src/sbbs3/jsexec.c b/src/sbbs3/jsexec.c index 48c36c44e9..23fe1c0f7d 100644 --- a/src/sbbs3/jsexec.c +++ b/src/sbbs3/jsexec.c @@ -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 2005 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 * @@ -345,39 +345,18 @@ js_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) static JSBool js_printf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - char* p; - uintN i; - JSString * fmt; - JSString * str; - va_list arglist[64]; + char* p; - if((fmt = JS_ValueToString(cx, argv[0]))==NULL) + if((p = js_sprintf(cx, 0, argc, argv))==NULL) { + JS_ReportError(cx,"js_sprintf failed"); return(JS_FALSE); - - memset(arglist,0,sizeof(arglist)); /* Initialize arglist to NULLs */ - - for (i = 1; i < argc && i<sizeof(arglist)/sizeof(arglist[0]); i++) { - if(JSVAL_IS_DOUBLE(argv[i])) - arglist[i-1]=(char*)(unsigned long)-1;//*JSVAL_TO_DOUBLE(argv[i]); - else if(JSVAL_IS_INT(argv[i])) - arglist[i-1]=(char *)JSVAL_TO_INT(argv[i]); - else { - if((str=JS_ValueToString(cx, argv[i]))==NULL) { - JS_ReportError(cx,"JS_ValueToString failed"); - return(JS_FALSE); - } - arglist[i-1]=JS_GetStringBytes(str); - } } - - if((p=JS_vsmprintf(JS_GetStringBytes(fmt),(char*)arglist))==NULL) - return(JS_FALSE); fprintf(confp,"%s",p); *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, p)); - JS_smprintf_free(p); + free(p); return(JS_TRUE); } diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index 30a5badba5..48f60264b0 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -693,36 +693,15 @@ static JSBool js_printf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { char* p; - uintN i; - JSString * fmt; - JSString * str; sbbs_t* sbbs; - va_list arglist[64]; if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) return(JS_FALSE); - if((fmt = JS_ValueToString(cx, argv[0]))==NULL) + if((p = js_sprintf(cx, 0, argc, argv))==NULL) { + JS_ReportError(cx,"js_sprintf failed"); return(JS_FALSE); - - memset(arglist,0,sizeof(arglist)); // Initialize arglist to NULLs - - for (i = 1; i < argc && i<sizeof(arglist)/sizeof(arglist[0]); i++) { - if(JSVAL_IS_DOUBLE(argv[i])) - arglist[i-1]=(char*)(unsigned long)*JSVAL_TO_DOUBLE(argv[i]); - else if(JSVAL_IS_INT(argv[i])) - arglist[i-1]=(char *)JSVAL_TO_INT(argv[i]); - else { - if((str=JS_ValueToString(cx, argv[i]))==NULL) { - JS_ReportError(cx,"JS_ValueToString failed"); - return(JS_FALSE); - } - arglist[i-1]=JS_GetStringBytes(str); - } } - - if((p=JS_vsmprintf(JS_GetStringBytes(fmt),(char*)arglist))==NULL) - return(JS_FALSE); if(sbbs->online==ON_LOCAL) eprintf(LOG_INFO,"%s",p); @@ -731,7 +710,7 @@ js_printf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, p)); - JS_smprintf_free(p); + free(p); return(JS_TRUE); } diff --git a/src/sbbs3/objects.mk b/src/sbbs3/objects.mk index 5e172beac0..e465b34176 100644 --- a/src/sbbs3/objects.mk +++ b/src/sbbs3/objects.mk @@ -52,6 +52,7 @@ OBJS = $(MTOBJODIR)$(DIRSEP)ansiterm$(OFILE) \ $(MTOBJODIR)$(DIRSEP)js_queue$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_server$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_socket$(OFILE)\ + $(MTOBJODIR)$(DIRSEP)js_sprintf$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_system$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_user$(OFILE)\ $(MTOBJODIR)$(DIRSEP)js_xtrn_area$(OFILE)\ diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index afe6567a40..e40c2c5ac6 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -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 2005 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 * @@ -1023,6 +1023,9 @@ extern "C" { /* js_file.c */ DLLEXPORT JSObject* DLLCALL js_CreateFileClass(JSContext* cx, JSObject* parent); + /* js_sprintf.c */ + DLLEXPORT char* DLLCALL js_sprintf(JSContext* cx, uint argn, uintN argc, jsval *argv); + /* js_console.cpp */ JSObject* js_CreateConsoleObject(JSContext* cx, JSObject* parent); -- GitLab