fix av_parser_parse2 abort

Signed-off-by: 凌空先知 <2414106632@qq.com>
This commit is contained in:
凌空先知
2025-06-26 11:38:32 +08:00
parent 15a88d1dce
commit fc6e645d8b
7 changed files with 66 additions and 1 deletions
+1
View File
@@ -167,6 +167,7 @@ config("ffmpeg_config") {
"-DOHOS_CUSTOM_INFO",
"-DOHOS_CAL_DASH_BITRATE",
"-DOHOS_AUXILIARY_TRACK",
"-DOHOS_ABORT_FIX",
]
if (use_musl) {
cflags += [ "-Wno-bool-operation" ]
+8
View File
@@ -162,7 +162,15 @@ int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx,
/* WARNING: the returned index can be negative */
index = s->parser->parser_parse(s, avctx, (const uint8_t **) poutbuf,
poutbuf_size, buf, buf_size);
#ifdef OHOS_ABORT_FIX
if (index <= -0x20000000) {
av_log(NULL, AV_LOG_ERROR,
"Parser returned an error code %d, which is not allowed.\n", index);
return -0x20000000;
}
#else
av_assert0(index > -0x20000000); // The API does not allow returning AVERROR codes
#endif
#define FILL(name) if(s->name > 0 && avctx->name <= 0) avctx->name = s->name
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
FILL(field_order);
+11
View File
@@ -2154,9 +2154,20 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt)
// Parse the packets only in scenarios where it's needed
uint8_t *data;
int size;
#ifdef OHOS_ABORT_FIX
int index = av_parser_parse2(os->parser, os->parser_avctx,
&data, &size, pkt->data, pkt->size,
pkt->pts, pkt->dts, pkt->pos);
if (index <= -0x20000000) {
s->pb->error = AVERROR_INVALIDDATA;
av_log(s, AV_LOG_ERROR, "dash_write_packet returned an error: %d\n", index);
retrun index;
}
#else
av_parser_parse2(os->parser, os->parser_avctx,
&data, &size, pkt->data, pkt->size,
pkt->pts, pkt->dts, pkt->pos);
#endif
os->coding_dependency |= os->parser->pict_type != AV_PICTURE_TYPE_I;
}
+17
View File
@@ -1229,6 +1229,14 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
len = av_parser_parse2(sti->parser, sti->avctx,
&out_pkt->data, &out_pkt->size, data, size,
pkt->pts, pkt->dts, pkt->pos);
#ifdef OHOS_ABORT_FIX
if (len <= -0x20000000) {
s->pb->error = AVERROR_INVALIDDATA;
av_log(s, AV_LOG_ERROR, "Parser returned an error: %d\n", len);
ret = AVERROR(EINVAL);
goto fail;
}
#endif
pkt->pts = pkt->dts = AV_NOPTS_VALUE;
pkt->pos = -1;
@@ -1350,8 +1358,17 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
for (unsigned i = 0; i < s->nb_streams; i++) {
AVStream *const st = s->streams[i];
FFStream *const sti = ffstream(st);
#ifdef OHOS_ABORT_FIX
if (sti->parser && sti->need_parsing) {
av_log(s, AV_LOG_DEBUG, "Flushing parser for stream %d\n", i);
ret = parse_packet(s, pkt, st->index, 1);
if (ret < 0)
return ret;
}
#else
if (sti->parser && sti->need_parsing)
parse_packet(s, pkt, st->index, 1);
#endif
}
/* all remaining packets are now in parse_queue =>
* really terminate parsing */
+11 -1
View File
@@ -287,10 +287,20 @@ static av_unused int64_t flac_read_timestamp(AVFormatContext *s, int stream_inde
av_assert1(!pkt->size);
}
}
#ifdef OHOS_ABORT_FIX
int index = av_parser_parse2(parser, ffstream(st)->avctx,
&data, &size, pkt->data, pkt->size,
pkt->pts, pkt->dts, *ppos);
if (index <= -0x20000000) {
s->pb->error = AVERROR_INVALIDDATA;
av_log(s, AV_LOG_ERROR, "flac_read_timestamp returned an error: %d\n", index);
retrun index;
}
#else
av_parser_parse2(parser, ffstream(st)->avctx,
&data, &size, pkt->data, pkt->size,
pkt->pts, pkt->dts, *ppos);
#endif
av_packet_unref(pkt);
if (size) {
if (parser->pts != AV_NOPTS_VALUE){
+11
View File
@@ -105,9 +105,20 @@ old_flac_header (AVFormatContext * s, int idx)
goto fail;
parser->flags = PARSER_FLAG_COMPLETE_FRAMES;
#ifdef OHOS_ABORT_FIX
int index = av_parser_parse2(parser, avctx,
&data, &size, os->buf + os->pstart, os->psize,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, -1);
if (index == -0x20000000) {
s->pb->error = AVERROR_INVALIDDATA;
ret = index;
goto fail;
}
#else
av_parser_parse2(parser, avctx,
&data, &size, os->buf + os->pstart, os->psize,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, -1);
#endif
av_parser_close(parser);
+7
View File
@@ -446,6 +446,13 @@ int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
if (ts_min == AV_NOPTS_VALUE) {
pos_min = si->data_offset;
ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp_func);
#ifdef OHOS_ABORT_FIX
if (ts_min == -0x20000000) {
s->pb->error = AVERROR_INVALIDDATA;
av_log(s, AV_LOG_ERROR, "read_timestamp failed at the beginning\n")
return -1;
}
#endif
if (ts_min == AV_NOPTS_VALUE)
return -1;
}