From 399aea6dae5207c7c47513ebb77d056aae1baae7 Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Sat, 10 Mar 2018 03:20:06 +0000
Subject: [PATCH] Resolve memory leaks found by clang scan-build (mostly, or
 all, in error conditions) - e.g. if a malloc or realloc failed, then some
 other allocated memory would be leaked.

---
 src/sbbs3/bat_xfer.cpp    |  5 ++++-
 src/sbbs3/getmail.c       |  6 ++++--
 src/sbbs3/js_bbs.cpp      |  7 ++++++-
 src/sbbs3/js_global.c     |  5 +++++
 src/sbbs3/js_msgbase.c    | 18 +++++++++++++-----
 src/sbbs3/js_system.c     |  1 +
 src/sbbs3/sbbs.h          |  2 +-
 src/sbbs3/sbbsecho.c      | 13 +++++++++----
 src/sbbs3/scfg/scfgxfr2.c |  2 ++
 src/sbbs3/scfg/scfgxtrn.c |  4 ++++
 10 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/src/sbbs3/bat_xfer.cpp b/src/sbbs3/bat_xfer.cpp
index da78692bf3..da1bdc18c4 100644
--- a/src/sbbs3/bat_xfer.cpp
+++ b/src/sbbs3/bat_xfer.cpp
@@ -439,10 +439,13 @@ BOOL sbbs_t::start_batch_download()
 			list_len=0;
 		else
 			list_len=strlen(list)+1;	/* add one for ' ' */
