summaryrefslogtreecommitdiffstats
path: root/libavcodec/h2645_parse.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2016-12-28 11:27:56 +0100
committerAnton Khirnov <anton@khirnov.net>2017-03-12 20:42:12 +0100
commit83b2b34d06e74cc8775ba3d833f9782505e17539 (patch)
treea60bb55456b8fa0d1adabaad7762e79c0bdec36a /libavcodec/h2645_parse.c
parentb76f6a76c6312dc551d7c37c6ded36bea7973c74 (diff)
downloadffmpeg-streaming-83b2b34d06e74cc8775ba3d833f9782505e17539.zip
ffmpeg-streaming-83b2b34d06e74cc8775ba3d833f9782505e17539.tar.gz
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
Diffstat (limited to 'libavcodec/h2645_parse.c')
-rw-r--r--libavcodec/h2645_parse.c43
1 files changed, 21 insertions, 22 deletions
diff --git a/libavcodec/h2645_parse.c b/libavcodec/h2645_parse.c
index 8492425..b507b19 100644
--- a/libavcodec/h2645_parse.c
+++ b/libavcodec/h2645_parse.c
@@ -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;
OpenPOWER on IntegriCloud