From 3b491aa07c2c704b724921b1ef514c45d0153b89 Mon Sep 17 00:00:00 2001 From: Kevin Croft Date: Wed, 4 Dec 2019 20:00:45 -0800 Subject: [PATCH 1/2] STB Vorbis: prevent division by zero in decode_resign if ch == 0 In the call to decode_residue: decode_residue(f, residue_buffers, ch, n2, r, do_not_decode); The channel count is previously intialized as zero and incremented based on a for-loop (f->channels) plus a conditional, if (map->chan[j].mux == i). If this doesn't happen then 'ch' remains zero. Once inside decode_residue(..), the code has three branches based on channel count: stereo (ch == 2), mono (ch == 1), and then the exception if it's neither of those (simple 'else'). It's in here where a zero-valued 'ch' can be used as the denominator in these calculations: int c_inter = z % ch p_inter = z/ch; Obviously this 'else' branch is meant for channel counts greater than two an not for zero channels; so this change simply makes that branch only valid if (ch > 2). --- stb_vorbis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index fd02caf..3f43983 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -2170,7 +2170,7 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int ++class_set; #endif } - } else { + } else if (ch > 2) { while (pcount < part_read) { int z = r->begin + pcount*r->part_size; int c_inter = z % ch, p_inter = z/ch; From 58e0c4438db5e77b0ad90d3a8c057bb04999bcdc Mon Sep 17 00:00:00 2001 From: Kevin Croft Date: Wed, 4 Dec 2019 21:48:21 -0800 Subject: [PATCH 2/2] STB Vorbis: eliminate inaccessible branch The eliminated code removes the (ch == 1) branch, which is scoped within this if condition: `if (rtype == 2 && ch != 1)`, therefore the (ch == 1) branch will never be taken. Fixes #842. --- stb_vorbis.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index 3f43983..610d2cf 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -2130,46 +2130,6 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int ++class_set; #endif } - } else if (ch == 1) { - while (pcount < part_read) { - int z = r->begin + pcount*r->part_size; - int c_inter = 0, p_inter = z; - if (pass == 0) { - Codebook *c = f->codebooks+r->classbook; - int q; - DECODE(q,f,c); - if (q == EOP) goto done; - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - part_classdata[0][class_set] = r->classdata[q]; - #else - for (i=classwords-1; i >= 0; --i) { - classifications[0][i+pcount] = q % r->classifications; - q /= r->classifications; - } - #endif - } - for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { - int z = r->begin + pcount*r->part_size; - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - int c = part_classdata[0][class_set][i]; - #else - int c = classifications[0][pcount]; - #endif - int b = r->residue_books[c][pass]; - if (b >= 0) { - Codebook *book = f->codebooks + b; - if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) - goto done; - } else { - z += r->part_size; - c_inter = 0; - p_inter = z; - } - } - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - ++class_set; - #endif - } } else if (ch > 2) { while (pcount < part_read) { int z = r->begin + pcount*r->part_size;