mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
h2645_parse: use the bytestream2 API for packet splitting
The code does some nontrivial jumping around in the buffer, so it is safer to use a checked API rather than do everything manually. Fixes a bug in nalff parsing, where the length field is currently not counted in the buffer size check, resulting in possible overreads with invalid files. CC: libav-stable@libav.org Bug-Id: 1002 Found-By: Kamil Frankowicz
This commit is contained in:
parent
b76f6a76c6
commit
83b2b34d06
@ -26,6 +26,7 @@
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
#include "bytestream.h"
|
||||
#include "h2645_parse.h"
|
||||
|
||||
int ff_h2645_extract_rbsp(const uint8_t *src, int length,
|
||||
@ -214,11 +215,14 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
|
||||
void *logctx, int is_nalff, int nal_length_size,
|
||||
enum AVCodecID codec_id)
|
||||
{
|
||||
GetByteContext bc;
|
||||
int consumed, ret = 0;
|
||||
const uint8_t *next_avc = buf + (is_nalff ? 0 : length);
|
||||
size_t next_avc = is_nalff ? 0 : length;
|
||||
|
||||
bytestream2_init(&bc, buf, length);
|
||||
|
||||
pkt->nb_nals = 0;
|
||||
while (length >= 4) {
|
||||
while (bytestream2_get_bytes_left(&bc) >= 4) {
|
||||
H2645NAL *nal;
|
||||
int extract_length = 0;
|
||||
int skip_trailing_zeros = 1;
|
||||
@ -231,40 +235,37 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
|
||||
* correctly and consumes only the first NAL unit. The additional NAL
|
||||
* units are handled here in the Annex B parsing code.
|
||||
*/
|
||||
if (buf == next_avc) {
|
||||
if (bytestream2_tell(&bc) == next_avc) {
|
||||
int i;
|
||||
for (i = 0; i < nal_length_size; i++)
|
||||
extract_length = (extract_length << 8) | buf[i];
|
||||
extract_length = (extract_length << 8) | bytestream2_get_byte(&bc);
|
||||
|
||||
if (extract_length > length) {
|
||||
if (extract_length > bytestream2_get_bytes_left(&bc)) {
|
||||
av_log(logctx, AV_LOG_ERROR,
|
||||
"Invalid NAL unit size (%d > %d).\n",
|
||||
extract_length, length);
|
||||
extract_length, bytestream2_get_bytes_left(&bc));
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
buf += nal_length_size;
|
||||
length -= nal_length_size;
|
||||
// keep track of the next AVC1 length field
|
||||
next_avc = buf + extract_length;
|
||||
next_avc = bytestream2_tell(&bc) + extract_length;
|
||||
} else {
|
||||
/*
|
||||
* expected to return immediately except for streams with mixed
|
||||
* NAL unit coding
|
||||
*/
|
||||
int buf_index = find_next_start_code(buf, next_avc);
|
||||
int buf_index = find_next_start_code(bc.buffer, buf + next_avc);
|
||||
|
||||
buf += buf_index;
|
||||
length -= buf_index;
|
||||
bytestream2_skip(&bc, buf_index);
|
||||
|
||||
/*
|
||||
* break if an AVC1 length field is expected at the current buffer
|
||||
* position
|
||||
*/
|
||||
if (buf == next_avc)
|
||||
if (bytestream2_tell(&bc) == next_avc)
|
||||
continue;
|
||||
|
||||
if (length > 0) {
|
||||
extract_length = length;
|
||||
if (bytestream2_get_bytes_left(&bc) > 0) {
|
||||
extract_length = bytestream2_get_bytes_left(&bc);
|
||||
} else if (pkt->nb_nals == 0) {
|
||||
av_log(logctx, AV_LOG_ERROR, "No NAL unit found\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
@ -286,14 +287,15 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
|
||||
}
|
||||
nal = &pkt->nals[pkt->nb_nals++];
|
||||
|
||||
consumed = ff_h2645_extract_rbsp(buf, extract_length, nal);
|
||||
consumed = ff_h2645_extract_rbsp(bc.buffer, extract_length, nal);
|
||||
if (consumed < 0)
|
||||
return consumed;
|
||||
|
||||
bytestream2_skip(&bc, consumed);
|
||||
|
||||
/* see commit 3566042a0 */
|
||||
if (consumed < length - 3 &&
|
||||
buf[consumed] == 0x00 && buf[consumed + 1] == 0x00 &&
|
||||
buf[consumed + 2] == 0x01 && buf[consumed + 3] == 0xE0)
|
||||
if (bytestream2_get_bytes_left(&bc) >= 4 &&
|
||||
bytestream2_peek_be32(&bc) == 0x000001E0)
|
||||
skip_trailing_zeros = 0;
|
||||
|
||||
nal->size_bits = get_bit_length(nal, skip_trailing_zeros);
|
||||
@ -313,9 +315,6 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
|
||||
}
|
||||
pkt->nb_nals--;
|
||||
}
|
||||
|
||||
buf += consumed;
|
||||
length -= consumed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user