From 597c256d0cc9e1708416fcb97483f807da9b2fb0 Mon Sep 17 00:00:00 2001
From: deuce <>
Date: Fri, 9 Mar 2018 05:50:12 +0000
Subject: [PATCH] Fix memory leak found by scan-build.

---
 src/xpdev/xpbeep.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/xpdev/xpbeep.c b/src/xpdev/xpbeep.c
index bc2ec9fb6d..1e4fb59c0d 100644
--- a/src/xpdev/xpbeep.c
+++ b/src/xpdev/xpbeep.c
@@ -826,6 +826,10 @@ error_return:
 	sample_thread_running=FALSE;
 }
 
+/*
+ * This MUST not return false after sample goes into the sample buffer in the background.
+ * If it does, the caller won't be able to free() it.
+ */
 BOOL DLLCALL xp_play_sample(const unsigned char *sample, size_t size, BOOL background)
 {
 	if(!sample_initialized) {
@@ -985,6 +989,7 @@ BOOL DLLCALL xptone(double freq, DWORD duration, enum WAVE_SHAPE shape)
 {
 	unsigned char	*wave;
 	int samples;
+	BOOL ret;
 
 	wave=(unsigned char *)malloc(S_RATE*15/2+1);
 	if(!wave)
@@ -1004,13 +1009,17 @@ BOOL DLLCALL xptone(double freq, DWORD duration, enum WAVE_SHAPE shape)
 			;
 		sample_len++;
 		while(samples > S_RATE*15/2) {
-			if(!xp_play_sample(wave, sample_len, TRUE))
+			if(!xp_play_sample(wave, sample_len, TRUE)) {
+				free(wave);
 				return FALSE;
+			}
 			samples -= sample_len;
 		}
 	}
 	makewave(freq,wave,samples,shape);
-	return(xp_play_sample(wave, samples, FALSE));
+	ret = xp_play_sample(wave, samples, FALSE);
+	free(wave);
+	return ret;
 }
 
 #ifdef __unix__
-- 
GitLab