Commit 4fc0c1d8 authored by Francois Cartegnie's avatar Francois Cartegnie

packetizer: flac: do better fallback on invalid values (fix #15740)

parent 885932e3
...@@ -88,7 +88,7 @@ struct decoder_sys_t ...@@ -88,7 +88,7 @@ struct decoder_sys_t
mtime_t i_firstframepts; mtime_t i_firstframepts;
mtime_t i_duration; mtime_t i_duration;
int i_frame_length; unsigned int i_frame_length;
size_t i_frame_size; size_t i_frame_size;
uint16_t crc; uint16_t crc;
unsigned int i_rate, i_channels, i_bits_per_sample; unsigned int i_rate, i_channels, i_bits_per_sample;
...@@ -346,14 +346,17 @@ static uint16_t flac_crc16_undo(uint16_t crc, const uint8_t last_byte) ...@@ -346,14 +346,17 @@ static uint16_t flac_crc16_undo(uint16_t crc, const uint8_t last_byte)
/***************************************************************************** /*****************************************************************************
* SyncInfo: parse FLAC sync info * SyncInfo: parse FLAC sync info
*****************************************************************************/ *****************************************************************************/
/* Returns: 1 on success, 0 on failure, and -1 if could be incorrect */
static int SyncInfo(decoder_t *p_dec, uint8_t *p_buf, static int SyncInfo(decoder_t *p_dec, uint8_t *p_buf,
unsigned int * pi_channels, unsigned int * pi_channels,
unsigned int * pi_sample_rate, unsigned int * pi_sample_rate,
unsigned int * pi_bits_per_sample, unsigned int * pi_bits_per_sample,
mtime_t * pi_pts, mtime_t * pi_pts,
mtime_t * pi_duration ) mtime_t * pi_duration,
unsigned int *pi_frame_length )
{ {
decoder_sys_t *p_sys = p_dec->p_sys; decoder_sys_t *p_sys = p_dec->p_sys;
bool b_guessing = false;
/* Check syncword */ /* Check syncword */
if (p_buf[0] != 0xFF || (p_buf[1] & 0xFE) != 0xF8) if (p_buf[0] != 0xFF || (p_buf[1] & 0xFE) != 0xF8)
...@@ -369,6 +372,7 @@ static int SyncInfo(decoder_t *p_dec, uint8_t *p_buf, ...@@ -369,6 +372,7 @@ static int SyncInfo(decoder_t *p_dec, uint8_t *p_buf,
if (blocksize >= 8) { if (blocksize >= 8) {
blocksize = 256 << (blocksize - 8); blocksize = 256 << (blocksize - 8);
} else if (blocksize == 0) { /* value 0 is reserved */ } else if (blocksize == 0) { /* value 0 is reserved */
b_guessing = true;
if (p_sys->b_stream_info && if (p_sys->b_stream_info &&
p_sys->stream_info.min_blocksize == p_sys->stream_info.max_blocksize) p_sys->stream_info.min_blocksize == p_sys->stream_info.max_blocksize)
blocksize = p_sys->stream_info.min_blocksize; blocksize = p_sys->stream_info.min_blocksize;
...@@ -513,7 +517,10 @@ static int SyncInfo(decoder_t *p_dec, uint8_t *p_buf, ...@@ -513,7 +517,10 @@ static int SyncInfo(decoder_t *p_dec, uint8_t *p_buf,
*pi_sample_rate = samplerate; *pi_sample_rate = samplerate;
*pi_channels = channels; *pi_channels = channels;
return blocksize; if( pi_frame_length )
*pi_frame_length = blocksize;
return b_guessing ? -1 : 1;
} }
/* */ /* */
...@@ -590,13 +597,13 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block) ...@@ -590,13 +597,13 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
return NULL; /* Need more data */ return NULL; /* Need more data */
/* Check if frame is valid and get frame info */ /* Check if frame is valid and get frame info */
p_sys->i_frame_length = SyncInfo(p_dec, p_header, int i_ret = SyncInfo(p_dec, p_header, &p_sys->i_channels,
&p_sys->i_channels,
&p_sys->i_rate, &p_sys->i_rate,
&p_sys->i_bits_per_sample, &p_sys->i_bits_per_sample,
&p_sys->i_pts, &p_sys->i_pts,
&p_sys->i_duration ); &p_sys->i_duration,
if (!p_sys->i_frame_length) { &p_sys->i_frame_length );
if (!i_ret) {
msg_Dbg(p_dec, "emulated sync word"); msg_Dbg(p_dec, "emulated sync word");
block_SkipByte(&p_sys->bytestream); block_SkipByte(&p_sys->bytestream);
p_sys->i_state = STATE_NOSYNC; p_sys->i_state = STATE_NOSYNC;
...@@ -641,14 +648,13 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block) ...@@ -641,14 +648,13 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
p_header, MAX_FLAC_HEADER_SIZE)) { p_header, MAX_FLAC_HEADER_SIZE)) {
if (p_header[0] == 0xFF && (p_header[1] & 0xFE) == 0xF8) { if (p_header[0] == 0xFF && (p_header[1] & 0xFE) == 0xF8) {
/* Check if frame is valid and get frame info */ /* Check if frame is valid and get frame info */
int i_frame_length = int i_ret = SyncInfo(p_dec, p_header,
SyncInfo(p_dec, p_header,
&p_sys->i_channels, &p_sys->i_channels,
&p_sys->i_rate, &p_sys->i_rate,
&p_sys->i_bits_per_sample, &p_sys->i_bits_per_sample,
NULL, NULL ); NULL, NULL, NULL );
if (i_frame_length) { if (i_ret) {
uint8_t crc_bytes[2]; uint8_t crc_bytes[2];
block_PeekOffsetBytes(&p_sys->bytestream, block_PeekOffsetBytes(&p_sys->bytestream,
p_sys->i_frame_size - 2, crc_bytes, 2); p_sys->i_frame_size - 2, crc_bytes, 2);
...@@ -657,11 +663,15 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block) ...@@ -657,11 +663,15 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
/* Calculate the frame CRC: remove the last 2 bytes */ /* Calculate the frame CRC: remove the last 2 bytes */
uint16_t crc = flac_crc16_undo(p_sys->crc, crc_bytes[1]); uint16_t crc = flac_crc16_undo(p_sys->crc, crc_bytes[1]);
crc = flac_crc16_undo(crc, crc_bytes[0]); crc = flac_crc16_undo(crc, crc_bytes[0]);
if (stream_crc != crc) { if (stream_crc != crc)
msg_Warn(p_dec, "Bad CRC for frame size %zu: 0x%x != 0x%x", {
p_sys->i_frame_size, crc, stream_crc); if(i_ret > 0)
block_SkipByte(&p_sys->bytestream); {
p_sys->i_state = STATE_NOSYNC; msg_Warn(p_dec, "Bad CRC for frame size %zu: 0x%x != 0x%x",
p_sys->i_frame_size, crc, stream_crc);
block_SkipByte(&p_sys->bytestream);
p_sys->i_state = STATE_NOSYNC;
}
} else { } else {
p_sys->i_state = STATE_SEND_DATA; p_sys->i_state = STATE_SEND_DATA;
p_sys->crc = 0; p_sys->crc = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment