ref: 6918be14d1e6822a592ec4ad12dccb4c98388d60
parent: dee63f713a6c9ae5d37671ee7ff20b52d50f9232
author: cbagwell <cbagwell>
date: Sun Feb 19 20:33:24 EST 2006
Overflow fixes in aiff and sphere.
--- a/Changelog
+++ b/Changelog
@@ -17,6 +17,9 @@
o Output filenames with multiple '.' confused SoX. (Christian Hammers)
o Moved to a common set of CLIP routines. This fixed clipping
bugs in noisered and mcompand.
+ o Stop SoX from crashing on sphere files that contain large text
+ strings. Ulf Hamhammar
+ o Fix some overflow crashes in aiff handler. Ulf Hamhammar.
sox-12.17.9
-----------
--- a/TODO
+++ b/TODO
@@ -100,8 +100,6 @@
o Make a global version of MIN/MAX instead of sprinkled min/max/MIN/MAX
- o Make a global version of clip() instead of sprinked in all files.
-
o Fix conversions to and from st_sample_t to floats. Currently,
its an approximation because it doesn't account from negative
side having 1 more value then positive side. That means instead
--- a/src/aiff.c
+++ b/src/aiff.c
@@ -228,19 +228,40 @@
else
foundmark = 1;
- chunksize -= 2;
- for(i = 0; i < nmarks; i++) {
- unsigned char len;
+ /* Make sure its not larger then we support */
+ if (nmarks > 32)
+ nmarks = 32;
+ if (chunksize > 2)
+ chunksize -= 2;
+ for(i = 0; i < nmarks && chunksize; i++) {
+ unsigned char len, read_len, tmp_c;
+
+ if (chunksize < 6)
+ break;
st_readw(ft, &(marks[i].id));
st_readdw(ft, &(marks[i].position));
chunksize -= 6;
- st_readb(ft, &len);
- chunksize -= len + 1;
- for(j = 0; j < len ; j++)
- st_readb(ft, (unsigned char *)&(marks[i].name[j]));
- marks[i].name[j] = 0;
- if ((len & 1) == 0) {
+ /* If error reading length then
+ * don't try to read more bytes
+ * based on that value.
+ */
+ if (st_readb(ft, &len) != ST_SUCCESS)
+ break;
+ if (len > chunksize)
+ len = chunksize;
+ read_len = len;
+ if (read_len > 39)
+ read_len = 39;
+ for(j = 0; j < len && chunksize; j++)
+ {
+ st_readb(ft, &tmp_c);
+ if (j < read_len)
+ marks[i].name[j] = tmp_c;
+ chunksize--;
+ }
+ marks[i].name[read_len] = 0;
+ if ((len & 1) == 0 && chunksize) {
chunksize--;
st_readb(ft, (unsigned char *)&trash8);
}
--- a/src/sphere.c
+++ b/src/sphere.c
@@ -82,18 +82,18 @@
{
if (strncmp(buf, "sample_n_bytes", 14) == 0 && ft->info.size == -1)
{
- sscanf(buf, "%s %s %d", fldname, fldtype, &i);
+ sscanf(buf, "%63s %15s %d", fldname, fldtype, &i);
ft->info.size = i;
}
if (strncmp(buf, "channel_count", 13) == 0 &&
ft->info.channels == -1)
{
- sscanf(buf, "%s %s %d", fldname, fldtype, &i);
+ sscanf(buf, "%63s %15s %d", fldname, fldtype, &i);
ft->info.channels = i;
}
if (strncmp(buf, "sample_coding", 13) == 0)
{
- sscanf(buf, "%s %s %s", fldname, fldtype, fldsval);
+ sscanf(buf, "%63s %15s %127s", fldname, fldtype, fldsval);
/* Only bother looking for ulaw flag. All others
* should be caught below by default PCM check
*/
@@ -106,12 +106,12 @@
if (strncmp(buf, "sample_rate ", 12) == 0 &&
ft->info.rate == 0)
{
- sscanf(buf, "%s %s %ld", fldname, fldtype, &rate);
+ sscanf(buf, "%53s %15s %ld", fldname, fldtype, &rate);
ft->info.rate = rate;
}
if (strncmp(buf, "sample_byte_format", 18) == 0)
{
- sscanf(buf, "%s %s %s", fldname, fldtype, fldsval);
+ sscanf(buf, "%53s %15s %127s", fldname, fldtype, fldsval);
if (strncmp(fldsval,"01",2) == 0)
{
/* Data is in little endian. */