shithub: dumb

Download patch

ref: 7ad496ecf2fd658a51de55df0e7f0257025038cc
parent: 5bee3e5ba3d57d1b16dda6d82c18fb417781625b
author: Chris Moeller <kode54@gmail.com>
date: Sun Jul 8 08:57:56 EDT 2012

- Added sanity checking to XM reader instrument and sample header sizes
- Added footer tag checking to prevent tags from reaching the module reader
- Version is now 0.9.9.55

--- a/dumb/src/it/readxm.c
+++ b/dumb/src/it/readxm.c
@@ -388,6 +388,13 @@
 	return 0;
 }
 
+static int limit_xm_skip_end(void *f, long n)
+{
+	DUMBFILE *df = f;
+	LIMITED_XM *lx = df->file;
+	return dumbfile_skip( lx->remaining, n );
+}
+
 static int limit_xm_skip(void *f, long n)
 {
 	LIMITED_XM *lx = f;
@@ -464,6 +471,8 @@
 	unsigned short vol_points[24];
 	unsigned short pan_points[24];
 	int i, type;
+	const unsigned long max_size = 4 + 22 + 1 + 2 + 4 + 96 + 48 + 48 + 1 * 14 + 2 + 2;
+	unsigned long skip_end = 0;
 
 	/* Header size. Tends to be more than the actual size of the structure.
 	 * So unread bytes must be skipped before reading the first sample
@@ -474,7 +483,12 @@
 
 	size = dumbfile_igetl(f);
 
-	if ( size == 0 ) size = 4 + 22 + 1 + 2 + 4 + 96 + 48 + 48 + 1 * 14 + 2 + 2;
+	if ( size == 0 ) size = max_size;
+	else if ( size > max_size )
+	{
+		skip_end = size - max_size;
+		size = max_size;
+	}
 
 	if ( limit_xm_resize( f, size - 4 ) < 0 ) return -1;
 
@@ -492,7 +506,7 @@
 	if (extra->n_samples) {
 		/* sample header size */
 		i = dumbfile_igetl(f);
-		if (!i) i = 0x28;
+		if (!i || i > 0x28) i = 0x28;
 		extra->sample_header_size = i;
 
 		/* sample map */
@@ -580,6 +594,9 @@
 			instrument->map_sample[i] = 0;
 
 	if (size > bytes_read && dumbfile_skip(f, size - bytes_read))
+		return -1;
+
+	if (skip_end && limit_xm_skip_end(f, skip_end))
 		return -1;
 
 	instrument->new_note_action = NNA_NOTE_CUT;