shithub: dumb

Download patch

ref: 753d2b72a1c2e76fc6f189e50bdc9632904d915d
parent: 2861bef3d4c7fd722cecc131c2d4453fc2e0718d
author: Christopher Snowhill <kode54@gmail.com>
date: Wed Sep 13 15:35:10 EDT 2017

Since snum allows successive sample entries to clobber each other, buffer up entire sample data before overwriting the memory structure, and free sample data if it's being replaced.

--- a/src/it/readoldpsm.c
+++ b/src/it/readoldpsm.c
@@ -66,89 +66,88 @@
 
 	qsort(buffer, count, 64, &psm_sample_compare);
 
-	for (n = 0; n < true_num; n++) {
+	for (n = 0; n < *num; n++) {
 		(*sample)[n].flags = 0;
 	}
 
 	for (n = 0; n < count; n++) {
+		IT_SAMPLE smp;
 		IT_SAMPLE * s;
 		snum = buffer[(n * 64) + 45] | (buffer[(n * 64) + 46] << 8);
 		s = &((*sample)[snum - 1]);
-		memcpy(s->filename, buffer + (n * 64), 13);
-		s->filename[13] = 0;
-		memcpy(s->name, buffer + (n * 64) + 13, 24);
-		s->name[24] = 0;
+		memcpy(smp.filename, buffer + (n * 64), 13);
+		smp.filename[13] = 0;
+		memcpy(smp.name, buffer + (n * 64) + 13, 24);
+		smp.name[24] = 0;
 		offset = buffer[(n * 64) + 37] | (buffer[(n * 64) + 38] << 8) |
 				 (buffer[(n * 64) + 39] << 16) | (buffer[(n * 64) + 40] << 24);
 		flags = buffer[(n * 64) + 47];
-		s->length = buffer[(n * 64) + 48] | (buffer[(n * 64) + 49] << 8) |
+		smp.length = buffer[(n * 64) + 48] | (buffer[(n * 64) + 49] << 8) |
 					(buffer[(n * 64) + 50] << 16) | (buffer[(n * 64) + 51] << 24);
-		s->loop_start = buffer[(n * 64) + 52] | (buffer[(n * 64) + 53] << 8) |
+		smp.loop_start = buffer[(n * 64) + 52] | (buffer[(n * 64) + 53] << 8) |
 						(buffer[(n * 64) + 54] << 16) | (buffer[(n * 64) + 55] << 24);
-		s->loop_end = buffer[(n * 64) + 56] | (buffer[(n * 64) + 57] << 8) |
+		smp.loop_end = buffer[(n * 64) + 56] | (buffer[(n * 64) + 57] << 8) |
 					  (buffer[(n * 64) + 58] << 16) | (buffer[(n * 64) + 59] << 24);
 
-		if (s->length <= 0) continue;
+		if (smp.length <= 0) continue;
 
 		finetune = buffer[(n * 64) + 60];
-		s->default_volume = buffer[(n * 64) + 61];
-		s->C5_speed = buffer[(n * 64) + 62] | (buffer[(n * 64) + 63] << 8);
+		smp.default_volume = buffer[(n * 64) + 61];
+		smp.C5_speed = buffer[(n * 64) + 62] | (buffer[(n * 64) + 63] << 8);
 		if (finetune & 15) {
 			finetune &= 15;
 			if (finetune >= 8) finetune -= 16;
 			//s->C5_speed = (long)((double)s->C5_speed * pow(DUMB_PITCH_BASE, finetune*32));
-			s->finetune = finetune * 32;
+			smp.finetune = finetune * 32;
 		}
-		else s->finetune = 0;
+		else smp.finetune = 0;
 
-		s->flags |= IT_SAMPLE_EXISTS;
-		if (flags & 0x41) {
-			s->flags &= ~IT_SAMPLE_EXISTS;
+		smp.flags |= IT_SAMPLE_EXISTS;
+		if (flags & 0x41)
 			continue;
-		}
-		if (flags & 0x20) s->flags |= IT_SAMPLE_PINGPONG_LOOP;
-		if (flags & 4) s->flags |= IT_SAMPLE_16BIT;
+		if (flags & 0x20) smp.flags |= IT_SAMPLE_PINGPONG_LOOP;
+		if (flags & 4) smp.flags |= IT_SAMPLE_16BIT;
 
 		if (flags & 0x80) {
-			s->flags |= IT_SAMPLE_LOOP;
-			if ((unsigned int)s->loop_end > (unsigned int)s->length)
-				s->loop_end = s->length;
-			else if ((unsigned int)s->loop_start >= (unsigned int)s->loop_end)
-				s->flags &= ~IT_SAMPLE_LOOP;
+			smp.flags |= IT_SAMPLE_LOOP;
+			if ((unsigned int)smp.loop_end > (unsigned int)smp.length)
+				smp.loop_end = smp.length;
+			else if ((unsigned int)smp.loop_start >= (unsigned int)smp.loop_end)
+				smp.flags &= ~IT_SAMPLE_LOOP;
 			else
-				s->length = s->loop_end;
+				smp.length = smp.loop_end;
 		}
 
-		s->global_volume = 64;
+		smp.global_volume = 64;
 
-		s->vibrato_speed = 0;
-		s->vibrato_depth = 0;
-		s->vibrato_rate = 0;
-		s->vibrato_waveform = IT_VIBRATO_SINE;
-		s->max_resampling_quality = -1;
+		smp.vibrato_speed = 0;
+		smp.vibrato_depth = 0;
+		smp.vibrato_rate = 0;
+		smp.vibrato_waveform = IT_VIBRATO_SINE;
+		smp.max_resampling_quality = -1;
 
-        sample_bytes = s->length * ((flags & 4) ? 2 : 1);
-        s->data = malloc(sample_bytes);
-		if (!s->data) goto error_fb;
+        sample_bytes = smp.length * ((flags & 4) ? 2 : 1);
+        smp.data = malloc(sample_bytes);
+		if (!smp.data) goto error_fb;
+		sdata = (const unsigned char *) smp.data;
 
-        if (dumbfile_seek(f, offset, DFS_SEEK_SET) || dumbfile_getnc(s->data, sample_bytes, f) < sample_bytes) goto error_fb;
-        sdata = ( const unsigned char * ) s->data;
+        if (dumbfile_seek(f, offset, DFS_SEEK_SET) || dumbfile_getnc(smp.data, sample_bytes, f) < sample_bytes) goto error_fd;
 
 		if (flags & 0x10) {
 			if (flags & 8) {
 				if (flags & 4) {
-					for (o = 0; o < s->length; o++)
-						((short *)s->data)[o] = (sdata[o * 2] | (sdata[(o * 2) + 1] << 8)) ^ 0x8000;
+					for (o = 0; o < smp.length; o++)
+						((short *)smp.data)[o] = (sdata[o * 2] | (sdata[(o * 2) + 1] << 8)) ^ 0x8000;
 				} else {
-					for (o = 0; o < s->length; o++)
-						((signed char *)s->data)[o] = sdata[o] ^ 0x80;
+					for (o = 0; o < smp.length; o++)
+						((signed char *)smp.data)[o] = sdata[o] ^ 0x80;
 				}
 			} else {
 				if (flags & 4) {
-					for (o = 0; o < s->length; o++)
-						((short *)s->data)[o] = sdata[o * 2] | (sdata[(o * 2) + 1] << 8);
+					for (o = 0; o < smp.length; o++)
+						((short *)smp.data)[o] = sdata[o * 2] | (sdata[(o * 2) + 1] << 8);
 				} else {
-					memcpy(s->data, sdata, s->length);
+					memcpy(smp.data, sdata, smp.length);
 				}
 			}
 		} else {
@@ -156,30 +155,33 @@
 			if (flags & 8) {
 				/* unsigned delta? mehhh, does anything even use this? */
 				if (flags & 4) {
-					for (o = 0; o < s->length; o++) {
+					for (o = 0; o < smp.length; o++) {
 						delta += (short)(sdata[o * 2] | (sdata[(o * 2) + 1] << 8));
-						((short *)s->data)[o] = delta ^ 0x8000;
+						((short *)smp.data)[o] = delta ^ 0x8000;
 					}
 				} else {
-					for (o = 0; o < s->length; o++) {
+					for (o = 0; o < smp.length; o++) {
 						delta += (signed char)sdata[o];
-						((signed char *)s->data)[o] = delta ^ 0x80;
+						((signed char *)smp.data)[o] = delta ^ 0x80;
 					}
 				}
 			} else {
 				if (flags & 4) {
-					for (o = 0; o < s->length; o++) {
+					for (o = 0; o < smp.length; o++) {
 						delta += (signed short)(sdata[o * 2] | (sdata[(o * 2) + 1] << 8));
-						((signed short *)s->data)[o] = delta;
+						((signed short *)smp.data)[o] = delta;
 					}
 				} else {
-					for (o = 0; o < s->length; o++) {
+					for (o = 0; o < smp.length; o++) {
 						delta += (signed char)sdata[o];
-						((signed char *)s->data)[o] = delta;
+						((signed char *)smp.data)[o] = delta;
 					}
 				}
 			}
 		}
+		
+		if (s->data) free(s->data);
+		*s = smp;
 	}
 
 	free(buffer);
@@ -186,6 +188,8 @@
 
 	return 0;
 
+error_fd:
+	free((void *)sdata);
 error_fb:
 	free(buffer);
 error: