mirror of
https://code.videolan.org/videolan/vlc
synced 2024-09-28 23:09:59 +02:00
packetizer: flac: allow to parse smaller than max header sized blocks
This commit is contained in:
parent
04eca05903
commit
0337ab24f4
@ -37,6 +37,7 @@
|
||||
#include <vlc_charset.h> /* EnsureUTF8 */
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include "xiph_metadata.h" /* vorbis comments */
|
||||
#include "../packetizer/flac.h"
|
||||
|
||||
@ -224,10 +225,11 @@ static block_t *GetPacketizedBlock( decoder_t *p_packetizer,
|
||||
block_t *p_block = p_packetizer->pf_packetize( p_packetizer, pp_current_block );
|
||||
if( p_block )
|
||||
{
|
||||
if( p_block->i_buffer >= FLAC_HEADER_SIZE_MAX )
|
||||
if( p_block->i_buffer >= FLAC_HEADER_SIZE_MIN && p_block->i_buffer < INT_MAX )
|
||||
{
|
||||
struct flac_header_info headerinfo = { .i_pts = VLC_TICK_INVALID };
|
||||
int i_ret = FLAC_ParseSyncInfo( p_block->p_buffer, streaminfo, NULL, &headerinfo );
|
||||
int i_ret = FLAC_ParseSyncInfo( p_block->p_buffer, p_block->i_buffer,
|
||||
streaminfo, NULL, &headerinfo );
|
||||
assert( i_ret != 0 ); /* Same as packetizer */
|
||||
/* Use Frame PTS, not the interpolated one */
|
||||
p_block->i_dts = p_block->i_pts = headerinfo.i_pts;
|
||||
|
@ -366,7 +366,7 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
|
||||
return NULL; /* Need more data */
|
||||
|
||||
/* Check if frame is valid and get frame info */
|
||||
int i_ret = FLAC_ParseSyncInfo(p_header,
|
||||
int i_ret = FLAC_ParseSyncInfo(p_header, FLAC_HEADER_SIZE_MAX,
|
||||
p_sys->b_stream_info ? &p_sys->stream_info : NULL,
|
||||
flac_crc8, &p_sys->headerinfo);
|
||||
if (!i_ret) {
|
||||
@ -413,7 +413,7 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
|
||||
|
||||
struct flac_header_info dummy;
|
||||
/* Check if frame is valid and get frame info */
|
||||
if(FLAC_ParseSyncInfo(nextheader,
|
||||
if(FLAC_ParseSyncInfo(nextheader, FLAC_HEADER_SIZE_MAX,
|
||||
p_sys->b_stream_info ? &p_sys->stream_info : NULL,
|
||||
NULL, &dummy) == 0)
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
*****************************************************************************/
|
||||
#include <vlc_common.h>
|
||||
|
||||
#define FLAC_HEADER_SIZE_MIN 9
|
||||
#define FLAC_HEADER_SIZE_MAX 16
|
||||
#define FLAC_STREAMINFO_SIZE 34
|
||||
#define FLAC_FRAME_SIZE_MIN ((48+(8 + 4 + 1*4)+FLAC_HEADER_SIZE_MAX)/8)
|
||||
@ -64,13 +65,16 @@ static inline void FLAC_ParseStreamInfo( const uint8_t *p_buf,
|
||||
}
|
||||
|
||||
/* Will return INT64_MAX for an invalid utf-8 sequence */
|
||||
static inline int64_t read_utf8(const uint8_t *p_buf, int *pi_read)
|
||||
static inline int64_t read_utf8(const uint8_t *p_buf, unsigned i_buf, int *pi_read)
|
||||
{
|
||||
/* Max coding bits is 56 - 8 */
|
||||
/* Value max precision is 36 bits */
|
||||
int64_t i_result = 0;
|
||||
unsigned i;
|
||||
|
||||
if(i_buf < 1)
|
||||
return INT64_MAX;
|
||||
|
||||
if (!(p_buf[0] & 0x80)) { /* 0xxxxxxx */
|
||||
i_result = p_buf[0];
|
||||
i = 0;
|
||||
@ -96,6 +100,9 @@ static inline int64_t read_utf8(const uint8_t *p_buf, int *pi_read)
|
||||
return INT64_MAX;
|
||||
}
|
||||
|
||||
if(i_buf < i + 1)
|
||||
return INT64_MAX;
|
||||
|
||||
for (unsigned j = 1; j <= i; j++) {
|
||||
if (!(p_buf[j] & 0x80) || (p_buf[j] & 0x40)) { /* 10xxxxxx */
|
||||
return INT64_MAX;
|
||||
@ -114,13 +121,16 @@ static inline int64_t read_utf8(const uint8_t *p_buf, int *pi_read)
|
||||
* - pf_crc8 can be NULL to skip crc check
|
||||
* Returns: 1 on success, 0 on failure, and -1 if could be incorrect
|
||||
*****************************************************************************/
|
||||
static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf,
|
||||
static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf, unsigned i_buf,
|
||||
const struct flac_stream_info *stream_info,
|
||||
uint8_t(*pf_crc8)(const uint8_t *, size_t),
|
||||
struct flac_header_info *h)
|
||||
{
|
||||
bool b_guessing = false;
|
||||
|
||||
if(unlikely(i_buf < FLAC_HEADER_SIZE_MIN))
|
||||
return 0;
|
||||
|
||||
/* Check syncword */
|
||||
if (p_buf[0] != 0xFF || (p_buf[1] & 0xFE) != 0xF8)
|
||||
return 0;
|
||||
@ -205,11 +215,13 @@ static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf,
|
||||
return 0;
|
||||
|
||||
/* End of fixed size header */
|
||||
int i_header = 4;
|
||||
unsigned i_header = 4;
|
||||
|
||||
/* > FLAC_HEADER_SIZE_MIN checks start here */
|
||||
|
||||
/* Check Sample/Frame number */
|
||||
int i_read;
|
||||
int64_t i_fsnumber = read_utf8(&p_buf[i_header++], &i_read);
|
||||
int64_t i_fsnumber = read_utf8(&p_buf[i_header++], i_buf - 4, &i_read);
|
||||
if ( i_fsnumber == INT64_MAX )
|
||||
return 0;
|
||||
|
||||
@ -217,6 +229,8 @@ static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf,
|
||||
|
||||
/* Read blocksize */
|
||||
if (blocksize_hint) {
|
||||
if(i_header == i_buf)
|
||||
return 0;
|
||||
blocksize = p_buf[i_header++];
|
||||
if (blocksize_hint == 7) {
|
||||
blocksize <<= 8;
|
||||
@ -227,8 +241,12 @@ static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf,
|
||||
|
||||
/* Read sample rate */
|
||||
if (samplerate == 0) {
|
||||
if(i_header == i_buf)
|
||||
return 0;
|
||||
samplerate = p_buf[i_header++];
|
||||
if (samplerate_hint != 12) { /* 16 bits */
|
||||
if(i_header == i_buf)
|
||||
return 0;
|
||||
samplerate <<= 8;
|
||||
samplerate |= p_buf[i_header++];
|
||||
}
|
||||
@ -242,6 +260,9 @@ static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf,
|
||||
if ( !samplerate )
|
||||
return 0;
|
||||
|
||||
if(i_header == i_buf) /* no crc space */
|
||||
return 0;
|
||||
|
||||
/* Check the CRC-8 byte */
|
||||
if (pf_crc8 &&
|
||||
pf_crc8(p_buf, i_header) != p_buf[i_header])
|
||||
|
Loading…
Reference in New Issue
Block a user