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.
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).
CVE-2019-13217: heap buffer overflow in start_decoder()
CVE-2019-13218: stack buffer overflow in compute_codewords()
CVE-2019-13219: uninitialized memory in vorbis_decode_packet_rest()
CVE-2019-13220: out-of-range read in draw_line()
CVE-2019-13221: issue with large 1D codebooks in lookup1_values()
CVE-2019-13222: unchecked NULL returned by get_window()
CVE-2019-13223: division by zero in predict_point()
For negative n, the original code went down the "n < (1<<4)"
path and performed an out-of-bounds array access. Fix the code
to agree with section 9.2.1 of the Vorbis spec. (Verified by
exhaustive testing of all 32-bit ints.)
Fixes issue #355.
temp_alloc() and temp_free() are documented as customization points in section "MEMORY ALLOCATION" (stb_vorbis.c:81).
However, in decode_residue() and inverse_mdct() (via temp_block_array() and temp_alloc() respectively), stb_vorbis allocates temporary memory but does not call temp_free() when finished. It does call temp_alloc_restore() though, but there is no sane way to provide an implementation thereof when using a malloc()/free()-like allocation backend.
Adding calls to temp_free() before the respective calls to temp_alloc_restore() is safe, because in case of a non-empty temp_alloc_restore() implementation, temp_free() would simply be implemented empty (the current implementation of temp_*() is fine in this regard). That way, all possible temporary memory allocation schemes (i.e. alloca(), custom provided alloc_buffer, malloc()) are handled properly.
Add the appropriate temp_free() calls.