diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c
index d2962c91f4f5eae946b708483f491aea02d7690c..3ca6536f3a67110611a3db935ccc29e4de5a5ce4 100644
--- a/src/sbbs3/ftpsrvr.c
+++ b/src/sbbs3/ftpsrvr.c
@@ -384,6 +384,7 @@ js_write(JSContext *cx, uintN argc, jsval *arglist)
     JSString*	str=NULL;
 	FILE*	fp;
 	jsrefcount	rc;
+	char		*p;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -394,8 +395,9 @@ js_write(JSContext *cx, uintN argc, jsval *arglist)
 		str = JS_ValueToString(cx, argv[i]);
 		if (!str)
 		    return JS_FALSE;
+		JSSTRING_TO_STRING(cx, str, p);
 		rc=JS_SUSPENDREQUEST(cx);
-		fprintf(fp,"%s",JS_GetStringBytes(str));
+		fprintf(fp,"%s", p);
 		JS_RESUMEREQUEST(cx, rc);
 	}
 
diff --git a/src/sbbs3/js_bbs.cpp b/src/sbbs3/js_bbs.cpp
index 42e90364a7b5c0cd04423ba768aa4086d43df9db..de80fd6dbf949a883e7d99d17821e05b197770b5 100644
--- a/src/sbbs3/js_bbs.cpp
+++ b/src/sbbs3/js_bbs.cpp
@@ -652,7 +652,7 @@ static JSBool js_bbs_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, j
 	else if(JSVAL_IS_STRING(*vp)) {
 		if((js_str = JS_ValueToString(cx, *vp))==NULL)
 			return(JS_FALSE);
-		p=JS_GetStringBytes(js_str);
+		JSSTRING_TO_STRING(cx, js_str, p);
 	}
 
 	switch(tiny) {
@@ -922,7 +922,9 @@ static uint get_subnum(JSContext* cx, sbbs_t* sbbs, jsval val)
 	uint subnum=INVALID_SUB;
 
 	if(JSVAL_IS_STRING(val)) {
-		char* p=JS_GetStringBytes(JS_ValueToString(cx,val));
+		char * p;
+
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(val), p);
 		for(subnum=0;subnum<sbbs->cfg.total_subs;subnum++)
 			if(!stricmp(sbbs->cfg.sub[subnum]->code,p))
 				break;
@@ -939,7 +941,8 @@ static uint get_dirnum(JSContext* cx, sbbs_t* sbbs, jsval val)
 	uint dirnum=INVALID_DIR;
 
 	if(JSVAL_IS_STRING(val)) {
-		char* p=JS_GetStringBytes(JS_ValueToString(cx,val));
+		char	*p;
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(val), p);
 		for(dirnum=0;dirnum<sbbs->cfg.total_dirs;dirnum++)
 			if(!stricmp(sbbs->cfg.dir[dirnum]->code,p))
 				break;
@@ -963,6 +966,7 @@ js_menu(JSContext *cx, uintN argc, jsval *arglist)
     JSString*	str;
  	sbbs_t*		sbbs;
 	jsrefcount	rc;
+	char		*menu;
  
  	if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
  		return(JS_FALSE);
@@ -972,7 +976,8 @@ js_menu(JSContext *cx, uintN argc, jsval *arglist)
  		return(JS_FALSE);
  
 	rc=JS_SUSPENDREQUEST(cx);
-	sbbs->menu(JS_GetStringBytes(str));
+	JSSTRING_TO_STRING(cx, str, menu);
+	sbbs->menu(menu);
 	JS_RESUMEREQUEST(cx, rc);
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
@@ -1051,9 +1056,9 @@ js_exec(JSContext *cx, uintN argc, jsval *arglist)
 	}
 
 	if(startup_dir!=NULL)
-		p_startup_dir=JS_GetStringBytes(startup_dir);
+		JSSTRING_TO_STRING(cx, startup_dir, p_startup_dir);
 
-	cstr=JS_GetStringBytes(cmd);
+	JSSTRING_TO_STRING(cx, cmd, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(sbbs->external(cstr,mode,p_startup_dir)));
 	JS_RESUMEREQUEST(cx, rc);
@@ -1078,10 +1083,8 @@ js_exec_xtrn(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_FALSE);
 
 	if(JSVAL_IS_STRING(argv[0])) {
-		if((str=JS_ValueToString(cx, argv[0]))==NULL)
-			return(JS_FALSE);
-
-		if((code=JS_GetStringBytes(str))==NULL)
+		JSVALUE_TO_STRING(cx,argv[0],code);
+		if(code==NULL)
 			return(JS_FALSE);
 
 		for(i=0;i<sbbs->cfg.total_xtrns;i++)
@@ -1158,7 +1161,7 @@ js_chkpass(JSContext *cx, uintN argc, jsval *arglist)
 
 	JSString* str=JS_ValueToString(cx,argv[0]);
 
-	cstr=JS_GetStringBytes(str);
+	JSSTRING_TO_STRING(cx, str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->chkpass(cstr,&sbbs->useron,true)));
 	JS_RESUMEREQUEST(cx, rc);
@@ -1221,10 +1224,8 @@ js_replace_text(JSContext *cx, uintN argc, jsval *arglist)
 	if(sbbs->text[i]!=sbbs->text_sav[i] && sbbs->text[i]!=nulstr)
 		free(sbbs->text[i]);
 
-	if((js_str=JS_ValueToString(cx, argv[1]))==NULL)
-		return(JS_TRUE);
-
-	if((p=JS_GetStringBytes(js_str))==NULL)
+	JSVALUE_TO_STRING(cx, argv[1], p);
+	if(p==NULL)
 		return(JS_TRUE);
 
 	len=strlen(p);
@@ -1300,7 +1301,7 @@ js_load_text(JSContext *cx, uintN argc, jsval *arglist)
 		JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 		return(JS_TRUE);
 	}
-	cstr=JS_GetStringBytes(js_str);
+	JSSTRING_TO_STRING(cx, js_str, cstr);
 
 	rc=JS_SUSPENDREQUEST(cx);
 	for(i=0;i<TOTAL_TEXT;i++) {
@@ -1362,7 +1363,7 @@ js_atcode(JSContext *cx, uintN argc, jsval *arglist)
 	if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
 		return(JS_FALSE);
 
-	instr = strdup(JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
+	JSVALUE_TO_STRING(cx, argv[0], instr);
 	if(instr==NULL)
 		return(JS_FALSE);
 
@@ -1382,7 +1383,6 @@ js_atcode(JSContext *cx, uintN argc, jsval *arglist)
 
 	rc=JS_SUSPENDREQUEST(cx);
 	cp=sbbs->atcode(instr,str2,sizeof(str2));
-	free(instr);
 	JS_RESUMEREQUEST(cx, rc);
 	if(cp==NULL)
 		JS_SET_RVAL(cx, arglist, JSVAL_NULL);
@@ -1428,7 +1428,8 @@ js_logkey(JSContext *cx, uintN argc, jsval *arglist)
 	if(argc>1)
 		JS_ValueToBoolean(cx,argv[1],&comma);
 
-	if((p=JS_GetStringBytes(js_str))==NULL) {
+	JSSTRING_TO_STRING(cx, js_str, p);
+	if(p==NULL) {
 		JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 		return(JS_TRUE);
 	}
@@ -1463,7 +1464,8 @@ js_logstr(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 	}
 
-	if((p=JS_GetStringBytes(js_str))==NULL) {
+	JSSTRING_TO_STRING(cx, js_str, p);
+	if(p==NULL) {
 		JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 		return(JS_TRUE);
 	}
@@ -1496,7 +1498,8 @@ js_finduser(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 	}
 
-	if((p=JS_GetStringBytes(js_str))==NULL) {
+	JSSTRING_TO_STRING(cx, js_str, p);
+	if(p==NULL) {
 		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
 		return(JS_TRUE);
 	}
@@ -1534,12 +1537,14 @@ js_trashcan(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 	}
 
-	if((can=JS_GetStringBytes(js_can))==NULL) {
+	JSSTRING_TO_STRING(cx, js_can, can);
+	if(can==NULL) {
 		JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 		return(JS_TRUE);
 	}
 
-	if((str=JS_GetStringBytes(js_str))==NULL) {
+	JSSTRING_TO_STRING(cx, js_str, str);
+	if(str==NULL) {
 		JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 		return(JS_TRUE);
 	}
@@ -1611,10 +1616,12 @@ js_login(JSContext *cx, uintN argc, jsval *arglist)
 	if((js_pw=JS_ValueToString(cx, argv[1]))==NULL) 
 		return(JS_FALSE);
 
-	if((name=JS_GetStringBytes(js_name))==NULL) 
+	JSSTRING_TO_STRING(cx, js_name, name);
+	if(name==NULL) 
 		return(JS_FALSE);
 
-	if((pw=JS_GetStringBytes(js_pw))==NULL) 
+	JSSTRING_TO_STRING(cx, js_pw, pw);
+	if(pw==NULL) 
 		return(JS_FALSE);
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -1847,7 +1854,7 @@ js_batchaddlist(JSContext *cx, uintN argc, jsval *arglist)
 	if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
 		return(JS_FALSE);
 
-	cstr=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+	JSVALUE_TO_STRING(cx, argv[0], cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	sbbs->batch_add_list(cstr);
 	JS_RESUMEREQUEST(cx, rc);
@@ -1874,7 +1881,7 @@ js_sendfile(JSContext *cx, uintN argc, jsval *arglist)
 	if(argc>1 && (p=js_ValueToStringBytes(cx, argv[1], NULL))!=NULL)
 		prot=*p;
 
-	cstr=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+	JSVALUE_TO_STRING(cx, argv[0], cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->sendfile(cstr,prot)));
 	JS_RESUMEREQUEST(cx, rc);
@@ -1901,7 +1908,7 @@ js_recvfile(JSContext *cx, uintN argc, jsval *arglist)
 	if(argc>1 && (p=js_ValueToStringBytes(cx, argv[1], NULL))!=NULL)
 		prot=*p;
 
-	cstr=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+	JSVALUE_TO_STRING(cx, argv[0], cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->recvfile(cstr,prot)));
 	JS_RESUMEREQUEST(cx, rc);
@@ -2306,8 +2313,8 @@ js_email(JSContext *cx, uintN argc, jsval *arglist)
 	jsval *argv=JS_ARGV(cx, arglist);
 	int32		usernumber=1;
 	int32		mode=WM_EMAIL;
-	const char*	top="";
-	const char*	subj="";
+	char*		top=(char *)"";
+	char*		subj=(char *)"";
 	JSString*	js_top=NULL;
 	JSString*	js_subj=NULL;
 	sbbs_t*		sbbs;
@@ -2330,9 +2337,9 @@ js_email(JSContext *cx, uintN argc, jsval *arglist)
 	}
 
 	if(js_top!=NULL)
-		top=JS_GetStringBytes(js_top);
+		JSSTRING_TO_STRING(cx, js_top, top);
 	if(js_subj!=NULL)
-		subj=JS_GetStringBytes(js_subj);
+		JSSTRING_TO_STRING(cx, js_subj, subj);
 
 	rc=JS_SUSPENDREQUEST(cx);
 	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->email(usernumber,top,subj,mode)));
@@ -2345,7 +2352,7 @@ js_netmail(JSContext *cx, uintN argc, jsval *arglist)
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
 	int32		mode=0;
-	const char*	subj="";
+	char*		subj=(char *)"";
 	JSString*	js_to;
 	JSString*	js_subj=NULL;
 	sbbs_t*		sbbs;
@@ -2368,9 +2375,9 @@ js_netmail(JSContext *cx, uintN argc, jsval *arglist)
 	}
 
 	if(js_subj!=NULL)
-		subj=JS_GetStringBytes(js_subj);
+		JSSTRING_TO_STRING(cx, js_subj, subj);
 
-	cstr=JS_GetStringBytes(js_to);
+	JSSTRING_TO_STRING(cx, js_to, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->netmail(cstr,subj,mode)));
 	JS_RESUMEREQUEST(cx, rc);
@@ -2386,6 +2393,7 @@ js_bulkmail(JSContext *cx, uintN argc, jsval *arglist)
 	JSString*	js_ars=NULL;
 	sbbs_t*		sbbs;
 	jsrefcount	rc;
+	char		*p;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -2393,10 +2401,10 @@ js_bulkmail(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_FALSE);
 
 	if(argc) {
-		if((js_ars=JS_ValueToString(cx, argv[0]))==NULL)
+		JSVALUE_TO_STRING(cx, argv[0], p);
+		if(p==NULL)
 			return(JS_FALSE);
-
-		ar=arstr(NULL,JS_GetStringBytes(js_ars), &sbbs->cfg);
+		ar=arstr(NULL, p, &sbbs->cfg);
 	}
 	rc=JS_SUSPENDREQUEST(cx);
 	sbbs->bulkmail(ar);
@@ -2510,7 +2518,8 @@ js_telnet_gate(JSContext *cx, uintN argc, jsval *arglist)
 	if((js_addr=JS_ValueToString(cx, argv[0]))==NULL) 
 		return(JS_FALSE);
 
-	if((addr=JS_GetStringBytes(js_addr))==NULL) 
+	JSSTRING_TO_STRING(cx, js_addr, addr);
+	if(addr==NULL) 
 		return(JS_FALSE);
 
 	if(argc>1 && JSVAL_IS_NUM(argv[1]))
@@ -2673,7 +2682,8 @@ js_put_node_message(JSContext *cx, uintN argc, jsval *arglist)
 	if((js_msg=JS_ValueToString(cx, argv[1]))==NULL) 
 		return(JS_FALSE);
 
-	if((msg=JS_GetStringBytes(js_msg))==NULL) 
+	JSSTRING_TO_STRING(cx, js_msg, msg);
+	if(msg==NULL) 
 		return(JS_FALSE);
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -2732,7 +2742,8 @@ js_put_telegram(JSContext *cx, uintN argc, jsval *arglist)
 	if((js_msg=JS_ValueToString(cx, argv[1]))==NULL) 
 		return(JS_FALSE);
 
-	if((msg=JS_GetStringBytes(js_msg))==NULL) 
+	JSSTRING_TO_STRING(cx, js_msg, msg);
+	if(msg==NULL) 
 		return(JS_FALSE);
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -2748,8 +2759,8 @@ js_cmdstr(JSContext *cx, uintN argc, jsval *arglist)
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
 	char*		p;
-	const char*	fpath="";
-	const char*	fspec="";
+	char*		fpath=(char *)"";
+	char*		fspec=(char *)"";
 	JSString*	js_str;
 	sbbs_t*		sbbs;
 	jsrefcount	rc;
@@ -2763,15 +2774,15 @@ js_cmdstr(JSContext *cx, uintN argc, jsval *arglist)
  	if (!js_str)
  		return(JS_FALSE);
 
-	p=JS_GetStringBytes(js_str);
+	JSSTRING_TO_STRING(cx, js_str, p);
 
 	for(uintN i=1;i<argc;i++) {
 		if(JSVAL_IS_STRING(argv[i])) {
 			js_str = JS_ValueToString(cx, argv[i]);
 			if(fpath==NULL)
-				fpath=JS_GetStringBytes(js_str);
+				JSSTRING_TO_STRING(cx, js_str, fpath)	// Magic
 			else
-				fspec=JS_GetStringBytes(js_str);
+				JSSTRING_TO_STRING(cx, js_str, fspec);
 		}
 	}
 
@@ -2821,7 +2832,7 @@ js_listfiles(JSContext *cx, uintN argc, jsval *arglist)
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
 	int32		mode=0;
-	const char*	fspec=ALLFILES;
+	char*		fspec=(char *)ALLFILES;
 	char		buf[MAX_PATH+1];
 	uint		dirnum;
     JSString*	js_str;
@@ -2845,7 +2856,7 @@ js_listfiles(JSContext *cx, uintN argc, jsval *arglist)
 			JS_ValueToInt32(cx,argv[i],&mode);
 		else if(JSVAL_IS_STRING(argv[i])) {
 			js_str = JS_ValueToString(cx, argv[i]);
-			fspec=JS_GetStringBytes(js_str);
+			JSSTRING_TO_STRING(cx, js_str, fspec);
 		}
 	}
 
