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;