mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-10-24 02:09:03 +03:00
avformat/mov: Check sample_rate in stsd version 2 audio
The QuickTime SoundDescription version 2 layout stores the sample rate as
a 64 bit float. Converting it to int is undefined behaviour when the value
does not fit into int, NaN included -- and NaN slips through every
integer-style range check because all comparisons against it are false.
The sample_rate < 0 check in ff_mov_read_stsd_entries() runs after the
conversion has already happened, so it cannot prevent this.
Validate the double before converting it, matching soxdec.
Zero is deliberately still accepted: mov_finalize_stsd_codec() substitutes
sc->time_scale for a zero audio sample rate, and rejecting zero here would
remove that existing recovery without being needed for the conversion fix.
Negative, NaN, infinite and out-of-range values are rejected before the
conversion.
Fixes: mov.c:3031 runtime error: nan is outside the range of
representable values of type 'int'
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Furkan Efe Can <caglarf646@gmail.com>
This commit is contained in:
committed by
michaelni
parent
a7b20ee103
commit
3be6c2d943
@@ -2995,8 +2995,8 @@ static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
|
||||
}
|
||||
}
|
||||
|
||||
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
|
||||
AVStream *st, MOVStreamContext *sc)
|
||||
static int mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
|
||||
AVStream *st, MOVStreamContext *sc)
|
||||
{
|
||||
int bits_per_sample, flags;
|
||||
uint16_t version = avio_rb16(pb);
|
||||
@@ -3035,8 +3035,18 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
|
||||
sc->bytes_per_frame = avio_rb32(pb);
|
||||
avio_rb32(pb); /* bytes per sample */
|
||||
} else if (version == 2) {
|
||||
double sample_rate;
|
||||
|
||||
avio_rb32(pb); /* sizeof struct only */
|
||||
st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
|
||||
sample_rate = av_int2double(avio_rb64(pb));
|
||||
|
||||
if (sample_rate < 0 || sample_rate > INT_MAX ||
|
||||
isnan(sample_rate)) {
|
||||
av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %g\n",
|
||||
sample_rate);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
st->codecpar->sample_rate = sample_rate;
|
||||
channel_count = avio_rb32(pb);
|
||||
st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
|
||||
st->codecpar->ch_layout.nb_channels = channel_count;
|
||||
@@ -3114,6 +3124,8 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
|
||||
st->codecpar->bits_per_coded_sample = bits_per_sample;
|
||||
sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
|
||||
@@ -3407,7 +3419,9 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
|
||||
if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
|
||||
mov_parse_stsd_video(c, pb, st, sc);
|
||||
} else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
|
||||
mov_parse_stsd_audio(c, pb, st, sc);
|
||||
ret = mov_parse_stsd_audio(c, pb, st, sc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (st->codecpar->sample_rate < 0) {
|
||||
av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
Reference in New Issue
Block a user