$OpenBSD: patch-src_wav_c,v 1.2 2021/02/13 06:31:07 rsadowski Exp $

- Fix memory leak in wav_read_smpl_chunk().
- Fix leak in wav_read_header.
- Fix memory leak in wav_read_acid_chunk.
- Improve handling of SMPL chunks in WAV files.

Index: src/wav.c
--- src/wav.c.orig
+++ src/wav.c
@@ -481,6 +481,11 @@ wav_read_header	(SF_PRIVATE *psf, int *blockalign, int
 
 						psf_log_printf (psf, "  Count : %d\n", cue_count) ;
 
+						if (psf->cues)
+						{	free (psf->cues) ;
+							psf->cues = NULL ;
+							} ;
+
 						if ((psf->cues = psf_cues_alloc (cue_count)) == NULL)
 							return SFE_MALLOC_FAILED ;
 
@@ -1289,7 +1294,7 @@ wav_command (SF_PRIVATE *psf, int command, void * UNUS
 static int
 wav_read_smpl_chunk (SF_PRIVATE *psf, uint32_t chunklen)
 {	char buffer [512] ;
-	uint32_t thisread, bytesread = 0, dword, sampler_data, loop_count ;
+	uint32_t thisread, bytesread = 0, dword, sampler_data, loop_count, actually_loop_count = 0 ;
 	uint32_t note, pitch, start, end, type = -1, count ;
 	int j, k ;
 
@@ -1335,6 +1340,11 @@ wav_read_smpl_chunk (SF_PRIVATE *psf, uint32_t chunkle
 	*/
 	bytesread += psf_binheader_readf (psf, "4", &sampler_data) ;
 
+	if (psf->instrument)
+	{	psf_log_printf (psf, "  Found more than one SMPL chunk, using last one.\n") ;
+		free (psf->instrument) ;
+		psf->instrument = NULL ;
+		} ;
 	if ((psf->instrument = psf_instrument_alloc ()) == NULL)
 		return SFE_MALLOC_FAILED ;
 
@@ -1381,8 +1391,17 @@ wav_read_smpl_chunk (SF_PRIVATE *psf, uint32_t chunkle
 					break ;
 				} ;
 			} ;
+		actually_loop_count ++ ;
+		} ;
 
-		loop_count -- ;
+	if (actually_loop_count > ARRAY_LEN (psf->instrument->loops))
+	{
+		psf_log_printf (psf, "*** Warning, actual Loop Points count exceeds %u, changing Loop Count from %u to %u\n", ARRAY_LEN (psf->instrument->loops), loop_count, ARRAY_LEN (psf->instrument->loops)) ;
+		psf->instrument->loop_count = ARRAY_LEN (psf->instrument->loops) ;
+		}
+	else if (loop_count != actually_loop_count)
+	{	psf_log_printf (psf, "*** Warning, actual Loop Points count != Loop Count, changing Loop Count from %u to %u\n", loop_count, actually_loop_count) ;
+		psf->instrument->loop_count = actually_loop_count ;
 		} ;
 
 	if (chunklen - bytesread == 0)
@@ -1486,6 +1505,11 @@ wav_read_acid_chunk (SF_PRIVATE *psf, uint32_t chunkle
 
 	psf_binheader_readf (psf, "j", chunklen - bytesread) ;
 
+	if (psf->loop_info)
+	{	psf_log_printf (psf, "  Found existing loop info, using last one.\n") ;
+		free (psf->loop_info) ;
+		psf->loop_info = NULL ;
+		} ;
 	if ((psf->loop_info = calloc (1, sizeof (SF_LOOP_INFO))) == NULL)
 		return SFE_MALLOC_FAILED ;
 
