Opus decoder produces signed arithmetic overflow undefined behavior
The libopus Opus decoder can produce signed multiplication overflows and signed addition overflows decoding Opus packets. This is undefined behavior according to ISO C.
When this happens, it is usually accompanied by loud, exceptionally poor quality clipped audio output.
The libopus README file claims that the implementation does not rely on any undefined behavior.
Attached is an example PCM input file that can be used with opus_demo
to reproduce the issue. The packets produced by the Opus encoder produce overflows when decoded. The issue can be reproduced with either the floating point or fixed point implementation using the command below:
$ opus_demo audio 48000 1 9000 -cbr ticket2000.pcm out.pcm
libopus 1.1-42-ge1f8462
Encoding 48000 Hz input at 9.000 kb/s in auto mode with 960-sample frames.
Numerous occurrences of the following operations are encountered (with varying values for the operands):
CLANG ARITHMETIC UNDEFINED at <silk/NSQ_del_dec.c, (234:64)> : Op: *, Reason : Signed Multiplication Overflow, BINARY OPERATION: left (int32): -284186 right (int32): 8512
CLANG ARITHMETIC UNDEFINED at <silk/decode_core.c, (224:36)> : Op: *, Reason : Signed Multiplication Overflow, BINARY OPERATION: left (int32): 47718480 right (int32): 52
CLANG ARITHMETIC UNDEFINED at <silk/decode_core.c, (224:36)> : Op: +, Reason : Signed Addition Overflow, BINARY OPERATION: left (int32): 44894665 right (int32): 2140023376
The output audio also sounds nothing like the input.