-		if((list=(char*)realloc(list,list_len+strlen(path)+1	/* add one for '\0'*/))==NULL) {
+		char* np;
+		if((np=(char*)realloc(list,list_len+strlen(path)+1	/* add one for '\0'*/))==NULL) {
+			free(list);
 			errormsg(WHERE,ERR_ALLOC,"list",list_len+strlen(path));
 			return(FALSE);
 		}
+		list = np;
 		if(!list_len)
 			strcpy(list,path);
 		else {
diff --git a/src/sbbs3/getmail.c b/src/sbbs3/getmail.c
index 2a9fb5671b..da8cae90fd 100644
--- a/src/sbbs3/getmail.c
+++ b/src/sbbs3/getmail.c
@@ -161,11 +161,13 @@ mail_t* DLLCALL loadmail(smb_t* smb, uint32_t* msgs, uint usernumber
 			continue;
 		if(mode&LM_SPAMONLY && !(idx.attr&MSG_SPAM))
 			continue;
-		if((mail=(mail_t *)realloc(mail,sizeof(mail_t)*(l+1)))
-			==NULL) {
+		mail_t* np;
+		if((np = realloc(mail, sizeof(mail_t) * (l+1))) == NULL) {
+			free(mail);
 			smb_unlocksmbhdr(smb);
 			return(NULL); 
 		}
+		mail = np;
 		mail[l]=idx;
 		l++; 
 	}
diff --git a/src/sbbs3/js_bbs.cpp b/src/sbbs3/js_bbs.cpp
index 5f1ad1e9f9..e0bbd1c91f 100644
--- a/src/sbbs3/js_bbs.cpp
+++ b/src/sbbs3/js_bbs.cpp
@@ -3090,6 +3090,7 @@ js_cmdstr(JSContext *cx, uintN argc, jsval *arglist)
 				if(fpath==NULL) {
 					if(fspec != def)
 						free(fspec);
+					free(p);
 					return JS_FALSE;
 				}
 			}
@@ -3098,6 +3099,7 @@ js_cmdstr(JSContext *cx, uintN argc, jsval *arglist)
 				if(fspec==NULL) {
 					if(fpath != def)
 						free(fpath);
+					free(p);
 					return JS_FALSE;
 				}
 			}
@@ -3175,8 +3177,11 @@ js_listfiles(JSContext *cx, uintN argc, jsval *arglist)
 
 	for(uintN i=1;i<argc;i++) {
 		if(JSVAL_IS_NUMBER(argv[i])) {
-			if(!JS_ValueToInt32(cx,argv[i],&mode))
+			if(!JS_ValueToInt32(cx,argv[i],&mode)) {
+				if(fspec != def)
+					FREE_AND_NULL(fspec);
 				return JS_FALSE;
+			}
 		}
 		else if(JSVAL_IS_STRING(argv[i])) {
 			js_str = JS_ValueToString(cx, argv[i]);
diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c
index 0a7f1de55e..e560de5917 100644
--- a/src/sbbs3/js_global.c
+++ b/src/sbbs3/js_global.c
@@ -2704,6 +2704,7 @@ js_truncstr(JSContext *cx, uintN argc, jsval *arglist)
 	JSVALUE_TO_MSTRING(cx, argv[1], set, NULL);
 	if(JS_IsExceptionPending(cx)) {
 		free(str);
+		FREE_AND_NULL(set);
 		return JS_FALSE;
 	}
 	if(set==NULL) {
@@ -3007,6 +3008,7 @@ js_fcopy(JSContext *cx, uintN argc, jsval *arglist)
 	JSVALUE_TO_MSTRING(cx, argv[1], dest, NULL);
 	if(JS_IsExceptionPending(cx)) {
 		free(src);
+		FREE_AND_NULL(dest);
 		return JS_FALSE;
 	}
 	if(dest==NULL) {
@@ -3339,6 +3341,7 @@ js_fmutex(JSContext *cx, uintN argc, jsval *arglist)
 		JSVALUE_TO_MSTRING(cx, argv[argn], text, NULL);
 		argn++;
 		if(JS_IsExceptionPending(cx)) {
+			FREE_AND_NULL(text);
 			free(fname);
 			return JS_FALSE;
 		}
@@ -3482,6 +3485,8 @@ js_wildmatch(JSContext *cx, uintN argc, jsval *arglist)
 		argn++;
 		if(JS_IsExceptionPending(cx)) {
 			free(fname);
+			if(spec != NULL && spec != spec_def)
+				free(spec);
 			return JS_FALSE;
 		}
 		if(spec==NULL) {
diff --git a/src/sbbs3/js_msgbase.c b/src/sbbs3/js_msgbase.c
index c39421bd6c..e73dc6f726 100644
--- a/src/sbbs3/js_msgbase.c
+++ b/src/sbbs3/js_msgbase.c
@@ -211,8 +211,10 @@ static BOOL parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, s
 	}
 
 	if(JS_GetProperty(cx, hdr, "to_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		if(!JS_ValueToInt32(cx,val,&i32))
+		if(!JS_ValueToInt32(cx,val,&i32)) {
+			free(cp);
 			return(FALSE);
+		}
 		nettype=(ushort)i32;
 	}
 
@@ -1506,7 +1508,11 @@ js_get_msg_header(JSContext *cx, uintN argc, jsval *arglist)
 	} else if(JSVAL_IS_STRING(argv[n]))	{		/* Get by ID */
 		JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(argv[n]), cstr, NULL);
 		n++;
-		HANDLE_PENDING(cx, cstr);
+		if(JS_IsExceptionPending(cx)) {
+			free(cstr);
+			free(p);
+			return JS_FALSE;
+		}
 		if(cstr != NULL) {
 			rc=JS_SUSPENDREQUEST(cx);
 			if((p->p->status=smb_getmsghdr_by_msgid(&(p->p->smb),&(p->msg)
@@ -2209,8 +2215,8 @@ js_save_msg(JSContext *cx, uintN argc, jsval *arglist)
 	jsval *argv=JS_ARGV(cx, arglist);
 	char*		body=NULL;
 	uintN		n;
-    jsuint      i;
-    jsuint      rcpt_list_length=0;
+	jsuint      i;
+	jsuint      rcpt_list_length=0;
 	jsval       val;
 	JSObject*	hdr=NULL;
 	JSObject*	objarg;
@@ -2282,8 +2288,10 @@ js_save_msg(JSContext *cx, uintN argc, jsval *arglist)
 		}
 	}
 
-	if(hdr==NULL)
+	if(hdr==NULL) {
+		FREE_AND_NULL(body);
 		return JS_TRUE;
+	}
 	if(body==NULL)
 		body=strdup("");
 
diff --git a/src/sbbs3/js_system.c b/src/sbbs3/js_system.c
index 0ffe5a5502..9b063e4ae7 100644
--- a/src/sbbs3/js_system.c
+++ b/src/sbbs3/js_system.c
@@ -930,6 +930,7 @@ js_trashcan(JSContext *cx, uintN argc, jsval *arglist)
 
 	JSSTRING_TO_MSTRING(cx, js_str, str, NULL);
 	if(JS_IsExceptionPending(cx)) {
+		FREE_AND_NULL(str);
 		free(can);
 		return JS_FALSE;
 	}
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index d8c7043298..3aba36ea39 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -133,8 +133,8 @@ extern int	thread_suid_broken;			/* NPTL is no longer broken */
 				*(sizeptr) = *JSSTSlenptr+1; \
 				if((JSSTStmpptr=(char *)realloc((ret), *(sizeptr)))==NULL) { \
 					JS_ReportError(cx, "Error reallocating %lu bytes at %s:%d", (*JSSTSlenptr)+1, getfname(__FILE__), __LINE__); \
+					if((ret) != NULL) free(ret); \
 					(ret)=NULL; \
-					free(ret); \
 				} \
 				else { \
 					(ret)=JSSTStmpptr; \
diff --git a/src/sbbs3/sbbsecho.c b/src/sbbs3/sbbsecho.c
index 7fa41706be..533463450b 100644
--- a/src/sbbs3/sbbsecho.c
+++ b/src/sbbs3/sbbsecho.c
@@ -5274,12 +5274,13 @@ void pack_netmail(void)
 		addr.net		= hdr.destnet;
 		addr.node		= hdr.destnode;
 		addr.point		= hdr.destpoint;
+		printf("NetMail msg %s from %s (%s) to %s (%s): "
+			,getfname(path), hdr.from, fmsghdr_srcaddr_str(&hdr), hdr.to, smb_faddrtoa(&addr,NULL));
 		if(sysfaddr_is_valid(find_sysfaddr(addr)))	{				  /* In-bound, so ignore */
+			printf("in-bound\n");
 			fclose(fidomsg);
 			continue;
 		}
-		printf("NetMail msg %s from %s (%s) to %s (%s): "
-			,getfname(path), hdr.from, fmsghdr_srcaddr_str(&hdr), hdr.to, smb_faddrtoa(&addr,NULL));
 		if((hdr.attr&FIDO_SENT) && !cfg.ignore_netmail_recv_attr) {
 			printf("already sent\n");
 			fclose(fidomsg);
@@ -5474,15 +5475,19 @@ void find_stray_packets(void)
 		outpkt_t* pkt;
 		if((pkt = calloc(1, sizeof(outpkt_t))) == NULL)
 			continue;
-		if((pkt->filename = strdup(packet)) == NULL)
+		if((pkt->filename = strdup(packet)) == NULL) {
+			free(pkt);
 			continue;
+		}
 		if(terminator == FIDO_PACKET_TERMINATOR)
 			lprintf(LOG_DEBUG, "Stray packet already finalized: %s", packet);
-		else
+		else {
 			if((pkt->fp = fopen(pkt->filename, "ab")) == NULL) {
 				lprintf(LOG_ERR, "ERROR %d (%s) opening %s", errno, strerror(errno), pkt->filename);
+				free(pkt);
 				continue;
 			}
+		}
 		pkt->orig = pkt_orig;
 		pkt->dest = pkt_dest;
 		listAddNode(&outpkt_list, pkt, 0, LAST_NODE);
diff --git a/src/sbbs3/scfg/scfgxfr2.c b/src/sbbs3/scfg/scfgxfr2.c
index cec38f3b5b..efd576f04f 100644
--- a/src/sbbs3/scfg/scfgxfr2.c
+++ b/src/sbbs3/scfg/scfgxfr2.c
@@ -63,6 +63,7 @@ static bool new_dir(unsigned new_dirnum, unsigned libnum)
 
 	dir_t** new_dir_list;
 	if ((new_dir_list = (dir_t **)realloc(cfg.dir, sizeof(dir_t *)*(cfg.total_dirs + 1))) == NULL) {
+		free(new_directory);
 		errormsg(WHERE, ERR_ALLOC, "directory list", cfg.total_dirs + 1);
 		return false;
 	}
@@ -89,6 +90,7 @@ static bool new_lib(unsigned new_libnum)
 
 	lib_t** new_lib_list;
 	if ((new_lib_list = (lib_t **)realloc(cfg.lib, sizeof(lib_t *)*(cfg.total_libs + 1))) == NULL) {
+		free(new_library);
 		errormsg(WHERE, ERR_ALLOC, "library list", cfg.total_libs + 1);
 		return false;
 	}
diff --git a/src/sbbs3/scfg/scfgxtrn.c b/src/sbbs3/scfg/scfgxtrn.c
index 799f58df76..bf9a9c19fd 100644
--- a/src/sbbs3/scfg/scfgxtrn.c
+++ b/src/sbbs3/scfg/scfgxtrn.c
@@ -54,6 +54,7 @@ static bool new_timed_event(unsigned new_event_num)
 
 	event_t** new_event_list = realloc(cfg.event, sizeof(event_t *)*(cfg.total_events + 1));
 	if (new_event_list == NULL) {
+		free(new_event);
 		errormsg(WHERE, ERR_ALLOC, "timed event list", cfg.total_events + 1);
 		return false;
 	}
@@ -78,6 +79,7 @@ static bool new_external_program_section(unsigned new_section_num)
 
 	xtrnsec_t** new_xtrnsec_list = realloc(cfg.xtrnsec, sizeof(xtrnsec_t *)*(cfg.total_xtrnsecs + 1));
 	if (new_xtrnsec_list == NULL) {
+		free(new_xtrnsec);
 		errormsg(WHERE, ERR_ALLOC, "external program section list", cfg.total_xtrnsecs + 1);
 		return false;
 	}
@@ -107,6 +109,7 @@ static bool new_external_program(unsigned new_xtrn_num, unsigned section)
 
 	xtrn_t ** new_xtrn_list = realloc(cfg.xtrn, sizeof(xtrn_t *)*(cfg.total_xtrns + 1));
 	if (new_xtrn_list == NULL) {
+		free(new_xtrn);
 		errormsg(WHERE, ERR_ALLOC, "external program list", cfg.total_xtrns + 1);
 		return false;
 	}
@@ -130,6 +133,7 @@ static bool new_external_editor(unsigned new_xedit_num)
 
 	xedit_t** new_xedit_list = realloc(cfg.xedit, sizeof(xedit_t *)*(cfg.total_xedits + 1));
 	if (new_xedit_list == NULL) {
+		free(new_xedit);
 		errormsg(WHERE, ERR_ALLOC, "external editor list", cfg.total_xedits + 1);
 		return false;
 	}
-- 
GitLab