From 1ea66f5b309e7d806dea46cb274f681ff04e60c3 Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Windows 11)" <rob@synchro.net>
Date: Wed, 24 Jan 2024 17:56:31 -0800
Subject: [PATCH] Don't store pointer to stack variable in sbbs_t::event_code

sbbs_t::gettimeleft() was storing a pointer to a stack (temporary/local)
variable containing a copy of the next exclusive event cfg (including its
internal code). This variable, including the internal code, is invalid when
it goes out of scope. This change makes the sbbs_t::event_code point to the
sbbs_t::cfg.event[]->code (on the heap) instead.

The only use of this event_code (outside of the event_thread), appears to be
in the JS bbs.event_code property string. So this fixes issue #705. No other
observed side effect from this bug.

Constified getnexteventtime() while here. No functional impact.
---
 src/sbbs3/data.cpp | 12 ++++++------
 src/sbbs3/sbbs.h   |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/sbbs3/data.cpp b/src/sbbs3/data.cpp
index 08bedb7caf..10f5af7790 100644
--- a/src/sbbs3/data.cpp
+++ b/src/sbbs3/data.cpp
@@ -100,7 +100,7 @@ uint sbbs_t::finduser(const char* name, bool silent_failure)
 /****************************************************************************/
 /* Return date/time that the specified event should run next				*/
 /****************************************************************************/
-extern "C" time_t getnexteventtime(event_t* event)
+extern "C" time_t getnexteventtime(const event_t* event)
 {
 	struct tm tm;
 	time_t	t = time(NULL);
@@ -143,7 +143,7 @@ extern "C" time_t getnexteventtime(event_t* event)
 /* Return time of next forced timed event									*/
 /* 'event' may be NULL														*/
 /****************************************************************************/
-extern "C" time_t getnextevent(scfg_t* cfg, event_t* event)
+extern "C" time_t getnextevent(scfg_t* cfg, event_t** event)
 {
     int     i;
 	time_t	event_time=0;
@@ -164,7 +164,7 @@ extern "C" time_t getnextevent(scfg_t* cfg, event_t* event)
 		if(!event_time || thisevent<event_time) {
 			event_time=thisevent;
 			if(event!=NULL)
-				*event=*cfg->event[i];
+				*event = cfg->event[i];
 		}
 	}
 
@@ -180,7 +180,7 @@ uint sbbs_t::gettimeleft(bool handle_out_of_time)
 {
     char    str[128];
 	char 	tmp[512];
-	event_t	nextevent;
+	event_t* nextevent{nullptr};
 
 	now=time(NULL);
 
@@ -188,8 +188,8 @@ uint sbbs_t::gettimeleft(bool handle_out_of_time)
 
 	/* Timed event time reduction handler */
 	event_time=getnextevent(&cfg, &nextevent);
-	if(event_time)
-		event_code=nextevent.code;
+	if(event_time && nextevent != nullptr)
+		event_code=nextevent->code;
 
 	if(event_time && now+(time_t)timeleft>event_time) {    /* less time, set flag */
 		if(event_time<now)
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index b954735288..92b0eb477f 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -1319,8 +1319,8 @@ extern "C" {
 	DLLEXPORT void		fcloselog(FILE*);
 
 	/* data.cpp */
-	DLLEXPORT time_t	getnextevent(scfg_t* cfg, event_t* event);
-	DLLEXPORT time_t	getnexteventtime(event_t* event);
+	DLLEXPORT time_t	getnextevent(scfg_t* cfg, event_t**);
+	DLLEXPORT time_t	getnexteventtime(const event_t*);
 
 	/* sockopt.c */
 	DLLEXPORT int		set_socket_options(scfg_t* cfg, SOCKET sock, const char* section
-- 
GitLab