@@ -2865,7 +2876,7 @@ js_listfileinfo(JSContext *cx, uintN argc, jsval *arglist)
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
 	int32		mode=FI_INFO;
-	const char*	fspec=ALLFILES;
+	char*		fspec=(char *)ALLFILES;
 	char		buf[MAX_PATH+1];
 	uint		dirnum;
     JSString*	js_str;
@@ -2889,7 +2900,7 @@ js_listfileinfo(JSContext *cx, uintN argc, jsval *arglist)
 			JS_ValueToInt32(cx,argv[i],&mode);
 		else if(JSVAL_IS_STRING(argv[i])) {
 			js_str = JS_ValueToString(cx, argv[i]);
-			fspec=JS_GetStringBytes(js_str);
+			JSSTRING_TO_STRING(cx, js_str, fspec);
 		}
 	}
 
@@ -3083,7 +3094,7 @@ js_scanposts(JSContext *cx, uintN argc, jsval *arglist)
 {
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
-	const char*	find="";
+	char*		find=(char *)"";
 	int32		mode=0;
 	uint		subnum;
 	sbbs_t*		sbbs;
@@ -3105,7 +3116,7 @@ js_scanposts(JSContext *cx, uintN argc, jsval *arglist)
 		if(JSVAL_IS_NUM(argv[i]))
 			JS_ValueToInt32(cx,argv[i],&mode);
 		else if(JSVAL_IS_STRING(argv[i]))
-			find=JS_GetStringBytes(JS_ValueToString(cx,argv[i]));
+			JSVALUE_TO_STRING(cx, argv[i], find);
 	}
 
 	if(*find)
@@ -3122,7 +3133,7 @@ js_listmsgs(JSContext *cx, uintN argc, jsval *arglist)
 {
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
-	const char*	find="";
+	char*		find=(char *)"";
 	int32		mode=0;
 	int32		start=0;
 	uint		subnum;
@@ -3147,7 +3158,7 @@ js_listmsgs(JSContext *cx, uintN argc, jsval *arglist)
 	if(JSVAL_IS_NUM(argv[argn]))
 		JS_ValueToInt32(cx,argv[argn++],&start);
 	if(JSVAL_IS_STRING(argv[argn]))
-		find=JS_GetStringBytes(JS_ValueToString(cx,argv[argn++]));
+		JSVALUE_TO_STRING(cx, argv[argn++], find);
 
 	rc=JS_SUSPENDREQUEST(cx);
 	JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(sbbs->listsub(subnum,mode,start,find)));
@@ -3249,17 +3260,19 @@ js_chk_ar(JSContext *cx, uintN argc, jsval *arglist)
 	JSString*	js_str;
 	sbbs_t*		sbbs;
 	jsrefcount	rc;
+	char		*p;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
 	if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
 		return JS_FALSE;
 
-	if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
+	JSVALUE_TO_STRING(cx, argv[0], p);
+	if(p==NULL)
 		return JS_FALSE;
 
 	rc=JS_SUSPENDREQUEST(cx);
-	ar = arstr(NULL,JS_GetStringBytes(js_str),&sbbs->cfg);
+	ar = arstr(NULL,p,&sbbs->cfg);
 
 	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->chk_ar(ar,&sbbs->useron,&sbbs->client)));
 
@@ -3647,7 +3660,7 @@ static JSBool js_bbs_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_bbs_properties, js_bbs_functions, NULL, 0));
diff --git a/src/sbbs3/js_client.c b/src/sbbs3/js_client.c
index 4c31849361638e1c528ffa7789f03b9cae663149..7f3a6f3d917dc33d78a3a46e429efb7b20b11aaa 100644
--- a/src/sbbs3/js_client.c
+++ b/src/sbbs3/js_client.c
@@ -138,7 +138,7 @@ static JSBool js_client_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_client_properties, NULL, NULL, 0));
diff --git a/src/sbbs3/js_com.c b/src/sbbs3/js_com.c
index c21e93531c6a2697fdb018489db745569bcb7a00..d8b2f12248766a69fd244c348e6bafd50f8e4238 100644
--- a/src/sbbs3/js_com.c
+++ b/src/sbbs3/js_com.c
@@ -187,8 +187,7 @@ js_send(JSContext *cx, uintN argc, jsval *arglist)
 
 	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 
-	str = JS_ValueToString(cx, argv[0]);
-	cp	= JS_GetStringBytes(str);
+	JSVALUE_TO_STRING(cx, argv[0], cp);
 	len	= JS_GetStringLength(str);
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -226,8 +225,8 @@ js_sendfile(JSContext *cx, uintN argc, jsval *arglist)
 
 	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 
-	if((str = JS_ValueToString(cx, argv[0]))==NULL
-		|| (fname=JS_GetStringBytes(str))==NULL) {
+	JSVALUE_TO_STRING(cx, argv[0], fname);
+	if(fname==NULL) {
 		JS_ReportError(cx,"Failure reading filename");
 		return(JS_FALSE);
 	}
@@ -733,7 +732,7 @@ static JSBool js_com_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_com_properties, js_com_functions, NULL, 0));
@@ -771,8 +770,9 @@ js_com_constructor(JSContext *cx, uintN argc, jsval *arglist)
 
 	obj=JS_NewObject(cx, &js_com_class, NULL, NULL);
 	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj));
