shithub: ft²

Download patch

ref: a09a16163e5449a359d0d70aa81d40e12fcdc5b6
parent: 62c674336658b9b277a6e000c452c468f9b96bdf
author: Olav Sørensen <olav.sorensen@live.no>
date: Mon Nov 22 18:17:44 EST 2021

Fix crash when using the "Copy ins." and "Xchg ins." feature

--- a/src/ft2_inst_ed.c
+++ b/src/ft2_inst_ed.c
@@ -180,16 +180,31 @@
 	{
 		if (allocateInstr(dstIns))
 		{
+			int16_t i;
+
+			sample_t *srcSmp;
+			sample_t *dstSmp;
+
 			memcpy(instr[dstIns], instr[srcIns], sizeof (instr_t));
 
-			sample_t *srcSmp = instr[srcIns]->smp;
-			sample_t *dstSmp = instr[dstIns]->smp;
+			// clear all copied sample structs (set up in cloneSample() later)
+			dstSmp = instr[dstIns]->smp;
+			for (i = 0; i < MAX_SMP_PER_INST; i++, dstSmp++)
+				memset(dstSmp, 0, sizeof (sample_t));
 
-			for (int16_t i = 0; i < MAX_SMP_PER_INST; i++, srcSmp++, dstSmp++)
+			// clone all the samples
+
+			srcSmp = instr[srcIns]->smp;
+			dstSmp = instr[dstIns]->smp;
+
+			for (i = 0; i < MAX_SMP_PER_INST; i++, srcSmp++, dstSmp++)
 			{
 				if (!cloneSample(srcSmp, dstSmp))
-					error = false;
+					break;
 			}
+
+			if (i == MAX_SMP_PER_INST) // did we manage to successfully copy the samples?
+				error = false; // yes
 		}
 	}
 
@@ -235,17 +250,14 @@
 
 	lockMixerCallback();
 
-	instr_t *src = instr[editor.srcInstr];
-	instr_t *dst = instr[editor.curInstr];
-
 	// swap instruments
-	instr_t dstTmp = *dst;
-	*dst = *src;
-	*src = dstTmp;
+	instr_t *dstTmp = instr[editor.curInstr];
+	instr[editor.curInstr] = instr[editor.srcInstr];
+	instr[editor.srcInstr] = dstTmp;
 
-	unlockMixerCallback();
+	// we do not swap instrument names (like FT2)
 
-	// do not change instrument names!
+	unlockMixerCallback();
 
 	updateNewInstrument();
 	setSongModifiedFlag();
--- a/src/ft2_sample_ed.c
+++ b/src/ft2_sample_ed.c
@@ -155,17 +155,23 @@
 	freeSmpData(dst);
 	memcpy(dst, src, sizeof (sample_t));
 
+	// zero out stuff that wasn't supposed to be cloned
 	dst->origDataPtr = dst->dataPtr = NULL;
 	dst->isFixed = false;
+	dst->fixedPos = 0;
 
+	// if source sample isn't empty, allocate room and copy it over (and fix it)
 	if (src->length > 0 && src->dataPtr != NULL)
 	{
 		bool sample16Bit = !!(src->flags & SAMPLE_16BIT);
 		if (!allocateSmpDataPtr(&sp, src->length, sample16Bit))
+		{
+			dst->length = 0;
 			return false;
+		}
 
-		memcpy(sp.ptr, src->dataPtr, src->length);
 		setSmpDataPtr(dst, &sp);
+		memcpy(dst->dataPtr, src->dataPtr, src->length << sample16Bit);
 		fixSample(dst);
 	}