-	if(argc==0 || (str = JS_ValueToString(cx, argv[0]))==NULL
-		|| (fname=JS_GetStringBytes(str))==NULL) {
+	if(argc > 0)
+		JSVALUE_TO_STRING(cx, argv[0], fname);
+	if(argc==0 || fname==NULL) {
 		JS_ReportError(cx,"Failure reading port name");
 		return(JS_FALSE);
 	}
diff --git a/src/sbbs3/js_conio.c b/src/sbbs3/js_conio.c
index a0ae4371702ba2217978f6629818005b53ef432c..19bc8c185641eed2acd04c4b144e29f879ba0cb0 100644
--- a/src/sbbs3/js_conio.c
+++ b/src/sbbs3/js_conio.c
@@ -1134,7 +1134,7 @@ static JSBool js_conio_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_properties, js_functions, NULL, 0));
diff --git a/src/sbbs3/js_console.cpp b/src/sbbs3/js_console.cpp
index d74f77c303f0fe1c31a78d2ef4ffbdfd3dd88bb0..65cce95c616c52b36cf62f4755ef7d80e1e91e39 100644
--- a/src/sbbs3/js_console.cpp
+++ b/src/sbbs3/js_console.cpp
@@ -183,6 +183,7 @@ static JSBool js_console_set(JSContext *cx, JSObject *obj, jsid id, JSBool stric
 	sbbs_t*		sbbs;
 	JSString*	str;
 	jsrefcount	rc;
+	char		*sval;
 
 	if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
 		return(JS_FALSE);
@@ -205,9 +206,10 @@ static JSBool js_console_set(JSContext *cx, JSObject *obj, jsid id, JSBool stric
 			break;
 		case CON_PROP_ATTR:
 			if(JSVAL_IS_STRING(*vp)) {
-				if((str=JS_ValueToString(cx, *vp))==NULL)
+				JSVALUE_TO_STRING(cx, *vp, sval);
+				if(sval==NULL)
 					break;
-				val=attrstr(JS_GetStringBytes(str));
+				val=attrstr(sval);
 			}
 			rc=JS_SUSPENDREQUEST(cx);
 			sbbs->attr(val);
@@ -226,9 +228,10 @@ static JSBool js_console_set(JSContext *cx, JSObject *obj, jsid id, JSBool stric
 			sbbs->autoterm=val;
 			break;
 		case CON_PROP_TERMINAL:
-			if((str=JS_ValueToString(cx, *vp))==NULL)
+			JSVALUE_TO_STRING(cx, *vp, sval);
+			if(sval==NULL)
 				break;
-			SAFECOPY(sbbs->terminal,JS_GetStringBytes(str));
+			SAFECOPY(sbbs->terminal,sval);
 			break;
 		case CON_PROP_INACTIV_WARN:
 			sbbs->cfg.sec_warn = (uint16_t)val;
@@ -259,9 +262,10 @@ static JSBool js_console_set(JSContext *cx, JSObject *obj, jsid id, JSBool stric
 			sbbs->getstr_offset=val;
 			break;
 		case CON_PROP_QUESTION:
-			if((str=JS_ValueToString(cx, *vp))==NULL)
+			JSVALUE_TO_STRING(cx, *vp, sval);
+			if(sval==NULL)
 				break;
-			SAFECOPY(sbbs->question,JS_GetStringBytes(str));
+			SAFECOPY(sbbs->question,sval);
 			break;
 		case CON_PROP_CTRLKEY_PASSTHRU:
 			if(JSVAL_IS_STRING(*vp)) {
@@ -273,7 +277,8 @@ static JSBool js_console_set(JSContext *cx, JSObject *obj, jsid id, JSBool stric
 				if((str=JS_ValueToString(cx, *vp))==NULL)
 					break;
 				val=sbbs->cfg.ctrlkey_passthru;
-				for(s=JS_GetStringBytes(str); *s; s++) {
+				JSSTRING_TO_STRING(cx, str, s);
+				for(; *s; s++) {
 					if(*s=='+')
 						op=1;
 					else if(*s=='-')
@@ -454,6 +459,7 @@ js_handle_ctrlkey(JSContext *cx, uintN argc, jsval *arglist)
 	sbbs_t*		sbbs;
     JSString*	js_str;
 	jsrefcount	rc;
+	char		*keystr;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 
@@ -463,9 +469,10 @@ js_handle_ctrlkey(JSContext *cx, uintN argc, jsval *arglist)
 	if(JSVAL_IS_INT(argv[0]))
 		key=(char)JSVAL_TO_INT(argv[0]);
 	else {
-		if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
+		JSVALUE_TO_STRING(cx, argv[0], keystr);
+		if(keystr==NULL)
 			return(JS_FALSE);
-		key=*JS_GetStringBytes(js_str);
+		key=keystr[0];
 	}
 
 	if(argc>1)
@@ -482,7 +489,7 @@ js_getstr(JSContext *cx, uintN argc, jsval *arglist)
 {
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
-	char		*p;
+	char		*p,*p2;
 	long		mode=0;
 	uintN		i;
 	size_t		maxlen=0;
@@ -515,8 +522,10 @@ js_getstr(JSContext *cx, uintN argc, jsval *arglist)
 	if((p=(char *)calloc(1,maxlen+1))==NULL)
 		return(JS_FALSE);
 
-	if(js_str!=NULL)
-		sprintf(p,"%.*s",(int)maxlen,JS_GetStringBytes(js_str));
+	if(js_str!=NULL) {
+		JSSTRING_TO_STRING(cx, js_str, p2);
+		sprintf(p,"%.*s",(int)maxlen,p2);
+	}
 
 	rc=JS_SUSPENDREQUEST(cx);
 	sbbs->getstr(p,maxlen,mode);
@@ -590,7 +599,7 @@ js_getkeys(JSContext *cx, uintN argc, jsval *arglist)
 	if(js_str==NULL)
 		return(JS_FALSE);
 
-	cstr=JS_GetStringBytes(js_str);
+	JSSTRING_TO_STRING(cx, js_str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	val=sbbs->getkeys(cstr,maxnum);
 	JS_RESUMEREQUEST(cx, rc);
@@ -645,10 +654,12 @@ js_gettemplate(JSContext *cx, uintN argc, jsval *arglist)
 
 	if(js_str==NULL)
 		str[0]=0;
-	else
-		SAFECOPY(str,JS_GetStringBytes(js_str));
+	else {
+		JSSTRING_TO_STRING(cx, js_str, cstr);
+		SAFECOPY(str,cstr);
+	}
 
-	cstr=JS_GetStringBytes(js_fmt);
+	JSSTRING_TO_STRING(cx, js_fmt, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	sbbs->gettmplt(str,cstr,mode);
 	JS_RESUMEREQUEST(cx, rc);
@@ -678,7 +689,7 @@ js_ungetstr(JSContext *cx, uintN argc, jsval *arglist)
 	if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
 		return(JS_FALSE);
 
-	p=JS_GetStringBytes(js_str);
+	JSSTRING_TO_STRING(cx, js_str, p);
 
 	rc=JS_SUSPENDREQUEST(cx);
 	while(p && *p)
@@ -705,7 +716,7 @@ js_yesno(JSContext *cx, uintN argc, jsval *arglist)
 	if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
 		return(JS_FALSE);
 
-	cstr=JS_GetStringBytes(js_str);
+	JSSTRING_TO_STRING(cx, js_str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->yesno(cstr)));
 	JS_RESUMEREQUEST(cx, rc);
@@ -730,7 +741,7 @@ js_noyes(JSContext *cx, uintN argc, jsval *arglist)
 	if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
 		return(JS_FALSE);
 
-	cstr=JS_GetStringBytes(js_str);
+	JSSTRING_TO_STRING(cx, js_str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->noyes(cstr)));
 	JS_RESUMEREQUEST(cx, rc);
@@ -755,7 +766,7 @@ js_mnemonics(JSContext *cx, uintN argc, jsval *arglist)
 	if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
 		return(JS_FALSE);
 	
-	cstr=JS_GetStringBytes(js_str);
+	JSSTRING_TO_STRING(cx, js_str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	sbbs->mnemonics(cstr);
 	JS_RESUMEREQUEST(cx, rc);
@@ -955,7 +966,7 @@ js_strlen(JSContext *cx, uintN argc, jsval *arglist)
 	if((str=JS_ValueToString(cx, argv[0]))==NULL)
 		return(JS_FALSE);
 
-	cstr=JS_GetStringBytes(str);
+	JSSTRING_TO_STRING(cx, str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(bstrlen(cstr)));
 	JS_RESUMEREQUEST(cx, rc);
@@ -1030,7 +1041,7 @@ js_putmsg(JSContext *cx, uintN argc, jsval *arglist)
 	if(argc>1 && JSVAL_IS_NUMBER(argv[1]))
 		JS_ValueToInt32(cx,argv[1],(int32*)&mode);
 
-	cstr=JS_GetStringBytes(str);
+	JSSTRING_TO_STRING(cx, str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	sbbs->putmsg(cstr,mode);
 	JS_RESUMEREQUEST(cx, rc);
@@ -1060,7 +1071,7 @@ js_printfile(JSContext *cx, uintN argc, jsval *arglist)
 	if(argc>1 && JSVAL_IS_NUMBER(argv[1]))
 		JS_ValueToInt32(cx,argv[1],(int32*)&mode);
 
-	cstr=JS_GetStringBytes(str);
+	JSSTRING_TO_STRING(cx, str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	sbbs->printfile(cstr,mode);
 	JS_RESUMEREQUEST(cx, rc);
@@ -1101,7 +1112,7 @@ js_printtail(JSContext *cx, uintN argc, jsval *arglist)
 	if(!lines) 
 		lines=5;
 
-	cstr=JS_GetStringBytes(js_str);
+	JSSTRING_TO_STRING(cx, js_str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	sbbs->printtail(cstr,lines,mode);
 	JS_RESUMEREQUEST(cx, rc);
@@ -1126,9 +1137,9 @@ js_editfile(JSContext *cx, uintN argc, jsval *arglist)
 	if((str=JS_ValueToString(cx, argv[0]))==NULL)
 		return(JS_FALSE);
 
-	cstr=JS_GetStringBytes(str);
+	JSSTRING_TO_STRING(cx, str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
-	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->editfile(JS_GetStringBytes(str))));
+	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->editfile(cstr)));
 	JS_RESUMEREQUEST(cx, rc);
     return(JS_TRUE);
 }
@@ -1168,11 +1179,11 @@ js_uselect(JSContext *cx, uintN argc, jsval *arglist)
 			return(JS_FALSE);
 
 		if(title==NULL) 
-			title=JS_GetStringBytes(js_str);
+			JSSTRING_TO_STRING(cx, js_str, title)	// Magicsemicolon
 		else if(item==NULL)
-			item=JS_GetStringBytes(js_str);
+			JSSTRING_TO_STRING(cx, js_str, item)	// Magicsemicolon
 		else {
-			ar_str=JS_GetStringBytes(js_str);
+			JSSTRING_TO_STRING(cx, js_str, ar_str);
 			ar=arstr(NULL,ar_str,&sbbs->cfg);
 		}
 	}
@@ -1202,9 +1213,9 @@ js_center(JSContext *cx, uintN argc, jsval *arglist)
 	if (!str)
 		return(JS_FALSE);
 
-	cstr=JS_GetStringBytes(str);
+	JSSTRING_TO_STRING(cx, str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
-	sbbs->center(JS_GetStringBytes(str));
+	sbbs->center(cstr);
 	JS_RESUMEREQUEST(cx, rc);
     return(JS_TRUE);
 }
@@ -1854,7 +1865,7 @@ static JSBool js_console_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_console_properties, js_console_functions, NULL, 0));
diff --git a/src/sbbs3/js_file.c b/src/sbbs3/js_file.c
index 6a304366616b9eb3468ba2beff832c7c9538aaad..76fcf24da221ad946c263876a7fdc00b7c6311e7 100644
--- a/src/sbbs3/js_file.c
+++ b/src/sbbs3/js_file.c
@@ -155,7 +155,7 @@ js_open(JSContext *cx, uintN argc, jsval *arglist)
 				JS_ReportError(cx,"Invalid mode specified: %s",str);
 				return(JS_TRUE);
 			}
-			mode=JS_GetStringBytes(str);
+			JSSTRING_TO_STRING(cx, str, mode);
 		} else if(JSVAL_IS_BOOLEAN(argv[i]))	/* shareable */
 			shareable=JSVAL_TO_BOOLEAN(argv[i]);
 		else if(JSVAL_IS_NUMBER(argv[i])) {	/* bufsize */
@@ -218,7 +218,7 @@ js_popen(JSContext *cx, uintN argc, jsval *arglist)
 				JS_ReportError(cx,"Invalid mode specified: %s",str);
 				return(JS_TRUE);
 			}
-			mode=JS_GetStringBytes(str);
+			JSSTRING_TO_STRING(cx, str, mode);
 		}
 		else if(JSVAL_IS_NUMBER(argv[i])) {	/* bufsize */
 			if(!JS_ValueToInt32(cx,argv[i],&bufsize))
@@ -641,8 +641,8 @@ js_iniGetValue(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 
 	if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
-		section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
-	key=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
+		JSVALUE_TO_STRING(cx, argv[0], section);
+	JSVALUE_TO_STRING(cx, argv[1], key);
 
 	if(dflt==JSVAL_VOID) {	/* unspecified default value */
 		rc=JS_SUSPENDREQUEST(cx);
@@ -667,7 +667,7 @@ js_iniGetValue(JSContext *cx, uintN argc, jsval *arglist)
 		}
 		else {
 		    array = JS_NewArrayObject(cx, 0, NULL);
-			cstr=JS_GetStringBytes(JS_ValueToString(cx,dflt));
+			JSVALUE_TO_STRING(cx, dflt, cstr);
 			rc=JS_SUSPENDREQUEST(cx);
 			list=iniReadStringList(p->fp,section,key,",",cstr);
 			JS_RESUMEREQUEST(cx, rc);
@@ -696,7 +696,7 @@ js_iniGetValue(JSContext *cx, uintN argc, jsval *arglist)
 		JS_RESUMEREQUEST(cx, rc);
 		JS_SET_RVAL(cx, arglist,INT_TO_JSVAL(i));
 	} else {
-		cstr=JS_GetStringBytes(JS_ValueToString(cx,dflt));
+		JSVALUE_TO_STRING(cx, dflt, cstr);
 		rc=JS_SUSPENDREQUEST(cx);
 		cstr2=iniReadString(p->fp,section,key,cstr,buf);
 		JS_RESUMEREQUEST(cx, rc);
@@ -732,8 +732,8 @@ js_iniSetValue_internal(JSContext *cx, JSObject *obj, uintN argc, jsval* argv, j
 		return(JS_TRUE);
 
 	if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
-		section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
-	key=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
+		JSVALUE_TO_STRING(cx, argv[0], section);
+	JSVALUE_TO_STRING(cx, argv[1], key);
 
 	rc=JS_SUSPENDREQUEST(cx);
 	if((list=iniReadFile(p->fp))==NULL) {
@@ -767,7 +767,7 @@ js_iniSetValue_internal(JSContext *cx, JSObject *obj, uintN argc, jsval* argv, j
 		result = iniSetDateTime(&list,section,key,/* include_time */TRUE, tt,NULL);
 		JS_RESUMEREQUEST(cx, rc);
 	} else {
-		cstr=JS_GetStringBytes(JS_ValueToString(cx,value));
+		JSVALUE_TO_STRING(cx, value, cstr);
 		rc=JS_SUSPENDREQUEST(cx);
 		result = iniSetString(&list,section,key, cstr,NULL);
 		JS_RESUMEREQUEST(cx, rc);
@@ -818,8 +818,8 @@ js_iniRemoveKey(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 
 	if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
-		section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
-	key=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
+		JSVALUE_TO_STRING(cx, argv[0], section);
+	JSVALUE_TO_STRING(cx, argv[1], key);
 
 	rc=JS_SUSPENDREQUEST(cx);
 	if((list=iniReadFile(p->fp))==NULL) {
@@ -857,7 +857,7 @@ js_iniRemoveSection(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 
 	if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
-		section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+		JSVALUE_TO_STRING(cx, argv[0], section);
 
 	rc=JS_SUSPENDREQUEST(cx);
 	if((list=iniReadFile(p->fp))==NULL) {
@@ -899,7 +899,7 @@ js_iniGetSections(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 
 	if(argc)
-		prefix=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+		JSVALUE_TO_STRING(cx, argv[0], prefix);
 
     array = JS_NewArrayObject(cx, 0, NULL);
 
@@ -944,7 +944,7 @@ js_iniGetKeys(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 
 	if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
-		section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+		JSVALUE_TO_STRING(cx, argv[0], section);
     array = JS_NewArrayObject(cx, 0, NULL);
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -987,7 +987,7 @@ js_iniGetObject(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 
 	if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
-		section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+		JSVALUE_TO_STRING(cx, argv[0], section);
 
 	rc=JS_SUSPENDREQUEST(cx);
 	list = iniReadNamedStringList(p->fp,section);
@@ -1025,6 +1025,7 @@ js_iniSetObject(JSContext *cx, uintN argc, jsval *arglist)
 	JSIdArray*	id_array;
 	jsval		set_argv[3];
 	jsval		rval;
+	char		*p;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 
@@ -1042,7 +1043,8 @@ js_iniSetObject(JSContext *cx, uintN argc, jsval *arglist)
 		/* property */
 		JS_IdToValue(cx,id_array->vector[i],&set_argv[1]);	
 		/* value */
-		JS_GetProperty(cx,object,JS_GetStringBytes(JSVAL_TO_STRING(set_argv[1])),&set_argv[2]);
+		JSVALUE_TO_STRING(cx, set_argv[1], p);
+		JS_GetProperty(cx,object,p,&set_argv[2]);
 		if(!js_iniSetValue_internal(cx,obj,3,set_argv,&rval))
 			break;
 	}
@@ -1083,10 +1085,10 @@ js_iniGetAllObjects(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 
 	if(argc)
-		name=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+		JSVALUE_TO_STRING(cx, argv[0], name);
 
 	if(argc>1)
-		prefix=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
+		JSVALUE_TO_STRING(cx, argv[1], prefix);
 
     array = JS_NewArrayObject(cx, 0, NULL);
 
@@ -1173,7 +1175,7 @@ js_iniSetAllObjects(JSContext *cx, uintN argc, jsval *arglist)
 {
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
-	char*		name="name";
+	char*		name=(char *)"name";
     jsuint      i;
     jsint       j;
     jsuint      count;
@@ -1183,6 +1185,7 @@ js_iniSetAllObjects(JSContext *cx, uintN argc, jsval *arglist)
 	jsval		set_argv[3];
 	JSIdArray*	id_array;
 	jsval		rval;
+	char		*p;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 
@@ -1198,7 +1201,7 @@ js_iniSetAllObjects(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 
 	if(argc>1)
-		name=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
+		JSVALUE_TO_STRING(cx, argv[1], name);
 
 	/* enumerate the array */
 	for(i=0; i<count; i++)  {
@@ -1216,10 +1219,11 @@ js_iniSetAllObjects(JSContext *cx, uintN argc, jsval *arglist)
 			/* property */
 			JS_IdToValue(cx,id_array->vector[j],&set_argv[1]);	
 			/* check if not name */
-			if(strcmp(JS_GetStringBytes(JS_ValueToString(cx, set_argv[1])),name)==0)
+			JSVALUE_TO_STRING(cx, set_argv[1], p);
+			if(strcmp(p,name)==0)
 				continue;
 			/* value */
-			JS_GetProperty(cx,object,JS_GetStringBytes(JSVAL_TO_STRING(set_argv[1])),&set_argv[2]);
+			JS_GetProperty(cx,object,p,&set_argv[2]);
 			if(!js_iniSetValue_internal(cx,obj,3,set_argv,&rval))
 				break;
 		}
@@ -1254,8 +1258,10 @@ js_write(JSContext *cx, uintN argc, jsval *arglist)
 	if(p->fp==NULL)
 		return(JS_TRUE);
 
-	str = JS_ValueToString(cx, argv[0]);
-	cp	= JS_GetStringBytes(str);
+	if((str = JS_ValueToString(cx, argv[0]))==NULL)
+		return(JS_FALSE);
+
+	JSSTRING_TO_STRING(cx, str, cp);
 	len	= JS_GetStringLength(str);
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -1337,7 +1343,7 @@ js_writeln_internal(JSContext *cx, JSObject *obj, jsval *arg, jsval *rval)
 			JS_ReportError(cx,"JS_ValueToString failed");
 			return(JS_FALSE);
 		}
-		cp = JS_GetStringBytes(str);
+		JSSTRING_TO_STRING(cx, str, cp);
 	}
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -2379,7 +2385,7 @@ static JSBool js_file_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_file_properties, js_file_functions, NULL, 0));
@@ -2412,6 +2418,7 @@ js_file_constructor(JSContext *cx, uintN argc, jsval *arglist)
 	jsval *argv=JS_ARGV(cx, arglist);
 	JSString*	str;
 	private_t*	p;
+	char		*cstr;
 
 	obj=JS_NewObject(cx, &js_file_class, NULL, NULL);
 	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj));
@@ -2425,7 +2432,8 @@ js_file_constructor(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_FALSE);
 	}
 
-	SAFECOPY(p->name,JS_GetStringBytes(str));
+	JSSTRING_TO_STRING(cx, str, cstr);
+	SAFECOPY(p->name,cstr);
 
 	if(!JS_SetPrivate(cx, obj, p)) {
 		dbprintf(TRUE, p, "JS_SetPrivate failed");
diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c
index 08504c435553840941721127e39d08d187911c73..6ae90090f458d3580a5299cdef7b94b126ddb05e 100644
--- a/src/sbbs3/js_global.c
+++ b/src/sbbs3/js_global.c
@@ -703,7 +703,8 @@ js_ascii(JSContext *cx, uintN argc, jsval *arglist)
 
 	if(JSVAL_IS_STRING(argv[0])) {	/* string to ascii-int */
 
-		if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL) 
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(argv[0]), p);
+		if(p==NULL) 
 			return(JS_FALSE);
 
 		JS_SET_RVAL(cx, arglist,INT_TO_JSVAL(*p));
@@ -740,7 +741,8 @@ js_ctrl(JSContext *cx, uintN argc, jsval *arglist)
 
 	if(JSVAL_IS_STRING(argv[0])) {	
 
-		if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL) 
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(argv[0]), p);
+		if(p==NULL) 
 			return(JS_FALSE);
 		ch=*p;
 	} else {
@@ -3317,7 +3319,8 @@ js_flags_str(JSContext *cx, uintN argc, jsval *arglist)
 
 	if(JSVAL_IS_STRING(argv[0])) {	/* string to long */
 
-		if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL) 
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(argv[0]), p);
+		if(p==NULL) 
 			return(JS_FALSE);
 
 		JS_SET_RVAL(cx, arglist,DOUBLE_TO_JSVAL((double)aftol(p)));
@@ -3754,7 +3757,7 @@ static JSBool js_global_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	if(p->methods) {
diff --git a/src/sbbs3/js_internal.c b/src/sbbs3/js_internal.c
index dfc255bbac1126206e8ffae142b2d735b96f494e..5c73010b2d8dd36824d22e5078c46c8619f684a7 100644
--- a/src/sbbs3/js_internal.c
+++ b/src/sbbs3/js_internal.c
@@ -271,7 +271,8 @@ js_eval(JSContext *parent_cx, uintN argc, jsval *arglist)
 
 	if((str=JS_ValueToString(parent_cx, argv[0]))==NULL)
 		return(JS_FALSE);
-	if((buf=JS_GetStringBytes(str))==NULL)
+	JSSTRING_TO_STRING(cx, str, buf);
+	if(buf==NULL)
 		return(JS_FALSE);
 	buflen=JS_GetStringLength(str);
 
@@ -351,7 +352,10 @@ js_report_error(JSContext *cx, uintN argc, jsval *arglist)
 {
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
-	JS_ReportError(cx,"%s",JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
+	char	*p;
+
+	JSVALUE_TO_STRING(cx, argv[0], p);
+	JS_ReportError(cx,"%s",p);
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -367,6 +371,7 @@ js_on_exit(JSContext *cx, uintN argc, jsval *arglist)
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
 	js_branch_t*	branch;
+	char		*p;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -376,7 +381,8 @@ js_on_exit(JSContext *cx, uintN argc, jsval *arglist)
 	if(branch->exit_func==NULL)
 		branch->exit_func=strListInit();
 
-	strListPush(&branch->exit_func,JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
+	JSVALUE_TO_STRING(cx, argv[0], p);
+	strListPush(&branch->exit_func,p);
 
 	return(JS_TRUE);
 }
@@ -433,7 +439,7 @@ static JSBool js_internal_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_properties, js_functions, NULL, 0));
@@ -457,25 +463,6 @@ static JSClass js_internal_class = {
 	,JS_FinalizeStub		/* finalize		*/
 };
 
-#if JS_VERSION >= 185
-char* DLLCALL JS_GetStringBytes_dumbass(JSContext *cx, JSString *str)
-{
-	size_t			len;
-	size_t			pos;
-	const jschar	*val;
-	char			*ret;
-
-	if(!(val=JS_GetStringCharsAndLength(cx, str, &len)))
-		return NULL;
-	if(!(ret=malloc(len+1)))
-		return NULL;
-	for(pos=0; pos<len; pos++)
-		ret[pos]=val[pos];
-	ret[len]=0;
-	return ret;
-}
-#endif
-
 void DLLCALL js_EvalOnExit(JSContext *cx, JSObject *obj, js_branch_t* branch)
 {
 	char*	p;
diff --git a/src/sbbs3/js_msgbase.c b/src/sbbs3/js_msgbase.c
index 0be41d98bd4ab22a1ea95d76df117b31f0eb79ce..e5edf6e2a868ee6053c4884b92b6775af371b3f4 100644
--- a/src/sbbs3/js_msgbase.c
+++ b/src/sbbs3/js_msgbase.c
@@ -145,7 +145,8 @@ static BOOL parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, s
 	jsval		val;
 
 	if(JS_GetProperty(cx, hdr, "to", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 	} else {
 		if(p->smb.status.attr&SMB_EMAIL)	/* e-mail */
@@ -162,7 +163,8 @@ static BOOL parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, s
 	}
 
 	if(JS_GetProperty(cx, hdr, "to_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, RECIPIENTEXT, cp))!=SMB_SUCCESS)
 			return(FALSE);
@@ -171,7 +173,8 @@ static BOOL parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, s
 	}
 
 	if(JS_GetProperty(cx, hdr, "to_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, RECIPIENTORG, cp))!=SMB_SUCCESS)
 			return(FALSE);
@@ -183,7 +186,8 @@ static BOOL parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, s
 	}
 
 	if(JS_GetProperty(cx, hdr, "to_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_netaddr(msg, RECIPIENTNETADDR, cp, &nettype))!=SMB_SUCCESS)
 			return(FALSE);
@@ -228,7 +232,8 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 
 	/* Required Header Fields */
 	if(JS_GetProperty(cx, hdr, "subject", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 	} else
 		cp="";
@@ -237,7 +242,8 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 	msg->idx.subj=smb_subject_crc(cp);
 
 	if(JS_GetProperty(cx, hdr, "from", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 	} else
 		return(FALSE);	/* "from" property required */
@@ -251,7 +257,8 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 
 	/* Optional Header Fields */
 	if(JS_GetProperty(cx, hdr, "from_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, SENDEREXT, cp))!=SMB_SUCCESS)
 			return(FALSE);
@@ -260,7 +267,8 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 	}
 
 	if(JS_GetProperty(cx, hdr, "from_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, SENDERORG, cp))!=SMB_SUCCESS)
 			return(FALSE);
@@ -272,7 +280,8 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 	}
 
 	if(JS_GetProperty(cx, hdr, "from_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_netaddr(msg, SENDERNETADDR, cp, &nettype))!=SMB_SUCCESS)
 			return(FALSE);
@@ -293,49 +302,56 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 	}
 
 	if(JS_GetProperty(cx, hdr, "from_ip_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, SENDERIPADDR, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "from_host_name", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, SENDERHOSTNAME, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "from_protocol", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, SENDERPROTOCOL, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "from_port", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, SENDERPORT, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "replyto", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, REPLYTO, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "replyto_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, REPLYTOEXT, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "replyto_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, REPLYTOORG, cp))!=SMB_SUCCESS)
 			return(FALSE);
@@ -347,7 +363,8 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 		nettype=(ushort)i32;
 	}
 	if(JS_GetProperty(cx, hdr, "replyto_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_netaddr(msg, REPLYTONETADDR, cp, &nettype))!=SMB_SUCCESS)
 			return(FALSE);
@@ -366,14 +383,16 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 
 	/* RFC822 headers */
 	if(JS_GetProperty(cx, hdr, "id", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, RFC822MSGID, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "reply_id", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, RFC822REPLYID, cp))!=SMB_SUCCESS)
 			return(FALSE);
@@ -381,14 +400,16 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 
 	/* SMTP headers */
 	if(JS_GetProperty(cx, hdr, "reverse_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, SMTPREVERSEPATH, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "forward_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, SMTPFORWARDPATH, cp))!=SMB_SUCCESS)
 			return(FALSE);
@@ -396,14 +417,16 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 
 	/* USENET headers */
 	if(JS_GetProperty(cx, hdr, "path", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, USENETPATH, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "newsgroups", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, USENETNEWSGROUPS, cp))!=SMB_SUCCESS)
 			return(FALSE);
@@ -411,49 +434,56 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 
 	/* FTN headers */
 	if(JS_GetProperty(cx, hdr, "ftn_msgid", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, FIDOMSGID, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "ftn_reply", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, FIDOREPLYID, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "ftn_area", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, FIDOAREA, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "ftn_flags", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, FIDOFLAGS, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "ftn_pid", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, FIDOPID, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "ftn_tid", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		if((p->status=smb_hfield_str(msg, FIDOTID, cp))!=SMB_SUCCESS)
 			return(FALSE);
 	}
 
 	if(JS_GetProperty(cx, hdr, "date", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+		JSVALUE_TO_STRING(cx, val, cp);
+		if(cp==NULL)
 			return(FALSE);
 		msg->hdr.when_written=rfc822date(cp);
 	}
@@ -517,15 +547,18 @@ static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbm
 			field=JSVAL_TO_OBJECT(val);
 			if(!JS_GetProperty(cx, field, "type", &val))
 				continue;
-			if(JSVAL_IS_STRING(val))
-				type=smb_hfieldtypelookup(JS_GetStringBytes(JS_ValueToString(cx,val)));
+			if(JSVAL_IS_STRING(val)) {
+				JSVALUE_TO_STRING(cx, val, cp);
+				type=smb_hfieldtypelookup(cp);
+			}
 			else {
 				JS_ValueToInt32(cx,val,&i32);
 				type=(ushort)i32;
 			}
 			if(!JS_GetProperty(cx, field, "data", &val))
 				continue;
-			if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
+			JSVALUE_TO_STRING(cx, val, cp);
+			if(cp==NULL)
 				return(FALSE);
 			if((p->status=smb_hfield_str(msg, type, cp))!=SMB_SUCCESS)
 				return(FALSE);
@@ -747,7 +780,7 @@ static JSBool js_get_msg_header_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	/* If we have already enumerated, we're done here... */
@@ -1044,7 +1077,7 @@ js_get_msg_header(JSContext *cx, uintN argc, jsval *arglist)
 			JS_RESUMEREQUEST(cx, rc);
 			break;
 		} else if(JSVAL_IS_STRING(argv[n]))	{		/* Get by ID */
-			cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
+			JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(argv[n]), cstr);
 			rc=JS_SUSPENDREQUEST(cx);
 			if((p->p->status=smb_getmsghdr_by_msgid(&(p->p->smb),&(p->msg)
 					,cstr))!=SMB_SUCCESS) {
@@ -1123,7 +1156,7 @@ js_put_msg_header(JSContext *cx, uintN argc, jsval *arglist)
 			n++;
 			break;
 		} else if(JSVAL_IS_STRING(argv[n]))	{		/* Get by ID */
-			cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
+			JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(argv[n]), cstr);
 			rc=JS_SUSPENDREQUEST(cx);
 			if(!msg_offset_by_id(p
 					,cstr
@@ -1220,7 +1253,7 @@ js_remove_msg(JSContext *cx, uintN argc, jsval *arglist)
 			n++;
 			break;
 		} else if(JSVAL_IS_STRING(argv[n]))	{		/* Get by ID */
-			cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
+			JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(argv[n]), cstr);
 			rc=JS_SUSPENDREQUEST(cx);
 			if(!msg_offset_by_id(p
 					,cstr
@@ -1341,7 +1374,7 @@ js_get_msg_body(JSContext *cx, uintN argc, jsval *arglist)
 			n++;
 			break;
 		} else if(JSVAL_IS_STRING(argv[n]))	{		/* Get by ID */
-			cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
+			JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(argv[n]), cstr);
 			rc=JS_SUSPENDREQUEST(cx);
 			if(!msg_offset_by_id(p
 					,cstr
@@ -1423,7 +1456,7 @@ js_get_msg_tail(JSContext *cx, uintN argc, jsval *arglist)
 			n++;
 			break;
 		} else if(JSVAL_IS_STRING(argv[n]))	{		/* Get by ID */
-			cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
+			JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(argv[n]), cstr);
 			rc=JS_SUSPENDREQUEST(cx);
 			if(!msg_offset_by_id(p
 					,cstr
@@ -1518,10 +1551,12 @@ js_save_msg(JSContext *cx, uintN argc, jsval *arglist)
 				continue;
 			}
 		}
-		if(body==NULL 
-			&& (body=JS_GetStringBytes(JS_ValueToString(cx,argv[n])))==NULL) {
-			JS_ReportError(cx,"JS_GetStringBytes failed");
-			return(JS_FALSE);
+		if(body==NULL) {
+			JSVALUE_TO_STRING(cx, argv[n], body);
+			if(body==NULL) {
+				JS_ReportError(cx,"JSVALUE_TO_STRING failed");
+				return(JS_FALSE);
+			}
 		}
 	}
 
@@ -1887,7 +1922,7 @@ static JSBool js_msgbase_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_msgbase_properties, js_msgbase_functions, NULL, 0));
@@ -1934,7 +1969,7 @@ js_msgbase_constructor(JSContext *cx, uintN argc, jsval *arglist)
 	p->smb.retry_time=scfg->smb_retry_time;
 
 	js_str = JS_ValueToString(cx, argv[0]);
-	base=JS_GetStringBytes(js_str);
+	JSSTRING_TO_STRING(cx, js_str, base);
 
 	p->debug=JS_FALSE;
 
diff --git a/src/sbbs3/js_queue.c b/src/sbbs3/js_queue.c
index 7e07002ed14952bef43181059b34c9d563428331..82253ea275a165dfbe341e59af5c1913186ce6d9 100644
--- a/src/sbbs3/js_queue.c
+++ b/src/sbbs3/js_queue.c
@@ -167,6 +167,7 @@ js_read(JSContext *cx, uintN argc, jsval *arglist)
 	queued_value_t*	v;
 	int32 timeout=0;
 	jsrefcount	rc;
+	char	*p;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -177,7 +178,8 @@ js_read(JSContext *cx, uintN argc, jsval *arglist)
 
 	if(JSVAL_IS_STRING(argv[0])) {	/* value named specified */
 		ZERO_VAR(find_v);
-		SAFECOPY(find_v.name,JS_GetStringBytes(JS_ValueToString(cx,argv[0])));
+		JSVALUE_TO_STRING(cx, argv[0], p);
+		SAFECOPY(find_v.name,p);
 		rc=JS_SUSPENDREQUEST(cx);
 		v=msgQueueFind(q,&find_v,sizeof(find_v.name));
 		JS_RESUMEREQUEST(cx, rc);
@@ -241,6 +243,7 @@ static queued_value_t* js_encode_value(JSContext *cx, jsval val, char* name
     JSObject*	obj;
 	JSIdArray*	id_array;
 	queued_value_t* nv;
+	char		*p;
 
 	if((nv=realloc(v,((*count)+1)*sizeof(queued_value_t)))==NULL) {
 		if(v) free(v);
@@ -277,7 +280,7 @@ static queued_value_t* js_encode_value(JSContext *cx, jsval val, char* name
 				/* property name */
 				JS_IdToValue(cx,id_array->vector[i],&prop_name);
 				if(JSVAL_IS_STRING(prop_name)) {
-					name=JS_GetStringBytes(JSVAL_TO_STRING(prop_name));
+					JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(prop_name), name);
 					/* value */
 					JS_GetProperty(cx,obj,name,&prop_val);
 				} else {
@@ -298,7 +301,8 @@ static queued_value_t* js_encode_value(JSContext *cx, jsval val, char* name
 		nv->type = JSTYPE_VOID;
 	} else {
 		nv->type= JSTYPE_STRING;
-		nv->value.s = strdup(JS_GetStringBytes(JS_ValueToString(cx,val)));
+		JSVALUE_TO_STRING(cx, val, p);
+		nv->value.s = strdup(p);
 	}
 
 	return(v);
@@ -341,7 +345,7 @@ js_write(JSContext *cx, uintN argc, jsval *arglist)
 	val = argv[argn++];
 
 	if(argn < argc)
-		name=JS_GetStringBytes(JS_ValueToString(cx,argv[argn++]));
+		JSVALUE_TO_STRING(cx, argv[argn++], name);
 
 	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(js_enqueue_value(cx, q, val, name)));
 
@@ -450,7 +454,7 @@ static JSBool js_queue_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_queue_properties, js_queue_functions, NULL, 0));
@@ -500,7 +504,7 @@ js_queue_constructor(JSContext *cx, uintN argc, jsval *arglist)
 #endif
 
 	if(argn<argc && JSVAL_IS_STRING(argv[argn]))
-		name=JS_GetStringBytes(JS_ValueToString(cx,argv[argn++]));
+		JSVALUE_TO_STRING(cx, argv[argn++], name);
 
 	if(argn<argc && JSVAL_IS_NUMBER(argv[argn]))
 		JS_ValueToInt32(cx,argv[argn++],&flags);
diff --git a/src/sbbs3/js_server.c b/src/sbbs3/js_server.c
index 7c6c3c35e223ddf7427b64017d0725612ac9dc95..0545808fa8680e0f5cf25376cd119d994b4d4219 100644
--- a/src/sbbs3/js_server.c
+++ b/src/sbbs3/js_server.c
@@ -146,7 +146,7 @@ static JSBool js_server_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_server_properties, NULL, NULL, 0));
diff --git a/src/sbbs3/js_socket.c b/src/sbbs3/js_socket.c
index e0308da1decd850157821b3fac92ac08ff8f9579..ed043ab779b2704c6d7ee89571bf00894834cbb0 100644
--- a/src/sbbs3/js_socket.c
+++ b/src/sbbs3/js_socket.c
@@ -140,7 +140,7 @@ static ushort js_port(JSContext* cx, jsval val, int type)
 	}
 	if(JSVAL_IS_STRING(val)) {
 		str = JS_ValueToString(cx,val);
-		cp = JS_GetStringBytes(str);
+		JSSTRING_TO_STRING(cx, str, cp);
 		if(isdigit(*cp))
 			return((ushort)strtol(cp,NULL,0));
 		rc=JS_SUSPENDREQUEST(cx);
@@ -191,6 +191,7 @@ js_bind(JSContext *cx, uintN argc, jsval *arglist)
 	ushort		port=0;
 	SOCKADDR_IN	addr;
 	jsrefcount	rc;
+	char		*cstr;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -205,8 +206,10 @@ js_bind(JSContext *cx, uintN argc, jsval *arglist)
 	if(argc)
 		port = js_port(cx,argv[0],p->type);
 	addr.sin_port = htons(port);
-	if(argc>1 
-		&& (ip=inet_addr(JS_GetStringBytes(JS_ValueToString(cx,argv[1]))))!=INADDR_NONE)
+	if(argc > 1)
+		JSVALUE_TO_STRING(cx, argv[1], cstr);
+	if(argc>1 && cstr != NULL
+		&& (ip=inet_addr(cstr))!=INADDR_NONE)
 		addr.sin_addr.s_addr = ip;
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -333,10 +336,10 @@ js_connect(JSContext *cx, uintN argc, jsval *arglist)
 	}
 
 	str = JS_ValueToString(cx, argv[0]);
-	cstr = JS_GetStringBytes(str);
+	JSSTRING_TO_STRING(cx, str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	dbprintf(FALSE, p, "resolving hostname: %s", cstr);
-	if((ip_addr=resolve_ip(JS_GetStringBytes(str)))==INADDR_NONE) {
+	if((ip_addr=resolve_ip(cstr))==INADDR_NONE) {
 		p->last_error=ERROR_VALUE;
 		dbprintf(TRUE, p, "resolve_ip failed with error %d",ERROR_VALUE);
 		JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
@@ -353,7 +356,7 @@ js_connect(JSContext *cx, uintN argc, jsval *arglist)
 		js_timeval(cx,argv[2],&tv);
 
 	rc=JS_SUSPENDREQUEST(cx);
-	dbprintf(FALSE, p, "connecting to port %u at %s", port, JS_GetStringBytes(str));
+	dbprintf(FALSE, p, "connecting to port %u at %s", port, cstr);
 
 	memset(&(p->remote_addr),0,sizeof(p->remote_addr));
 	p->remote_addr.sin_addr.s_addr = ip_addr;
@@ -387,7 +390,7 @@ js_connect(JSContext *cx, uintN argc, jsval *arglist)
 
 	p->is_connected = TRUE;
 	JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
-	dbprintf(FALSE, p, "connected to port %u at %s", port, JS_GetStringBytes(str));
+	dbprintf(FALSE, p, "connected to port %u at %s", port, cstr);
 	JS_RESUMEREQUEST(cx, rc);
 
 	return(JS_TRUE);
@@ -414,7 +417,7 @@ js_send(JSContext *cx, uintN argc, jsval *arglist)
 	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 
 	str = JS_ValueToString(cx, argv[0]);
-	cp	= JS_GetStringBytes(str);
+	JSSTRING_TO_STRING(cx, str, cp);
 	len	= JS_GetStringLength(str);
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -457,14 +460,14 @@ js_sendto(JSContext *cx, uintN argc, jsval *arglist)
 
 	/* data */
 	data_str = JS_ValueToString(cx, argv[0]);
-	cp = JS_GetStringBytes(data_str);
+	JSSTRING_TO_STRING(cx, data_str, cp);
 	len = JS_GetStringLength(data_str);
 
 	/* address */
 	ip_str = JS_ValueToString(cx, argv[1]);
-	cstr = JS_GetStringBytes(ip_str);
+	JSSTRING_TO_STRING(cx, ip_str, cstr);
 	rc=JS_SUSPENDREQUEST(cx);
-	dbprintf(FALSE, p, "resolving hostname: %s", JS_GetStringBytes(ip_str));
+	dbprintf(FALSE, p, "resolving hostname: %s", cstr);
 	if((ip_addr=resolve_ip(cstr))==INADDR_NONE) {
 		p->last_error=ERROR_VALUE;
 		dbprintf(TRUE, p, "resolve_ip failed with error %d",ERROR_VALUE);
@@ -479,7 +482,7 @@ js_sendto(JSContext *cx, uintN argc, jsval *arglist)
 	rc=JS_SUSPENDREQUEST(cx);
 
 	dbprintf(FALSE, p, "sending %d bytes to port %u at %s"
-		,len, port, JS_GetStringBytes(ip_str));
+		,len, port, cstr);
 
 	memset(&addr,0,sizeof(addr));
 	addr.sin_addr.s_addr = ip_addr;
@@ -520,8 +523,8 @@ js_sendfile(JSContext *cx, uintN argc, jsval *arglist)
 
 	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
 
-	if((str = JS_ValueToString(cx, argv[0]))==NULL
-		|| (fname=JS_GetStringBytes(str))==NULL) {
+	JSVALUE_TO_STRING(cx, argv[0], fname);
+	if(fname==NULL) {
 		JS_ReportError(cx,"Failure reading filename");
 		return(JS_FALSE);
 	}
@@ -1017,6 +1020,7 @@ js_getsockopt(JSContext *cx, uintN argc, jsval *arglist)
 	void*		vp=&val;
 	socklen_t	len=sizeof(val);
 	jsrefcount	rc;
+	char		*cstr;
 
 	JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(-1));
 
@@ -1026,7 +1030,8 @@ js_getsockopt(JSContext *cx, uintN argc, jsval *arglist)
 	}
 
 	rc=JS_SUSPENDREQUEST(cx);
-	if((opt = getSocketOptionByName(JS_GetStringBytes(JS_ValueToString(cx,argv[0])),&level)) == -1) {
+	JSVALUE_TO_STRING(cx, argv[0], cstr);
+	if((opt = getSocketOptionByName(cstr, &level)) == -1) {
 		JS_RESUMEREQUEST(cx, rc);
 		return(JS_TRUE);
 	}
@@ -1067,6 +1072,7 @@ js_setsockopt(JSContext *cx, uintN argc, jsval *arglist)
 	void*		vp=&val;
 	socklen_t	len=sizeof(val);
 	jsrefcount	rc;
+	char		*optname;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -1075,8 +1081,9 @@ js_setsockopt(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_FALSE);
 	}
 
+	JSVALUE_TO_STRING(cx, argv[0], optname);
 	rc=JS_SUSPENDREQUEST(cx);
-	opt = getSocketOptionByName(JS_GetStringBytes(JS_ValueToString(cx,argv[0])),&level);
+	opt = getSocketOptionByName(optname,&level);
 	if(argv[1]!=JSVAL_VOID) {
 		JS_RESUMEREQUEST(cx, rc);
 		JS_ValueToInt32(cx,argv[1],&val);
@@ -1526,7 +1533,7 @@ static JSBool js_socket_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_socket_properties, js_socket_functions, NULL, 0));
@@ -1596,7 +1603,7 @@ js_socket_constructor(JSContext *cx, uintN argc, jsval *arglist)
 		if(JSVAL_IS_NUMBER(argv[i]))
 			JS_ValueToInt32(cx,argv[i],&type);
 		else if(protocol==NULL)
-			protocol=JS_GetStringBytes(JS_ValueToString(cx,argv[i]));
+			JSVALUE_TO_STRING(cx, argv[i], protocol);
 	}
 		
 	if((p=(private_t*)malloc(sizeof(private_t)))==NULL) {
diff --git a/src/sbbs3/js_sprintf.c b/src/sbbs3/js_sprintf.c
index c8cd433261d1f2a46e67a42735f5f0ca4206e187..e49feca48b6287dfd992fc53bb0b6ffb9e76e9dd 100644
--- a/src/sbbs3/js_sprintf.c
+++ b/src/sbbs3/js_sprintf.c
@@ -41,7 +41,7 @@
 char* DLLCALL
 js_sprintf(JSContext *cx, uint argn, uintN argc, jsval *argv)
 {
-	char*		p;
+	char*		p,*p2;
     JSString*	str;
 
 	if((p=js_ValueToStringBytes(cx, argv[argn++], NULL))==NULL)
@@ -56,9 +56,10 @@ js_sprintf(JSContext *cx, uint argn, uintN argc, jsval *argv)
 		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));
+			JSVALUE_TO_STRING(cx, argv[argn], p2);
+			if(p2==NULL)
+				return NULL;
+			p=xp_asprintf_next(p,XP_PRINTF_CONVERT|XP_PRINTF_TYPE_CHARP,p2);
 		}
 	}
 
diff --git a/src/sbbs3/js_system.c b/src/sbbs3/js_system.c
index f8f7b0b7c1b1f2a3006d3e29f38471c894021639..b78a20010d1ed7bde74bcf067adeaf504ebd4dcd 100644
--- a/src/sbbs3/js_system.c
+++ b/src/sbbs3/js_system.c
@@ -698,7 +698,7 @@ static JSBool js_sysstats_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_sysstats_properties, NULL, NULL, 0));
@@ -743,7 +743,8 @@ js_alias(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 	}
 
-	if((p=JS_GetStringBytes(js_str))==NULL) {
+	JSSTRING_TO_STRING(cx, js_str, p);
+	if(p==NULL) {
 		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
 		return(JS_TRUE);
 	}
@@ -813,7 +814,8 @@ js_matchuser(JSContext *cx, uintN argc, jsval *arglist)
 	if(argc>1)
 		JS_ValueToBoolean(cx,argv[1],&sysop_alias);
 
-	if((p=JS_GetStringBytes(js_str))==NULL) {
+	JSSTRING_TO_STRING(cx, js_str, p);
+	if(p==NULL) {
 		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
 		return(JS_TRUE);
 	}
@@ -862,8 +864,9 @@ js_matchuserdata(JSContext *cx, uintN argc, jsval *arglist)
 		JS_ValueToInt32(cx, argv[argnum++], &usernumber);
 	if(JSVAL_IS_BOOLEAN(argv[argnum]))
 		JS_ValueToBoolean(cx, argv[argnum], &match_next);
-		
-	if((p=JS_GetStringBytes(js_str))==NULL) {
+	
+	JSSTRING_TO_STRING(cx, js_str, p);
+	if(p==NULL) {
 		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
 		return(JS_TRUE);
 	}
@@ -901,12 +904,14 @@ js_trashcan(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 	}
 
-	if((can=JS_GetStringBytes(js_can))==NULL) {
+	JSSTRING_TO_STRING(cx, js_can, can);
+	if(can==NULL) {
 		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
 		return(JS_TRUE);
 	}
 
-	if((str=JS_GetStringBytes(js_str))==NULL) {
+	JSSTRING_TO_STRING(cx, js_str, str);
+	if(str==NULL) {
 		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
 		return(JS_TRUE);
 	}
@@ -938,12 +943,14 @@ js_findstr(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_TRUE);
 	}
 
-	if((fname=JS_GetStringBytes(js_fname))==NULL) {
+	JSSTRING_TO_STRING(cx, js_fname, fname);
+	if(fname==NULL) {
 		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
 		return(JS_TRUE);
 	}
 
-	if((str=JS_GetStringBytes(js_str))==NULL) {
+	JSSTRING_TO_STRING(cx, js_str, str);
+	if(str==NULL) {
 		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
 		return(JS_TRUE);
 	}
@@ -1031,6 +1038,7 @@ js_datestr(JSContext *cx, uintN argc, jsval *arglist)
 	time_t		t;
 	JSString*	js_str;
 	scfg_t*		cfg;
+	char		*p;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -1041,7 +1049,8 @@ js_datestr(JSContext *cx, uintN argc, jsval *arglist)
 		t=time(NULL);	/* use current time */
 	else {
 		if(JSVAL_IS_STRING(argv[0])) {	/* convert from string to time_t? */
-			JS_SET_RVAL(cx, arglist, DOUBLE_TO_JSVAL((double)dstrtounix(cfg,JS_GetStringBytes(JS_ValueToString(cx, argv[0])))));
+			JSVALUE_TO_STRING(cx, argv[0], p);
+			JS_SET_RVAL(cx, arglist, DOUBLE_TO_JSVAL((double)dstrtounix(cfg, p)));
 			return(JS_TRUE);
 		}
 		JS_ValueToInt32(cx,argv[0],(int32*)&t);
@@ -1102,7 +1111,7 @@ js_spamlog(JSContext *cx, uintN argc, jsval *arglist)
 	for(i=0;i<argc;i++) {
 		if(!JSVAL_IS_STRING(argv[i]))
 			continue;
-		p=JS_GetStringBytes(JS_ValueToString(cx, argv[i]));
+		JSVALUE_TO_STRING(cx, argv[i], p);
 		if(p==NULL)
 			continue;
 		if(prot==NULL)
@@ -1159,7 +1168,7 @@ js_hacklog(JSContext *cx, uintN argc, jsval *arglist)
 		}
 		if(!JSVAL_IS_STRING(argv[i]))
 			continue;
-		p=JS_GetStringBytes(JS_ValueToString(cx, argv[i]));
+		JSVALUE_TO_STRING(cx, argv[i], p);
 		if(p==NULL)
 			continue;
 		if(prot==NULL)
@@ -1201,7 +1210,7 @@ js_filter_ip(JSContext *cx, uintN argc, jsval *arglist)
 	for(i=0;i<argc;i++) {
 		if(!JSVAL_IS_STRING(argv[i]))
 			continue;
-		p=JS_GetStringBytes(JS_ValueToString(cx, argv[i]));
+		JSVALUE_TO_STRING(cx, argv[i], p);
 		if(p==NULL)
 			continue;
 		if(prot==NULL)
@@ -1283,7 +1292,8 @@ js_put_node_message(JSContext *cx, uintN argc, jsval *arglist)
 	if((js_msg=JS_ValueToString(cx, argv[1]))==NULL) 
 		return(JS_FALSE);
 
-	if((msg=JS_GetStringBytes(js_msg))==NULL) 
+	JSSTRING_TO_STRING(cx, js_msg, msg);
+	if(msg==NULL) 
 		return(JS_FALSE);
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -1351,7 +1361,8 @@ js_put_telegram(JSContext *cx, uintN argc, jsval *arglist)
 	if((js_msg=JS_ValueToString(cx, argv[1]))==NULL) 
 		return(JS_FALSE);
 
-	if((msg=JS_GetStringBytes(js_msg))==NULL) 
+	JSSTRING_TO_STRING(cx, js_msg, msg);
+	if(msg==NULL) 
 		return(JS_FALSE);
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -1380,7 +1391,7 @@ js_new_user(JSContext *cx, uintN argc, jsval *arglist)
 	if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
 		return(JS_FALSE);
 
-	alias=JS_GetStringBytes(JS_ValueToString(cx,argv[0]));
+	JSVALUE_TO_STRING(cx, argv[0], alias);
 
 	rc=JS_SUSPENDREQUEST(cx);
 	if(!check_name(cfg,alias)) {
@@ -1464,9 +1475,11 @@ js_exec(JSContext *cx, uintN argc, jsval *arglist)
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
 	jsrefcount	rc;
+	char	*cmd;
 
+	JSVALUE_TO_STRING(cx, argv[0], cmd);
 	rc=JS_SUSPENDREQUEST(cx);
-	JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(system(JS_GetStringBytes(JS_ValueToString(cx, argv[0])))));
+	JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(system(cmd)));
 	JS_RESUMEREQUEST(cx, rc);
 	
 	return(JS_TRUE);
@@ -1494,7 +1507,7 @@ js_popen(JSContext *cx, uintN argc, jsval *arglist)
 	if((array=JS_NewArrayObject(cx,0,NULL))==NULL)
 		return(JS_FALSE);
 
-	cmd=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+	JSVALUE_TO_STRING(cx, argv[0], cmd);
 	rc=JS_SUSPENDREQUEST(cx);
 	if((fp=popen(cmd,"r"))==NULL) {
 		JS_RESUMEREQUEST(cx, rc);
@@ -1529,15 +1542,16 @@ js_chksyspass(JSContext *cx, uintN argc, jsval *arglist)
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
 	scfg_t*		cfg;
+	char		*pass;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
 	if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
 		return(JS_FALSE);
 
-	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(stricmp(JS_GetStringBytes(JS_ValueToString(cx, argv[0]))
-								,cfg->sys_pass)==0));
-	
+	JSVALUE_TO_STRING(cx, argv[0], pass);
+	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(stricmp(pass,cfg->sys_pass)==0));
+
 	return(JS_TRUE);
 }
 
@@ -1552,7 +1566,7 @@ js_chkname(JSContext *cx, uintN argc, jsval *arglist)
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
-	str = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+	JSVALUE_TO_STRING(cx, argv[0], str);
 	if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
 		return(JS_FALSE);
 
@@ -1914,7 +1928,7 @@ static JSBool js_node_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_node_properties, NULL, NULL, 0));
@@ -1989,7 +2003,7 @@ static JSBool js_system_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	/****************************/
diff --git a/src/sbbs3/js_uifc.c b/src/sbbs3/js_uifc.c
index a12204428d452d08a863fcd074586fcd3d27648f..bc229a0f4e1a73e9c6976db64602a43755afe00f 100644
--- a/src/sbbs3/js_uifc.c
+++ b/src/sbbs3/js_uifc.c
@@ -534,7 +534,7 @@ static JSBool js_uifc_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_properties, js_functions, NULL, 0));
diff --git a/src/sbbs3/js_user.c b/src/sbbs3/js_user.c
index edaa96add6ed8445256d1dae57931b604a924efd..d8a65633c07b20e0dfca87e5f1779292eed1287a 100644
--- a/src/sbbs3/js_user.c
+++ b/src/sbbs3/js_user.c
@@ -420,10 +420,8 @@ static JSBool js_user_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
 	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
 		return(JS_TRUE);
 
-	if((js_str=JS_ValueToString(cx,*vp))==NULL)
-		return(JS_FALSE);
-
-	if((str=JS_GetStringBytes(js_str))==NULL)
+	JSVALUE_TO_STRING(cx, *vp, str);
+	if(str==NULL)
 		return(JS_FALSE);
 
     JS_IdToValue(cx, id, &idval);
@@ -891,17 +889,19 @@ js_chk_ar(JSContext *cx, uintN argc, jsval *arglist)
 	JSString*	js_str;
 	private_t*	p;
 	jsrefcount	rc;
+	char		*ars;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
 	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
 		return JS_FALSE;
 
-	if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
+	JSVALUE_TO_STRING(cx,argv[0], ars);
+	if(arstr==NULL)
 		return JS_FALSE;
 
 	rc=JS_SUSPENDREQUEST(cx);
-	ar = arstr(NULL,JS_GetStringBytes(js_str),p->cfg);
+	ar = arstr(NULL,ars,p->cfg);
 
 	js_getuserdat(p);
 
@@ -1152,7 +1152,7 @@ static JSBool js_user_stats_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_user_stats_properties, NULL, NULL, 0));
@@ -1171,7 +1171,7 @@ static JSBool js_user_security_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_user_security_properties, NULL, NULL, 0));
@@ -1190,7 +1190,7 @@ static JSBool js_user_limits_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	return(js_SyncResolve(cx, obj, name, js_user_limits_properties, NULL, NULL, 0));
@@ -1253,7 +1253,7 @@ static JSBool js_user_resolve(JSContext *cx, JSObject *obj, jsid id)
 		jsval idval;
 		
 		JS_IdToValue(cx, id, &idval);
-		name=JS_GetStringBytes(JSVAL_TO_STRING(idval));
+		JSSTRING_TO_STRING(cx, JSVAL_TO_STRING(idval), name);
 	}
 
 	if(name==NULL || strcmp(name, "stats")==0) {
diff --git a/src/sbbs3/jsexec.c b/src/sbbs3/jsexec.c
index 0277863234825a576b18db9781d6d9225a496a5c..cc641a7493294ea2743361525e410d4a238553b5 100644
--- a/src/sbbs3/jsexec.c
+++ b/src/sbbs3/jsexec.c
@@ -294,6 +294,7 @@ js_log(JSContext *cx, uintN argc, jsval *arglist)
 	int32		level=LOG_INFO;
     JSString*	str=NULL;
 	jsrefcount	rc;
+	char		*logstr;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -303,12 +304,15 @@ js_log(JSContext *cx, uintN argc, jsval *arglist)
 	for(; i<argc; i++) {
 		if((str=JS_ValueToString(cx, argv[i]))==NULL)
 			return(JS_FALSE);
+		JSSTRING_TO_STRING(cx, str, logstr);
+		if(logstr==NULL)
+			return(JS_FALSE);
 		rc=JS_SUSPENDREQUEST(cx);
-		lprintf(level,"%s",JS_GetStringBytes(str));
+		lprintf(level,"%s",logstr);
 		JS_RESUMEREQUEST(cx, rc);
 	}
 
-	if(str==NULL)
+	if(logstr==NULL)
 		JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 	else
 		JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(str));
@@ -379,14 +383,18 @@ js_write(JSContext *cx, uintN argc, jsval *arglist)
     uintN		i;
     JSString*	str=NULL;
 	jsrefcount	rc;
+	char		*line;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
     for (i = 0; i < argc; i++) {
-		if((str=JS_ValueToString(cx, argv[i]))==NULL)
+		if((str=JS_ValueToString(cx, argv[0]))==NULL)
 		    return(JS_FALSE);
+		JSSTRING_TO_STRING(cx, str, line);
+		if(line==NULL)
+			return(JS_FALSE);
 		rc=JS_SUSPENDREQUEST(cx);
-		fprintf(confp,"%s",JS_GetStringBytes(str));
+		fprintf(confp,"%s",line);
 		JS_RESUMEREQUEST(cx, rc);
 	}
 
@@ -448,14 +456,16 @@ js_alert(JSContext *cx, uintN argc, jsval *arglist)
 	jsval *argv=JS_ARGV(cx, arglist);
     JSString *	str;
 	jsrefcount	rc;
+	char		*line;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
-	if((str=JS_ValueToString(cx, argv[0]))==NULL)
+	JSVALUE_TO_STRING(cx, argv[0], line);
+	if(line==NULL)
 	    return(JS_FALSE);
 
 	rc=JS_SUSPENDREQUEST(cx);
-	fprintf(confp,"!%s\n",JS_GetStringBytes(str));
+	fprintf(confp,"!%s\n",line);
 	JS_RESUMEREQUEST(cx, rc);
 
 	JS_SET_RVAL(cx, arglist, argv[0]);
@@ -479,7 +489,7 @@ js_confirm(JSContext *cx, uintN argc, jsval *arglist)
 	if((str=JS_ValueToString(cx, argv[0]))==NULL)
 	    return(JS_FALSE);
 
-	cstr = JS_GetStringBytes(str);
+	JSSTRING_TO_STRING(cx, str, cstr);
 	printf("%s (Y/n)? ", cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	fgets(instr,sizeof(instr),stdin);
@@ -507,7 +517,7 @@ js_deny(JSContext *cx, uintN argc, jsval *arglist)
 	if((str=JS_ValueToString(cx, argv[0]))==NULL)
 	    return(JS_FALSE);
 
-	cstr = JS_GetStringBytes(str);
+	JSSTRING_TO_STRING(cx, str, cstr);
 	printf("%s (N/y)? ", cstr);
 	rc=JS_SUSPENDREQUEST(cx);
 	fgets(instr,sizeof(instr),stdin);
@@ -528,21 +538,24 @@ js_prompt(JSContext *cx, uintN argc, jsval *arglist)
     JSString *	prompt;
     JSString *	str;
 	jsrefcount	rc;
+	char		*prstr;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
 	if(!JSVAL_IS_VOID(argv[0])) {
-		if((prompt=JS_ValueToString(cx, argv[0]))==NULL)
+		JSVALUE_TO_STRING(cx, argv[0], prstr);
+		if(prompt==NULL)
 			return(JS_FALSE);
 		rc=JS_SUSPENDREQUEST(cx);
-		fprintf(confp,"%s: ",JS_GetStringBytes(prompt));
+		fprintf(confp,"%s: ",prstr);
 		JS_RESUMEREQUEST(cx, rc);
 	}
 
 	if(argc>1) {
-		if((str=JS_ValueToString(cx, argv[1]))==NULL)
+		JSVALUE_TO_STRING(cx, argv[1], prstr);
+		if(str==NULL)
 		    return(JS_FALSE);
-		SAFECOPY(instr,JS_GetStringBytes(str));
+		SAFECOPY(instr,prstr);
 	} else
 		instr[0]=0;
 
@@ -568,7 +581,8 @@ js_chdir(JSContext *cx, uintN argc, jsval *arglist)
 	char*		p;
 	jsrefcount	rc;
 
-	if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
+	JSVALUE_TO_STRING(cx, argv[0], p);
+	if(p==NULL) {
 		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(-1));
 		return(JS_TRUE);
 	}
@@ -586,7 +600,8 @@ js_putenv(JSContext *cx, uintN argc, jsval *arglist)
 	jsval *argv=JS_ARGV(cx, arglist);
 	char*		p;
 
-	if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
+	JSVALUE_TO_STRING(cx, argv[0], p);
+	if(p==NULL) {
 		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(-1));
 		return(JS_TRUE);
 	}
@@ -905,7 +920,10 @@ long js_exec(const char *fname, char** args)
 	JS_ExecuteScript(js_cx, js_glob, js_script, &rval);
 	JS_GetProperty(js_cx, js_glob, "exit_code", &rval);
 	if(rval!=JSVAL_VOID && JSVAL_IS_NUMBER(rval)) {
-		mfprintf(statfp,"Using JavaScript exit_code: %s",JS_GetStringBytes_dumbass(js_cx, JS_ValueToString(js_cx,rval)));
+		char	*p;
+
+		JSVALUE_TO_STRING(js_cx, rval, p);
+		mfprintf(statfp,"Using JavaScript exit_code: %s",p);
 		JS_ValueToInt32(js_cx,rval,&result);
 	}
 	js_EvalOnExit(js_cx, js_glob, &branch);
diff --git a/src/sbbs3/mailsrvr.c b/src/sbbs3/mailsrvr.c
index 59fe05ab77e58262ae3560d6d35ff3d9cc5fa72e..768eeb313815125e8d2b63bdcefa991e43793163 100644
--- a/src/sbbs3/mailsrvr.c
+++ b/src/sbbs3/mailsrvr.c
@@ -1693,6 +1693,7 @@ js_log(JSContext *cx, uintN argc, jsval *arglist)
     JSString*	str=NULL;
 	private_t*	p;
 	jsrefcount	rc;
+	char		*lstr;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -1703,11 +1704,12 @@ js_log(JSContext *cx, uintN argc, jsval *arglist)
 		JS_ValueToInt32(cx,argv[i++],&level);
 
 	for(; i<argc; i++) {
-		if((str=JS_ValueToString(cx, argv[i]))==NULL)
+		JSVALUE_TO_STRING(cx, argv[i], lstr);
+		if(lstr==NULL)
 			return(JS_FALSE);
 		rc=JS_SUSPENDREQUEST(cx);
 		lprintf(level,"%04d %s %s %s"
-			,p->sock,p->log_prefix,p->proc_name,JS_GetStringBytes(str));
+			,p->sock,p->log_prefix,p->proc_name,lstr);
 		JS_RESUMEREQUEST(cx, rc);
 	}
 
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 611bc75c727121f8ce6b56b603a1896450442cce..e0629f5ea8d920fb41af182e1105e2f58a7651c0 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -643,6 +643,7 @@ char*
 DLLCALL js_ValueToStringBytes(JSContext* cx, jsval val, size_t* len)
 {
 	JSString* str;
+	char	*leak;
 	
 	if((str=JS_ValueToString(cx, val))==NULL)
 		return(NULL);
@@ -650,7 +651,8 @@ DLLCALL js_ValueToStringBytes(JSContext* cx, jsval val, size_t* len)
 	if(len!=NULL)
 		*len = JS_GetStringLength(str);
 
-	return(JS_GetStringBytes(str));
+	JSSTRING_TO_STRING(cx, str, leak);
+	return(strdup(leak));
 }
 
 static JSBool
@@ -663,6 +665,7 @@ js_log(JSContext *cx, uintN argc, jsval *arglist)
     JSString*	str=NULL;
 	sbbs_t*		sbbs;
 	jsrefcount	rc;
+	char		*line;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -673,16 +676,18 @@ js_log(JSContext *cx, uintN argc, jsval *arglist)
 		JS_ValueToInt32(cx,argv[i++],&level);
 
     for(; i<argc; i++) {
-		if((str=JS_ValueToString(cx, argv[i]))==NULL) {
+		JSVALUE_TO_STRING(cx, argv[i], line);
+		if(line==NULL) {
 			JS_RESUMEREQUEST(cx, rc);
 		    return(JS_FALSE);
 		}
 		rc=JS_SUSPENDREQUEST(cx);
 		if(sbbs->online==ON_LOCAL) {
-			if(startup!=NULL && startup->event_lputs!=NULL && level <= startup->log_level)
-				startup->event_lputs(startup->event_cbdata,level,JS_GetStringBytes(str));
+			if(startup!=NULL && startup->event_lputs!=NULL && level <= startup->log_level) {
+				startup->event_lputs(startup->event_cbdata,level,line);
+			}
 		} else
-			lprintf(level,"Node %d %s", sbbs->cfg.node_num, JS_GetStringBytes(str));
+			lprintf(level,"Node %d %s", sbbs->cfg.node_num, line);
 		JS_RESUMEREQUEST(cx, rc);
 	}
 
@@ -766,6 +771,7 @@ js_write(JSContext *cx, uintN argc, jsval *arglist)
     JSString*	str=NULL;
 	sbbs_t*		sbbs;
 	jsrefcount	rc;
+	char		*cstr;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -773,13 +779,14 @@ js_write(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_FALSE);
 
     for (i = 0; i < argc; i++) {
-		if((str=JS_ValueToString(cx, argv[i]))==NULL)
+		JSVALUE_TO_STRING(cx, argv[i], cstr);
+		if(cstr==NULL)
 		    return(JS_FALSE);
 		rc=JS_SUSPENDREQUEST(cx);
 		if(sbbs->online==ON_LOCAL)
-			eprintf(LOG_INFO,"%s",JS_GetStringBytes(str));
+			eprintf(LOG_INFO,"%s",cstr);
 		else
-			sbbs->bputs(JS_GetStringBytes(str));
+			sbbs->bputs(cstr);
 		JS_RESUMEREQUEST(cx, rc);
 	}
 
@@ -880,18 +887,20 @@ js_alert(JSContext *cx, uintN argc, jsval *arglist)
     JSString *	str;
 	sbbs_t*		sbbs;
 	jsrefcount	rc;
+	char		*cstr;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
 	if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
 		return(JS_FALSE);
 
-	if((str=JS_ValueToString(cx, argv[0]))==NULL)
+	JSVALUE_TO_STRING(cx, argv[0], cstr);
+	if(cstr==NULL)
 	    return(JS_FALSE);
 
 	rc=JS_SUSPENDREQUEST(cx);
 	sbbs->attr(sbbs->cfg.color[clr_err]);
-	sbbs->bputs(JS_GetStringBytes(str));
+	sbbs->bputs(cstr);
 	sbbs->attr(LIGHTGRAY);
 	sbbs->bputs(crlf);
 	JS_RESUMEREQUEST(cx, rc);
@@ -907,17 +916,16 @@ js_confirm(JSContext *cx, uintN argc, jsval *arglist)
     JSString *	str;
 	sbbs_t*		sbbs;
 	jsrefcount	rc;
+	char		*cstr;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
-	if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
-		return(JS_FALSE);
-
-	if((str=JS_ValueToString(cx, argv[0]))==NULL)
+	JSVALUE_TO_STRING(cx, argv[0], cstr);
+	if(cstr==NULL)
 	    return(JS_FALSE);
 
 	rc=JS_SUSPENDREQUEST(cx);
-	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->yesno(JS_GetStringBytes(str))));
+	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->yesno(cstr)));
 	JS_RESUMEREQUEST(cx, rc);
 	return(JS_TRUE);
 }
@@ -930,17 +938,19 @@ js_deny(JSContext *cx, uintN argc, jsval *arglist)
     JSString *	str;
 	sbbs_t*		sbbs;
 	jsrefcount	rc;
+	char		*cstr;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
 	if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
 		return(JS_FALSE);
 
-	if((str=JS_ValueToString(cx, argv[0]))==NULL)
+	JSVALUE_TO_STRING(cx, argv[0], cstr);
+	if(cstr==NULL)
 	    return(JS_FALSE);
 
 	rc=JS_SUSPENDREQUEST(cx);
-	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->noyes(JS_GetStringBytes(str))));
+	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->noyes(cstr)));
 	JS_RESUMEREQUEST(cx, rc);
 	return(JS_TRUE);
 }
@@ -952,28 +962,31 @@ js_prompt(JSContext *cx, uintN argc, jsval *arglist)
 	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
 	jsval *argv=JS_ARGV(cx, arglist);
 	char		instr[81];
-    JSString *	prompt;
     JSString *	str;
 	sbbs_t*		sbbs;
 	jsrefcount	rc;
+	char		*cstr;
+    char 		*prompt;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
 	if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
 		return(JS_FALSE);
 
-	if((prompt=JS_ValueToString(cx, argv[0]))==NULL)
+	JSVALUE_TO_STRING(cx, argv[0], prompt);
+	if(prompt==NULL)
 	    return(JS_FALSE);
 
 	if(argc>1) {
-		if((str=JS_ValueToString(cx, argv[1]))==NULL)
+		JSVALUE_TO_STRING(cx, argv[1], cstr);
+		if(cstr==NULL)
 		    return(JS_FALSE);
-		SAFECOPY(instr,JS_GetStringBytes(str));
+		SAFECOPY(instr,cstr);
 	} else
 		instr[0]=0;
 
 	rc=JS_SUSPENDREQUEST(cx);
-	sbbs->bprintf("\1n\1y\1h%s\1w: ",JS_GetStringBytes(prompt));
+	sbbs->bprintf("\1n\1y\1h%s\1w: ",prompt);
 
 	if(!sbbs->getstr(instr,sizeof(instr)-1,K_EDIT)) {
 		JS_SET_RVAL(cx, arglist, JSVAL_NULL);
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index 07cbfe691932fbb3f221e2e00719ac9c06192730..20708f0f0046f67a79ac09370bb553ad475f605c 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -1073,8 +1073,6 @@ extern "C" {
 	DLLEXPORT void		DLLCALL js_EvalOnExit(JSContext*, JSObject*, js_branch_t*);
 	DLLEXPORT void		DLLCALL	js_PrepareToExecute(JSContext*, JSObject*, const char *filename, const char* startup_dir);
 	DLLEXPORT char*		DLLCALL js_getstring(JSContext *cx, JSString *str);
-	DLLEXPORT char*		DLLCALL JS_GetStringBytes_dumbass(JSContext *cx, JSString *str);
-	#define JS_GetStringBytes(str)	JS_GetStringBytes_dumbass(cx, str)
 
 	/* js_system.c */
 	DLLEXPORT JSObject* DLLCALL js_CreateSystemObject(JSContext* cx, JSObject* parent
diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c
index 72d97f74b58a7a0246c291539965ac5f5d7fb2e3..d0c84c7f4ddf9046f6d6f08b2f5287f0896b5339 100644
--- a/src/sbbs3/services.c
+++ b/src/sbbs3/services.c
@@ -372,9 +372,8 @@ js_write(JSContext *cx, uintN argc, jsval *arglist)
 	JS_SET_RVAL(cx, arglist, argv[0]);
 
 	for(i=0; i<argc; i++) {
-		if((str=JS_ValueToString(cx, argv[i]))==NULL)
-			continue;
-		if((cp=JS_GetStringBytes(str))==NULL)
+		JSVALUE_TO_STRING(cx, argv[i], cp);
+		if(cp==NULL)
 			continue;
 		rc=JS_SUSPENDREQUEST(cx);
 		sendsocket(client->socket,cp,strlen(cp));
@@ -419,6 +418,7 @@ js_log(JSContext *cx, uintN argc, jsval *arglist)
     JSString*	js_str;
 	service_client_t* client;
 	jsrefcount	rc;
+	char		*line;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -433,9 +433,10 @@ js_log(JSContext *cx, uintN argc, jsval *arglist)
 
 	str[0]=0;
     for(;i<argc && strlen(str)<(sizeof(str)/2);i++) {
-		if((js_str=JS_ValueToString(cx, argv[i]))==NULL)
+		JSVALUE_TO_STRING(cx, argv[i], line);
+		if(line==NULL)
 		    return(JS_FALSE);
-		strncat(str,JS_GetStringBytes(js_str),sizeof(str)/2);
+		strncat(str,line,sizeof(str)/2);
 		strcat(str," ");
 	}
 
@@ -691,6 +692,7 @@ js_client_add(JSContext *cx, uintN argc, jsval *arglist)
 	SOCKADDR_IN	addr;
 	service_client_t* service_client;
 	jsrefcount	rc;
+	char		*cstr;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -716,11 +718,15 @@ js_client_add(JSContext *cx, uintN argc, jsval *arglist)
 		client.port=ntohs(addr.sin_port);
 	}
 
-	if(argc>1)
-		client.user=JS_GetStringBytes(JS_ValueToString(cx,argv[1]));
+	if(argc>1) {
+		JSVALUE_TO_STRING(cx, argv[1], cstr);
+		client.user=cstr;
+	}
 
-	if(argc>2)
-		SAFECOPY(client.host,JS_GetStringBytes(JS_ValueToString(cx,argv[2])));
+	if(argc>2) {
+		JSVALUE_TO_STRING(cx, argv[2], cstr);
+		SAFECOPY(client.host,cstr);
+	}
 
 	rc=JS_SUSPENDREQUEST(cx);
 	client_on(sock, &client, /* update? */ FALSE);
@@ -744,6 +750,7 @@ js_client_update(JSContext *cx, uintN argc, jsval *arglist)
 	SOCKADDR_IN	addr;
 	service_client_t* service_client;
 	jsrefcount	rc;
+	char		*cstr;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -764,11 +771,15 @@ js_client_update(JSContext *cx, uintN argc, jsval *arglist)
 		client.port=ntohs(addr.sin_port);
 	}
 
-	if(argc>1)
-		client.user=JS_GetStringBytes(JS_ValueToString(cx,argv[1]));
+	if(argc>1) {
+		JSVALUE_TO_STRING(cx, argv[1], cstr);
+		client.user=cstr;
+	}
 
-	if(argc>2)
-		SAFECOPY(client.host,JS_GetStringBytes(JS_ValueToString(cx,argv[2])));
+	if(argc>2) {
+		JSVALUE_TO_STRING(cx, argv[2], cstr);
+		SAFECOPY(client.host,cstr);
+	}
 
 	rc=JS_SUSPENDREQUEST(cx);
 	client_on(sock, &client, /* update? */ TRUE);
diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c
index c26d78fcbb5a2124c0fb71b548227e91484b5b7a..186e5c938045f5ec04d2d8b1913f849d775c73cf 100644
--- a/src/sbbs3/websrvr.c
+++ b/src/sbbs3/websrvr.c
@@ -3965,6 +3965,8 @@ js_writefunc(JSContext *cx, uintN argc, jsval *arglist, BOOL writeln)
     JSString*	str=NULL;
 	http_session_t* session;
 	jsrefcount	rc;
+	char		*cstr;
+	size_t		len;
 
 	if((session=(http_session_t*)JS_GetContextPrivate(cx))==NULL)
 		return(JS_FALSE);
@@ -4006,10 +4008,10 @@ js_writefunc(JSContext *cx, uintN argc, jsval *arglist, BOOL writeln)
     for(i=0; i<argc; i++) {
 		if((str=JS_ValueToString(cx, argv[i]))==NULL)
 			continue;
-		if(JS_GetStringLength(str)<1 && !writeln)
-			continue;
+		len=JS_GetStringLength(str);
+		JSSTRING_TO_STRING(cx, str, cstr);
 		rc=JS_SUSPENDREQUEST(cx);
-		js_writebuf(session,JS_GetStringBytes(str), JS_GetStringLength(str));
+		js_writebuf(session, cstr, len);
 		if(writeln)
 			js_writebuf(session, newline, 2);
 		JS_RESUMEREQUEST(cx, rc);
@@ -4119,6 +4121,7 @@ js_log(JSContext *cx, uintN argc, jsval *arglist)
     JSString*	js_str;
 	http_session_t* session;
 	jsrefcount	rc;
+	char		*val;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
 
@@ -4133,9 +4136,10 @@ js_log(JSContext *cx, uintN argc, jsval *arglist)
 
 	str[0]=0;
     for(;i<argc && strlen(str)<(sizeof(str)/2);i++) {
-		if((js_str=JS_ValueToString(cx, argv[i]))==NULL)
+		JSVALUE_TO_STRING(cx, argv[i], val);
+		if(val==NULL)
 		    return(JS_FALSE);
-		strncat(str,JS_GetStringBytes(js_str),sizeof(str)/2);
+		strncat(str,val,sizeof(str)/2);
 		strcat(str," ");
 	}
 
@@ -4166,10 +4170,8 @@ js_login(JSContext *cx, uintN argc, jsval *arglist)
 		return(JS_FALSE);
 
 	/* User name */
-	if((js_str=JS_ValueToString(cx, argv[0]))==NULL) 
-		return(JS_FALSE);
-
-	if((p=JS_GetStringBytes(js_str))==NULL) 
+	JSVALUE_TO_STRING(cx, argv[0], p);
+	if(p==NULL) 
 		return(JS_FALSE);
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -4198,10 +4200,8 @@ js_login(JSContext *cx, uintN argc, jsval *arglist)
 	JS_RESUMEREQUEST(cx, rc);
 	/* Password */
 	if(user.pass[0]) {
-		if((js_str=JS_ValueToString(cx, argv[1]))==NULL) 
-			return(JS_FALSE);
-
-		if((p=JS_GetStringBytes(js_str))==NULL) 
+		JSVALUE_TO_STRING(cx, argv[1], p);
+		if(p==NULL) 
 			return(JS_FALSE);
 
 		if(stricmp(user.pass,p)) { /* Wrong password */
@@ -4575,22 +4575,24 @@ static BOOL ssjs_send_headers(http_session_t* session,int chunked)
 	int			i;
 	JSString*	js_str;
 	char		str[MAX_REQUEST_LINE+1];
+	char		*p,*p2;
 
 	JS_BEGINREQUEST(session->js_cx);
 	JS_GetProperty(session->js_cx,session->js_glob,"http_reply",&val);
 	reply = JSVAL_TO_OBJECT(val);
 	JS_GetProperty(session->js_cx,reply,"status",&val);
-	SAFECOPY(session->req.status,JS_GetStringBytes_dumbass(session->js_cx, JSVAL_TO_STRING(val)));
+	JSVALUE_TO_STRING(session->js_cx, val, p);
+	SAFECOPY(session->req.status,p);
 	JS_GetProperty(session->js_cx,reply,"header",&val);
 	headers = JSVAL_TO_OBJECT(val);
 	heads=JS_Enumerate(session->js_cx,headers);
 	if(heads != NULL) {
 		for(i=0;i<heads->length;i++)  {
 			JS_IdToValue(session->js_cx,heads->vector[i],&val);
-			js_str=JSVAL_TO_STRING(val);
-			JS_GetProperty(session->js_cx,headers,JS_GetStringBytes_dumbass(session->js_cx, js_str),&val);
-			safe_snprintf(str,sizeof(str),"%s: %s"
-				,JS_GetStringBytes_dumbass(session->js_cx, js_str),JS_GetStringBytes_dumbass(session->js_cx, JSVAL_TO_STRING(val)));
+			JSVALUE_TO_STRING(session->js_cx, val, p);
+			JS_GetProperty(session->js_cx,headers,p,&val);
+			JSVALUE_TO_STRING(session->js_cx, val, p2);
+			safe_snprintf(str,sizeof(str),"%s: %s",p,p2);
 			strListPush(&session->req.dynamic_heads,str);
 		}
 		JS_ClearScope(session->js_cx, headers);