diff --git a/Changelog b/Changelog index be7588bbbf..28d79ea1ae 100644 --- a/Changelog +++ b/Changelog @@ -1,6 +1,261 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. +version 4.3.2: + avcodec/hapdec: Change compressed_offset to unsigned 32bit + avformat/rmdec: Check codec_length without overflow + avformat/mov: Check element count in mov_metadata_hmmt() + avcodec/vp8: Move end check into MB loop in vp78_decode_mv_mb_modes() + avcodec/fits: Check gcount and pcount being non negative + avformat/nutdec: Check timebase count against main header length + avformat/electronicarts: Clear partial_packet on error + avformat/r3d: Check samples before computing duration + avcodec/pnm_parser: Check av_image_get_buffer_size() for failure + avformat/wavdec: Consider AV_INPUT_BUFFER_PADDING_SIZE in set_spdif() + avformat/rmdec: Check remaining space in debug av_log() loop + avformat/flvdec: Treat high ts byte as unsigned + avformat/samidec: Sanity check pts + avcodec/jpeg2000dec: Check atom_size in jp2_find_codestream() + avformat/avidec: Use 64bit in get_duration() + avformat/mov: Check for duplicate st3d + avformat/mvdec: Check for EOF in read_index() + avcodec/jpeglsdec: Fix k=16 in ls_get_code_regular() + avformat/id3v2: Check the return from avio_get_str() + avcodec/hevc_sei: Check payload size in decode_nal_sei_message() + libavutil/eval: Remove CONFIG_TRAPV special handling + avformat/wtvdec: Check len in parse_chunks() to avoid overflow + avformat/asfdec_f: Add an additional check for the extradata size + avformat/3dostr: Check sample_rate + avformat/4xm: Make audio_frame_count 64bit + avformat/mov: Use av_mul_q() to avoid integer overflows + avcodec/vp9dsp_template: Fix integer overflows in itxfm_wrapper + avformat/rmdec: Reorder operations to avoid overflow + avcodec/mxpegdec: fix SOF counting + avcodec/rscc: Check inflated_buf size whan it is used + avformat/mvdec: Sanity check SAMPLE_WIDTH + avcodec/nvenc: fix timestamp offset ticks logic + avformat/rmdec: Fix codecdata_length overflow check + avcodec/simple_idct: Fix undefined integer overflow in idct4row() + avformat/wavdec: Check block_align vs. channels before combining them + avformat/tta: Use 64bit intermediate for index + avformat/soxdec: Check channels to be positive + avformat/smacker: Check for too small pts_inc + avformat/sbgdec: Use av_sat_add64() in str_to_time() + avcodec/cscd: Check output len in zlib as in lzo + avcodec/vp3: Check input amount in theora_decode_header() + avformat/wavdec: Check avio_get_str16le() for failure + avformat/flvdec: Check for EOF in amf_skip_tag() + avformat/aiffdec: Check size before subtraction in get_aiff_header() + avformat/electronicarts: More chunk_size checks + avcodec/cfhd: check peak.offset + avformat/tedcaptionsdec: Check for overflow in parse_int() + avformat/nuv: Check channels + avcodec/siren: Increase noise category 5 and 6 + avformat/mpc8: Check size before implicitly converting to int + avformat/nutdec: Fix integer overflow in count computation + avformat/mvi: Use 64bit for testing dimensions + avformat/utils: Check dts in update_initial_timestamps() more + avformat/mpsubdec: Use av_sat_add/sub64() in fracval handling + avformat/flvdec: Check for avio_read() failure in amf_get_string() + avformat/flvdec: Check for nesting depth in amf_skip_tag() + avformat/flvdec: Check for nesting depth in amf_parse_object() + avformat/asfdec_o: Check for EOF in asf_read_marker() + avformat/flvdec: Use av_sat_add64() for pts computation + avformat/utils: Check dts - (1< $TMPH <nb_outputs; j++) { OutputFilter *ofilter = fg->outputs[j]; - avfilter_inout_free(&ofilter->out_tmp); av_freep(&ofilter->name); av_freep(&ofilter->formats); av_freep(&ofilter->channel_layouts); diff --git a/libavcodec/aacdec_fixed.c b/libavcodec/aacdec_fixed.c index 9b2145c729..daaf765e0c 100644 --- a/libavcodec/aacdec_fixed.c +++ b/libavcodec/aacdec_fixed.c @@ -155,9 +155,9 @@ static void vector_pow43(int *coefs, int len) for (i=0; imap[x]; if (orig_mv_x >= -32) { - if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 >= h || - x * 8 + mv_x < 0 || x * 8 + mv_x + 8 >= w) + if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h || + x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w) return AVERROR_INVALIDDATA; copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 82689da02a..c8b25dfeac 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -302,6 +302,9 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index, decorr_shift = get_bits(&alac->gb, 8); decorr_left_weight = get_bits(&alac->gb, 8); + if (channels == 2 && decorr_left_weight && decorr_shift > 31) + return AVERROR_INVALIDDATA; + for (ch = 0; ch < channels; ch++) { prediction_type[ch] = get_bits(&alac->gb, 4); lpc_quant[ch] = get_bits(&alac->gb, 4); diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 80f128cade..fa0c08d42e 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -679,9 +679,7 @@ extern AVCodec ff_xsub_decoder; /* external libraries */ extern AVCodec ff_aac_at_encoder; extern AVCodec ff_aac_at_decoder; -extern AVCodec ff_aac_mf_encoder; extern AVCodec ff_ac3_at_decoder; -extern AVCodec ff_ac3_mf_encoder; extern AVCodec ff_adpcm_ima_qt_at_decoder; extern AVCodec ff_alac_at_encoder; extern AVCodec ff_alac_at_decoder; @@ -693,7 +691,6 @@ extern AVCodec ff_ilbc_at_decoder; extern AVCodec ff_mp1_at_decoder; extern AVCodec ff_mp2_at_decoder; extern AVCodec ff_mp3_at_decoder; -extern AVCodec ff_mp3_mf_encoder; extern AVCodec ff_pcm_alaw_at_encoder; extern AVCodec ff_pcm_alaw_at_decoder; extern AVCodec ff_pcm_mulaw_at_encoder; @@ -757,6 +754,8 @@ extern AVCodec ff_idf_decoder; /* external libraries, that shouldn't be used by default if one of the * above is available */ +extern AVCodec ff_aac_mf_encoder; +extern AVCodec ff_ac3_mf_encoder; extern AVCodec ff_h263_v4l2m2m_encoder; extern AVCodec ff_libaom_av1_decoder; extern AVCodec ff_libopenh264_encoder; @@ -789,6 +788,7 @@ extern AVCodec ff_mjpeg_cuvid_decoder; extern AVCodec ff_mjpeg_qsv_encoder; extern AVCodec ff_mjpeg_qsv_decoder; extern AVCodec ff_mjpeg_vaapi_encoder; +extern AVCodec ff_mp3_mf_encoder; extern AVCodec ff_mpeg1_cuvid_decoder; extern AVCodec ff_mpeg2_cuvid_decoder; extern AVCodec ff_mpeg2_qsv_encoder; diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 62c6036037..7eb14db8fe 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -762,7 +762,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) } for (k = 2; k < opt_order; k++) - quant_cof[k] = (quant_cof[k] * (1 << 14)) + (add_base << 13); + quant_cof[k] = (quant_cof[k] * (1U << 14)) + (add_base << 13); } } diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c index 516d07db69..3a461eec26 100644 --- a/libavcodec/ansi.c +++ b/libavcodec/ansi.c @@ -431,7 +431,8 @@ static int decode_frame(AVCodecContext *avctx, s->args[s->nb_args] = FFMAX(s->args[s->nb_args], 0) * 10 + buf[0] - '0'; break; case ';': - s->nb_args++; + if (s->nb_args < MAX_NB_ARGS) + s->nb_args++; if (s->nb_args < MAX_NB_ARGS) s->args[s->nb_args] = 0; break; @@ -474,6 +475,11 @@ static av_cold int decode_close(AVCodecContext *avctx) return 0; } +static const AVCodecDefault ansi_defaults[] = { + { "max_pixels", "640*480" }, + { NULL }, +}; + AVCodec ff_ansi_decoder = { .name = "ansi", .long_name = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"), @@ -485,4 +491,5 @@ AVCodec ff_ansi_decoder = { .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .defaults = ansi_defaults, }; diff --git a/libavcodec/cbs_av1.h b/libavcodec/cbs_av1.h index fdc629b00c..1adb5ae070 100644 --- a/libavcodec/cbs_av1.h +++ b/libavcodec/cbs_av1.h @@ -158,8 +158,8 @@ typedef struct AV1RawFrameHeader { uint8_t use_superres; uint8_t coded_denom; uint8_t render_and_frame_size_different; - uint8_t render_width_minus_1; - uint8_t render_height_minus_1; + uint16_t render_width_minus_1; + uint16_t render_height_minus_1; uint8_t found_ref[AV1_REFS_PER_FRAME]; @@ -429,6 +429,7 @@ typedef struct CodedBitstreamAV1Context { int operating_point_idc; int bit_depth; + int order_hint; int frame_width; int frame_height; int upscaled_width; diff --git a/libavcodec/cbs_av1_syntax_template.c b/libavcodec/cbs_av1_syntax_template.c index a315e8868a..beab57300f 100644 --- a/libavcodec/cbs_av1_syntax_template.c +++ b/libavcodec/cbs_av1_syntax_template.c @@ -366,7 +366,7 @@ static int FUNC(set_frame_refs)(CodedBitstreamContext *ctx, RWContext *rw, for (i = 0; i < AV1_NUM_REF_FRAMES; i++) shifted_order_hints[i] = cur_frame_hint + cbs_av1_get_relative_dist(seq, priv->ref[i].order_hint, - current->order_hint); + priv->order_hint); latest_order_hint = shifted_order_hints[current->last_frame_idx]; earliest_order_hint = shifted_order_hints[current->golden_frame_idx]; @@ -541,7 +541,7 @@ static int FUNC(frame_size_with_refs)(CodedBitstreamContext *ctx, RWContext *rw, } priv->upscaled_width = ref->upscaled_width; - priv->frame_width = ref->frame_width; + priv->frame_width = priv->upscaled_width; priv->frame_height = ref->frame_height; priv->render_width = ref->render_width; priv->render_height = ref->render_height; @@ -993,7 +993,7 @@ static int FUNC(skip_mode_params)(CodedBitstreamContext *ctx, RWContext *rw, for (i = 0; i < AV1_REFS_PER_FRAME; i++) { ref_hint = priv->ref[current->ref_frame_idx[i]].order_hint; dist = cbs_av1_get_relative_dist(seq, ref_hint, - current->order_hint); + priv->order_hint); if (dist < 0) { if (forward_idx < 0 || cbs_av1_get_relative_dist(seq, ref_hint, @@ -1261,10 +1261,10 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, flag(show_existing_frame); if (current->show_existing_frame) { - AV1ReferenceFrameState *frame; + AV1ReferenceFrameState *ref; fb(3, frame_to_show_map_idx); - frame = &priv->ref[current->frame_to_show_map_idx]; + ref = &priv->ref[current->frame_to_show_map_idx]; if (seq->decoder_model_info_present_flag && !seq->timing_info.equal_picture_interval) { @@ -1275,12 +1275,24 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, if (seq->frame_id_numbers_present_flag) fb(id_len, display_frame_id); - if (frame->frame_type == AV1_FRAME_KEY) + infer(frame_type, ref->frame_type); + if (current->frame_type == AV1_FRAME_KEY) { infer(refresh_frame_flags, all_frames); - else + + // Section 7.21 + infer(current_frame_id, ref->frame_id); + priv->upscaled_width = ref->upscaled_width; + priv->frame_width = ref->frame_width; + priv->frame_height = ref->frame_height; + priv->render_width = ref->render_width; + priv->render_height = ref->render_height; + priv->bit_depth = ref->bit_depth; + priv->order_hint = ref->order_hint; + } else infer(refresh_frame_flags, 0); - return 0; + // Section 7.20 + goto update_refs; } fb(2, frame_type); @@ -1366,6 +1378,7 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, fb(order_hint_bits, order_hint); else infer(order_hint, 0); + priv->order_hint = current->order_hint; if (frame_is_intra || current->error_resilient_mode) infer(primary_ref_frame, AV1_PRIMARY_REF_NONE); @@ -1381,7 +1394,7 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, int in_temporal_layer = (op_pt_idc >> priv->temporal_id ) & 1; int in_spatial_layer = (op_pt_idc >> (priv->spatial_id + 8)) & 1; if (seq->operating_point_idc[i] == 0 || - in_temporal_layer || in_spatial_layer) { + (in_temporal_layer && in_spatial_layer)) { fbs(seq->decoder_model_info.buffer_removal_time_length_minus_1 + 1, buffer_removal_time[i], 1, i); } @@ -1541,6 +1554,16 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, CHECK(FUNC(film_grain_params)(ctx, rw, current)); + av_log(ctx->log_ctx, AV_LOG_DEBUG, "Frame %d: size %dx%d " + "upscaled %d render %dx%d subsample %dx%d " + "bitdepth %d tiles %dx%d.\n", priv->order_hint, + priv->frame_width, priv->frame_height, priv->upscaled_width, + priv->render_width, priv->render_height, + seq->color_config.subsampling_x + 1, + seq->color_config.subsampling_y + 1, priv->bit_depth, + priv->tile_rows, priv->tile_cols); + +update_refs: for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { if (current->refresh_frame_flags & (1 << i)) { priv->ref[i] = (AV1ReferenceFrameState) { @@ -1555,20 +1578,11 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, .subsampling_x = seq->color_config.subsampling_x, .subsampling_y = seq->color_config.subsampling_y, .bit_depth = priv->bit_depth, - .order_hint = current->order_hint, + .order_hint = priv->order_hint, }; } } - av_log(ctx->log_ctx, AV_LOG_DEBUG, "Frame %d: size %dx%d " - "upscaled %d render %dx%d subsample %dx%d " - "bitdepth %d tiles %dx%d.\n", current->order_hint, - priv->frame_width, priv->frame_height, priv->upscaled_width, - priv->render_width, priv->render_height, - seq->color_config.subsampling_x + 1, - seq->color_config.subsampling_y + 1, priv->bit_depth, - priv->tile_rows, priv->tile_cols); - return 0; } diff --git a/libavcodec/celp_filters.c b/libavcodec/celp_filters.c index fafedd99a3..40ff7427df 100644 --- a/libavcodec/celp_filters.c +++ b/libavcodec/celp_filters.c @@ -65,11 +65,11 @@ int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs, int i,n; for (n = 0; n < buffer_length; n++) { - int sum = -rounder, sum1; + int sum = rounder, sum1; for (i = 1; i <= filter_length; i++) - sum += (unsigned)(filter_coeffs[i-1] * out[n-i]); + sum -= (unsigned)(filter_coeffs[i-1] * out[n-i]); - sum1 = ((-sum >> 12) + in[n]) >> shift; + sum1 = ((sum >> 12) + in[n]) >> shift; sum = av_clip_int16(sum1); if (stop_on_overflow && sum != sum1) diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index 7956367b49..fac1892cec 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -503,6 +503,10 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, avpriv_report_missing_feature(avctx, "Transform type of %"PRIu16, data); ret = AVERROR_PATCHWELCOME; break; + } else if (data == 1) { + av_log(avctx, AV_LOG_ERROR, "unsupported transform type\n"); + ret = AVERROR_PATCHWELCOME; + break; } av_log(avctx, AV_LOG_DEBUG, "Transform-type? %"PRIu16"\n", data); } else if (abstag >= 0x4000 && abstag <= 0x40ff) { @@ -607,6 +611,12 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, s->peak.level = 0; } else if (tag == -74 && s->peak.offset) { s->peak.level = data; + if (s->peak.offset < 4 - bytestream2_tell(&s->peak.base) || + s->peak.offset > 4 + bytestream2_get_bytes_left(&s->peak.base) + ) { + ret = AVERROR_INVALIDDATA; + goto end; + } bytestream2_seek(&s->peak.base, s->peak.offset - 4, SEEK_CUR); } else av_log(avctx, AV_LOG_DEBUG, "Unknown tag %i data %x\n", tag, data); diff --git a/libavcodec/cook.c b/libavcodec/cook.c index d0b41a2431..9582495442 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1084,6 +1084,10 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) ff_audiodsp_init(&q->adsp); while (bytestream2_get_bytes_left(&gb)) { + if (s >= FFMIN(MAX_SUBPACKETS, avctx->block_align)) { + avpriv_request_sample(avctx, "subpackets > %d", FFMIN(MAX_SUBPACKETS, avctx->block_align)); + return AVERROR_PATCHWELCOME; + } /* 8 for mono, 16 for stereo, ? for multichannel Swap to right endianness so we don't need to care later on. */ q->subpacket[s].cookversion = bytestream2_get_be32(&gb); @@ -1215,10 +1219,6 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->num_subpackets++; s++; - if (s > FFMIN(MAX_SUBPACKETS, avctx->block_align)) { - avpriv_request_sample(avctx, "subpackets > %d", FFMIN(MAX_SUBPACKETS, avctx->block_align)); - return AVERROR_PATCHWELCOME; - } } /* Try to catch some obviously faulty streams, otherwise it might be exploitable */ diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c index d50ddd6258..f5c93e9912 100644 --- a/libavcodec/cscd.c +++ b/libavcodec/cscd.c @@ -93,7 +93,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, case 1: { // zlib compression #if CONFIG_ZLIB unsigned long dlen = c->decomp_size; - if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK) { + if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK || dlen != c->decomp_size) { av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n"); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c index bce584c9c6..2d6377bc8c 100644 --- a/libavcodec/cuviddec.c +++ b/libavcodec/cuviddec.c @@ -88,7 +88,7 @@ typedef struct CuvidContext CUVIDDECODECAPS caps8, caps10, caps12; CUVIDPARSERPARAMS cuparseinfo; - CUVIDEOFORMATEX cuparse_ext; + CUVIDEOFORMATEX *cuparse_ext; CudaFunctions *cudl; CuvidFunctions *cvdl; @@ -684,6 +684,7 @@ static av_cold int cuvid_decode_end(AVCodecContext *avctx) av_buffer_unref(&ctx->hwdevice); av_freep(&ctx->key_frame); + av_freep(&ctx->cuparse_ext); cuvid_free_functions(&ctx->cvdl); @@ -793,6 +794,8 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) CUVIDSOURCEDATAPACKET seq_pkt; CUcontext cuda_ctx = NULL; CUcontext dummy; + uint8_t *extradata; + int extradata_size; int ret = 0; enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_CUDA, @@ -889,11 +892,8 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) ctx->cudl = device_hwctx->internal->cuda_dl; memset(&ctx->cuparseinfo, 0, sizeof(ctx->cuparseinfo)); - memset(&ctx->cuparse_ext, 0, sizeof(ctx->cuparse_ext)); memset(&seq_pkt, 0, sizeof(seq_pkt)); - ctx->cuparseinfo.pExtVideoInfo = &ctx->cuparse_ext; - switch (avctx->codec->id) { #if CONFIG_H264_CUVID_DECODER case AV_CODEC_ID_H264: @@ -947,17 +947,26 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) if (avctx->codec->bsfs) { const AVCodecParameters *par = avctx->internal->bsf->par_out; - ctx->cuparse_ext.format.seqhdr_data_length = par->extradata_size; - memcpy(ctx->cuparse_ext.raw_seqhdr_data, - par->extradata, - FFMIN(sizeof(ctx->cuparse_ext.raw_seqhdr_data), par->extradata_size)); - } else if (avctx->extradata_size > 0) { - ctx->cuparse_ext.format.seqhdr_data_length = avctx->extradata_size; - memcpy(ctx->cuparse_ext.raw_seqhdr_data, - avctx->extradata, - FFMIN(sizeof(ctx->cuparse_ext.raw_seqhdr_data), avctx->extradata_size)); + extradata = par->extradata; + extradata_size = par->extradata_size; + } else { + extradata = avctx->extradata; + extradata_size = avctx->extradata_size; } + ctx->cuparse_ext = av_mallocz(sizeof(*ctx->cuparse_ext) + + FFMAX(extradata_size - (int)sizeof(ctx->cuparse_ext->raw_seqhdr_data), 0)); + if (!ctx->cuparse_ext) { + ret = AVERROR(ENOMEM); + goto error; + } + + if (extradata_size > 0) + memcpy(ctx->cuparse_ext->raw_seqhdr_data, extradata, extradata_size); + ctx->cuparse_ext->format.seqhdr_data_length = extradata_size; + + ctx->cuparseinfo.pExtVideoInfo = ctx->cuparse_ext; + ctx->key_frame = av_mallocz(ctx->nb_surfaces * sizeof(int)); if (!ctx->key_frame) { ret = AVERROR(ENOMEM); @@ -986,8 +995,8 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) if (ret < 0) goto error; - seq_pkt.payload = ctx->cuparse_ext.raw_seqhdr_data; - seq_pkt.payload_size = ctx->cuparse_ext.format.seqhdr_data_length; + seq_pkt.payload = ctx->cuparse_ext->raw_seqhdr_data; + seq_pkt.payload_size = ctx->cuparse_ext->format.seqhdr_data_length; if (seq_pkt.payload && seq_pkt.payload_size) { ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &seq_pkt)); @@ -1046,8 +1055,8 @@ static void cuvid_flush(AVCodecContext *avctx) if (ret < 0) goto error; - seq_pkt.payload = ctx->cuparse_ext.raw_seqhdr_data; - seq_pkt.payload_size = ctx->cuparse_ext.format.seqhdr_data_length; + seq_pkt.payload = ctx->cuparse_ext->raw_seqhdr_data; + seq_pkt.payload_size = ctx->cuparse_ext->format.seqhdr_data_length; if (seq_pkt.payload && seq_pkt.payload_size) { ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &seq_pkt)); diff --git a/libavcodec/decode.c b/libavcodec/decode.c index a4e50c0d03..a190c3901a 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1858,7 +1858,8 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) int ret; if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - if ((ret = av_image_check_size2(FFALIGN(avctx->width, STRIDE_ALIGN), avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) { + if ((unsigned)avctx->width > INT_MAX - STRIDE_ALIGN || + (ret = av_image_check_size2(FFALIGN(avctx->width, STRIDE_ALIGN), avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) { av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n"); ret = AVERROR(EINVAL); goto fail; diff --git a/libavcodec/dirac_parser.c b/libavcodec/dirac_parser.c index fbc7414c79..8e68b4a9da 100644 --- a/libavcodec/dirac_parser.c +++ b/libavcodec/dirac_parser.c @@ -215,7 +215,7 @@ static int dirac_combine_frame(AVCodecParserContext *s, AVCodecContext *avctx, int64_t pts = AV_RB32(cur_pu + 13); if (s->last_pts == 0 && s->last_dts == 0) s->dts = pts - 1; - else + else if (s->last_dts != AV_NOPTS_VALUE) s->dts = s->last_dts + 1; s->pts = pts; if (!avctx->has_b_frames && (cur_pu[4] & 0x03)) diff --git a/libavcodec/diracdsp.c b/libavcodec/diracdsp.c index 2dd56f83f3..4e08d3817e 100644 --- a/libavcodec/diracdsp.c +++ b/libavcodec/diracdsp.c @@ -198,9 +198,9 @@ static void dequant_subband_ ## PX ## _c(uint8_t *src, uint8_t *dst, ptrdiff_t s PX c, sign, *src_r = (PX *)src, *dst_r = (PX *)dst; \ for (i = 0; i < tot_h; i++) { \ c = *src_r++; \ - sign = FFSIGN(c)*(!!c); \ - c = (FFABS(c)*(unsigned)qf + qs) >> 2; \ - *dst_r++ = c*sign; \ + if (c < 0) c = -((-(unsigned)c*qf + qs) >> 2); \ + else if(c > 0) c = (( (unsigned)c*qf + qs) >> 2); \ + *dst_r++ = c; \ } \ src += tot_h << (sizeof(PX) >> 1); \ dst += stride; \ diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c index 4dd675316b..e5d710069d 100644 --- a/libavcodec/dxtory.c +++ b/libavcodec/dxtory.c @@ -456,7 +456,7 @@ static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame, V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80; } - Y += ystride << 2; + Y += ystride * 4; U += ustride; V += vstride; } @@ -501,7 +501,7 @@ static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80; } - Y += ystride << 1; + Y += ystride * 2; U += ustride; V += vstride; } diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 6a0700cc10..2e008c8f6f 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -1051,6 +1051,9 @@ static int decode_block(AVCodecContext *avctx, void *tdata, if ((col + td->xsize) != s->xdelta)/* not the last tile of the line */ axmax = 0; /* doesn't add pixel at the right of the datawindow */ + if (td->xsize * (uint64_t)s->current_channel_offset > INT_MAX) + return AVERROR_INVALIDDATA; + td->channel_line_size = td->xsize * s->current_channel_offset;/* uncompress size of one line */ uncompressed_size = td->channel_line_size * (uint64_t)td->ysize;/* uncompress size of the block */ } else { @@ -1070,6 +1073,9 @@ static int decode_block(AVCodecContext *avctx, void *tdata, td->ysize = FFMIN(s->scan_lines_per_block, s->ymax - line + 1); /* s->ydelta - line ?? */ td->xsize = s->xdelta; + if (td->xsize * (uint64_t)s->current_channel_offset > INT_MAX) + return AVERROR_INVALIDDATA; + td->channel_line_size = td->xsize * s->current_channel_offset;/* uncompress size of one line */ uncompressed_size = td->channel_line_size * (uint64_t)td->ysize;/* uncompress size of the block */ @@ -1493,15 +1499,27 @@ static int decode_header(EXRContext *s, AVFrame *frame) continue; } else if ((var_size = check_header_variable(s, "dataWindow", "box2i", 31)) >= 0) { + int xmin, ymin, xmax, ymax; if (!var_size) { ret = AVERROR_INVALIDDATA; goto fail; } - s->xmin = bytestream2_get_le32(&s->gb); - s->ymin = bytestream2_get_le32(&s->gb); - s->xmax = bytestream2_get_le32(&s->gb); - s->ymax = bytestream2_get_le32(&s->gb); + xmin = bytestream2_get_le32(&s->gb); + ymin = bytestream2_get_le32(&s->gb); + xmax = bytestream2_get_le32(&s->gb); + ymax = bytestream2_get_le32(&s->gb); + + if (xmin > xmax || ymin > ymax || + (unsigned)xmax - xmin >= INT_MAX || + (unsigned)ymax - ymin >= INT_MAX) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + s->xmin = xmin; + s->xmax = xmax; + s->ymin = ymin; + s->ymax = ymax; s->xdelta = (s->xmax - s->xmin) + 1; s->ydelta = (s->ymax - s->ymin) + 1; @@ -1734,7 +1752,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, s->ymin > s->ymax || s->xdelta != s->xmax - s->xmin + 1 || s->xmax >= s->w || - s->ymax >= s->h) { + s->ymax >= s->h || + s->ydelta == 0xFFFFFFFF || s->xdelta == 0xFFFFFFFF + ) { av_log(avctx, AV_LOG_ERROR, "Wrong or missing size information.\n"); return AVERROR_INVALIDDATA; } @@ -1765,7 +1785,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) return ret; - if (bytestream2_get_bytes_left(&s->gb) < nb_blocks * 8) + if (bytestream2_get_bytes_left(&s->gb)/8 < nb_blocks) return AVERROR_INVALIDDATA; // check offset table and recreate it if need diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index c704373cfe..0a3f425493 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -786,7 +786,7 @@ static int read_header(FFV1Context *f) if (f->version == 2) { int idx = get_symbol(c, state, 0); - if (idx > (unsigned)f->quant_table_count) { + if (idx >= (unsigned)f->quant_table_count) { av_log(f->avctx, AV_LOG_ERROR, "quant_table_index out of range\n"); return AVERROR_INVALIDDATA; diff --git a/libavcodec/ffwavesynth.c b/libavcodec/ffwavesynth.c index 8d3ac81aef..d92bb38c45 100644 --- a/libavcodec/ffwavesynth.c +++ b/libavcodec/ffwavesynth.c @@ -373,7 +373,7 @@ static void wavesynth_synth_sample(struct wavesynth_context *ws, int64_t ts, in->amp += in->damp; switch (in->type) { case WS_SINE: - val = amp * ws->sin[in->phi >> (64 - SIN_BITS)]; + val = amp * (unsigned)ws->sin[in->phi >> (64 - SIN_BITS)]; in->phi += in->dphi; in->dphi += in->ddphi; break; diff --git a/libavcodec/fits.c b/libavcodec/fits.c index ad73ab70de..97fa7abe80 100644 --- a/libavcodec/fits.c +++ b/libavcodec/fits.c @@ -187,6 +187,8 @@ int avpriv_fits_header_parse_line(void *avcl, FITSHeader *header, const uint8_t header->blank = t; header->blank_found = 1; } else if (!strcmp(keyword, "BSCALE") && sscanf(value, "%lf", &d) == 1) { + if (d <= 0) + return AVERROR_INVALIDDATA; header->bscale = d; } else if (!strcmp(keyword, "BZERO") && sscanf(value, "%lf", &d) == 1) { header->bzero = d; @@ -203,8 +205,12 @@ int avpriv_fits_header_parse_line(void *avcl, FITSHeader *header, const uint8_t } else if (!strcmp(keyword, "GROUPS") && sscanf(value, "%c", &c) == 1) { header->groups = (c == 'T'); } else if (!strcmp(keyword, "GCOUNT") && sscanf(value, "%"SCNd64"", &t) == 1) { + if (t < 0 || t > INT_MAX) + return AVERROR_INVALIDDATA; header->gcount = t; } else if (!strcmp(keyword, "PCOUNT") && sscanf(value, "%"SCNd64"", &t) == 1) { + if (t < 0 || t > INT_MAX) + return AVERROR_INVALIDDATA; header->pcount = t; } dict_set_if_not_null(metadata, keyword, value); diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c index 622cac2251..83229f620a 100644 --- a/libavcodec/frame_thread_encoder.c +++ b/libavcodec/frame_thread_encoder.c @@ -118,7 +118,7 @@ end: int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ int i=0; ThreadContext *c; - AVCodecContext *thread_avctx = NULL; + if( !(avctx->thread_type & FF_THREAD_FRAME) || !(avctx->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS)) @@ -196,17 +196,16 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ AVDictionary *tmp = NULL; int ret; void *tmpv; - thread_avctx = avcodec_alloc_context3(avctx->codec); + AVCodecContext *thread_avctx = avcodec_alloc_context3(avctx->codec); if(!thread_avctx) goto fail; tmpv = thread_avctx->priv_data; *thread_avctx = *avctx; - thread_avctx->priv_data = tmpv; - thread_avctx->internal = NULL; - thread_avctx->hw_frames_ctx = NULL; ret = av_opt_copy(thread_avctx, avctx); if (ret < 0) goto fail; + thread_avctx->priv_data = tmpv; + thread_avctx->internal = NULL; if (avctx->codec->priv_class) { int ret = av_opt_copy(thread_avctx->priv_data, avctx->priv_data); if (ret < 0) @@ -235,8 +234,6 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ return 0; fail: - avcodec_close(thread_avctx); - av_freep(&thread_avctx); avctx->thread_count = i; av_log(avctx, AV_LOG_ERROR, "ff_frame_thread_encoder_init failed\n"); ff_frame_thread_encoder_free(avctx); diff --git a/libavcodec/frame_thread_encoder.h b/libavcodec/frame_thread_encoder.h index fc85ba48b8..1f79553f20 100644 --- a/libavcodec/frame_thread_encoder.h +++ b/libavcodec/frame_thread_encoder.h @@ -23,10 +23,6 @@ #include "avcodec.h" -/** - * Initialize frame thread encoder. - * @note hardware encoders are not supported - */ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options); void ff_frame_thread_encoder_free(AVCodecContext *avctx); int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr); diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 713953778a..4e3abf859b 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1599,7 +1599,7 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl, prev->f->format, prev->f->width, prev->f->height); - h->short_ref[0]->poc = prev->poc + 2; + h->short_ref[0]->poc = prev->poc + 2U; } else if (!h->frame_recovered && !h->avctx->hwaccel) ff_color_frame(h->short_ref[0]->f, c); h->short_ref[0]->frame_num = h->poc.prev_frame_num; diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c index 5993ae2e6e..ce66ed3ab8 100644 --- a/libavcodec/h264idct_template.c +++ b/libavcodec/h264idct_template.c @@ -278,13 +278,13 @@ void FUNCC(ff_h264_chroma422_dc_dequant_idct)(int16_t *_block, int qmul){ const int stride= 16*2; const int xStride= 16; int i; - int temp[8]; + unsigned temp[8]; static const uint8_t x_offset[2]={0, 16}; dctcoef *block = (dctcoef*)_block; for(i=0; i<4; i++){ - temp[2*i+0] = block[stride*i + xStride*0] + block[stride*i + xStride*1]; - temp[2*i+1] = block[stride*i + xStride*0] - block[stride*i + xStride*1]; + temp[2*i+0] = block[stride*i + xStride*0] + (unsigned)block[stride*i + xStride*1]; + temp[2*i+1] = block[stride*i + xStride*0] - (unsigned)block[stride*i + xStride*1]; } for(i=0; i<2; i++){ diff --git a/libavcodec/hap.h b/libavcodec/hap.h index bbeed11e32..00c3dbb32d 100644 --- a/libavcodec/hap.h +++ b/libavcodec/hap.h @@ -52,7 +52,7 @@ enum HapSectionType { typedef struct HapChunk { enum HapCompressor compressor; - int compressed_offset; + uint32_t compressed_offset; size_t compressed_size; int uncompressed_offset; size_t uncompressed_size; diff --git a/libavcodec/hapdec.c b/libavcodec/hapdec.c index ab364aa790..692bb6e750 100644 --- a/libavcodec/hapdec.c +++ b/libavcodec/hapdec.c @@ -105,6 +105,8 @@ static int hap_parse_decode_instructions(HapContext *ctx, int size) size_t running_size = 0; for (i = 0; i < ctx->chunk_count; i++) { ctx->chunks[i].compressed_offset = running_size; + if (ctx->chunks[i].compressed_size > UINT32_MAX - running_size) + return AVERROR_INVALIDDATA; running_size += ctx->chunks[i].compressed_size; } } @@ -186,7 +188,7 @@ static int hap_parse_frame_header(AVCodecContext *avctx) HapChunk *chunk = &ctx->chunks[i]; /* Check the compressed buffer is valid */ - if (chunk->compressed_offset + chunk->compressed_size > bytestream2_get_bytes_left(gbc)) + if (chunk->compressed_offset + (uint64_t)chunk->compressed_size > bytestream2_get_bytes_left(gbc)) return AVERROR_INVALIDDATA; /* Chunks are unpacked sequentially, ctx->tex_size is the uncompressed diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c index 3dc0987dad..3635b16ca9 100644 --- a/libavcodec/hevc_cabac.c +++ b/libavcodec/hevc_cabac.c @@ -998,7 +998,7 @@ static av_always_inline int coeff_abs_level_remaining_decode(HEVCContext *s, int } else { int prefix_minus3 = prefix - 3; - if (prefix == CABAC_MAX_BIN || prefix_minus3 + rc_rice_param >= 31) { + if (prefix == CABAC_MAX_BIN || prefix_minus3 + rc_rice_param > 16 + 6) { av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", prefix); return 0; } diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index ea6fd536c6..139f3deeda 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -816,7 +816,11 @@ static int scaling_list_data(GetBitContext *gb, AVCodecContext *avctx, ScalingLi next_coef = 8; coef_num = FFMIN(64, 1 << (4 + (size_id << 1))); if (size_id > 1) { - scaling_list_dc_coef[size_id - 2][matrix_id] = get_se_golomb(gb) + 8; + int scaling_list_coeff_minus8 = get_se_golomb(gb); + if (scaling_list_coeff_minus8 < -7 || + scaling_list_coeff_minus8 > 247) + return AVERROR_INVALIDDATA; + scaling_list_dc_coef[size_id - 2][matrix_id] = scaling_list_coeff_minus8 + 8; next_coef = scaling_list_dc_coef[size_id - 2][matrix_id]; sl->sl_dc[size_id - 2][matrix_id] = next_coef; } diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index 60570690cf..b4b90b570b 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -343,6 +343,8 @@ static int decode_nal_sei_message(GetBitContext *gb, void *logctx, HEVCSEI *s, byte = get_bits(gb, 8); payload_size += byte; } + if (get_bits_left(gb) < 8LL*payload_size) + return AVERROR_INVALIDDATA; if (nal_unit_type == HEVC_NAL_SEI_PREFIX) { return decode_nal_sei_prefix(gb, logctx, s, ps, payload_type, payload_size); } else { /* nal_unit_type == NAL_SEI_SUFFIX */ diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 0772608a30..1eaeaf72f1 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -785,6 +785,11 @@ static int hls_slice_header(HEVCContext *s) if (s->ps.pps->pic_slice_level_chroma_qp_offsets_present_flag) { sh->slice_cb_qp_offset = get_se_golomb(gb); sh->slice_cr_qp_offset = get_se_golomb(gb); + if (sh->slice_cb_qp_offset < -12 || sh->slice_cb_qp_offset > 12 || + sh->slice_cr_qp_offset < -12 || sh->slice_cr_qp_offset > 12) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid slice cx qp offset.\n"); + return AVERROR_INVALIDDATA; + } } else { sh->slice_cb_qp_offset = 0; sh->slice_cr_qp_offset = 0; diff --git a/libavcodec/hevcpred_template.c b/libavcodec/hevcpred_template.c index 6fe33546b1..f1a1f4c1f0 100644 --- a/libavcodec/hevcpred_template.c +++ b/libavcodec/hevcpred_template.c @@ -83,6 +83,7 @@ do { \ int y = y0 >> vshift; int x_tb = (x0 >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask; int y_tb = (y0 >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask; + int spin = c_idx && !size_in_tbs_v && ((2 * y0) & (1 << s->ps.sps->log2_min_tb_size)); int cur_tb_addr = MIN_TB_ADDR_ZS(x_tb, y_tb); @@ -103,11 +104,11 @@ do { \ pixel *top = top_array + 1; pixel *filtered_left = filtered_left_array + 1; pixel *filtered_top = filtered_top_array + 1; - int cand_bottom_left = lc->na.cand_bottom_left && cur_tb_addr > MIN_TB_ADDR_ZS( x_tb - 1, (y_tb + size_in_tbs_v) & s->ps.sps->tb_mask); + int cand_bottom_left = lc->na.cand_bottom_left && cur_tb_addr > MIN_TB_ADDR_ZS( x_tb - 1, (y_tb + size_in_tbs_v + spin) & s->ps.sps->tb_mask); int cand_left = lc->na.cand_left; int cand_up_left = lc->na.cand_up_left; int cand_up = lc->na.cand_up; - int cand_up_right = lc->na.cand_up_right && cur_tb_addr > MIN_TB_ADDR_ZS((x_tb + size_in_tbs_h) & s->ps.sps->tb_mask, y_tb - 1); + int cand_up_right = lc->na.cand_up_right && !spin && cur_tb_addr > MIN_TB_ADDR_ZS((x_tb + size_in_tbs_h) & s->ps.sps->tb_mask, y_tb - 1); int bottom_left_size = (FFMIN(y0 + 2 * size_in_luma_v, s->ps.sps->height) - (y0 + size_in_luma_v)) >> vshift; diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index ab36009a2d..fad614e03a 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -2207,8 +2207,12 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s) return 0; } atom_size = bytestream2_get_be32u(&s->g); + if (atom_size < 16 || (int64_t)bytestream2_tell(&s->g) + atom_size - 16 > INT_MAX) + return AVERROR_INVALIDDATA; atom_end = bytestream2_tell(&s->g) + atom_size - 16; } else { + if (atom_size < 8 || (int64_t)bytestream2_tell(&s->g) + atom_size - 8 > INT_MAX) + return AVERROR_INVALIDDATA; atom_end = bytestream2_tell(&s->g) + atom_size - 8; } diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index 0b1e139048..fd4eb234bc 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -149,7 +149,7 @@ static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q) { int k, ret; - for (k = 0; (state->N[Q] << k) < state->A[Q]; k++) + for (k = 0; ((unsigned)state->N[Q] << k) < state->A[Q]; k++) ; #ifdef JLS_BROKEN diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c index 5d76274d54..731854959e 100644 --- a/libavcodec/magicyuv.c +++ b/libavcodec/magicyuv.c @@ -695,6 +695,9 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, s->slices[i][j].start = offset + header_size; s->slices[i][j].size = avpkt->size - s->slices[i][j].start; + + if (s->slices[i][j].size < 2) + return AVERROR_INVALIDDATA; } if (bytestream2_get_byte(&gbyte) != s->planes) diff --git a/libavcodec/mpc.c b/libavcodec/mpc.c index 6cf9b9d520..e56b608d8c 100644 --- a/libavcodec/mpc.c +++ b/libavcodec/mpc.c @@ -75,17 +75,17 @@ void ff_mpc_dequantize_and_synth(MPCContext * c, int maxband, int16_t **out, j = 0; mul = (mpc_CC+1)[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][0] & 0xFF]; for(; j < 12; j++) - c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; + c->sb_samples[ch][j][i] = av_clipf(mul * c->Q[ch][j + off], INT32_MIN, INT32_MAX); mul = (mpc_CC+1)[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][1] & 0xFF]; for(; j < 24; j++) - c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; + c->sb_samples[ch][j][i] = av_clipf(mul * c->Q[ch][j + off], INT32_MIN, INT32_MAX); mul = (mpc_CC+1)[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][2] & 0xFF]; for(; j < 36; j++) - c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; + c->sb_samples[ch][j][i] = av_clipf(mul * c->Q[ch][j + off], INT32_MIN, INT32_MAX); } } if(bands[i].msf){ - int t1, t2; + unsigned t1, t2; for(j = 0; j < SAMPLES_PER_BAND; j++){ t1 = c->sb_samples[0][j][i]; t2 = c->sb_samples[1][j][i]; diff --git a/libavcodec/mv30.c b/libavcodec/mv30.c index c83ba7ffbd..59088d84f8 100644 --- a/libavcodec/mv30.c +++ b/libavcodec/mv30.c @@ -102,25 +102,25 @@ static void get_qtable(int16_t *table, int quant, const uint8_t *quant_tab) } } -static inline void idct_1d(int *blk, int step) +static inline void idct_1d(unsigned *blk, int step) { - const int t0 = blk[0 * step] + blk[4 * step]; - const int t1 = blk[0 * step] - blk[4 * step]; - const int t2 = blk[2 * step] + blk[6 * step]; - const int t3 = ((int)((blk[2 * step] - blk[6 * step]) * 362U) >> 8) - t2; - const int t4 = t0 + t2; - const int t5 = t0 - t2; - const int t6 = t1 + t3; - const int t7 = t1 - t3; - const int t8 = blk[5 * step] + blk[3 * step]; - const int t9 = blk[5 * step] - blk[3 * step]; - const int tA = blk[1 * step] + blk[7 * step]; - const int tB = blk[1 * step] - blk[7 * step]; - const int tC = t8 + tA; - const int tD = (int)((tB + t9) * 473U) >> 8; - const int tE = (((int)(t9 * -669U) >> 8) - tC) + tD; - const int tF = ((int)((tA - t8) * 362U) >> 8) - tE; - const int t10 = (((int)(tB * 277U) >> 8) - tD) + tF; + const unsigned t0 = blk[0 * step] + blk[4 * step]; + const unsigned t1 = blk[0 * step] - blk[4 * step]; + const unsigned t2 = blk[2 * step] + blk[6 * step]; + const unsigned t3 = ((int)((blk[2 * step] - blk[6 * step]) * 362U) >> 8) - t2; + const unsigned t4 = t0 + t2; + const unsigned t5 = t0 - t2; + const unsigned t6 = t1 + t3; + const unsigned t7 = t1 - t3; + const unsigned t8 = blk[5 * step] + blk[3 * step]; + const unsigned t9 = blk[5 * step] - blk[3 * step]; + const unsigned tA = blk[1 * step] + blk[7 * step]; + const unsigned tB = blk[1 * step] - blk[7 * step]; + const unsigned tC = t8 + tA; + const unsigned tD = (int)((tB + t9) * 473U) >> 8; + const unsigned tE = (((int)(t9 * -669U) >> 8) - tC) + tD; + const unsigned tF = ((int)((tA - t8) * 362U) >> 8) - tE; + const unsigned t10 = (((int)(tB * 277U) >> 8) - tD) + tF; blk[0 * step] = t4 + tC; blk[1 * step] = t6 + tE; @@ -198,12 +198,12 @@ static void idct_add(uint8_t *dst, int stride, static inline void idct2_1d(int *blk, int step) { - const int t0 = blk[0 * step]; - const int t1 = blk[1 * step]; - const int t2 = (int)(t1 * 473U) >> 8; - const int t3 = t2 - t1; - const int t4 = ((int)(t1 * 362U) >> 8) - t3; - const int t5 = (((int)(t1 * 277U) >> 8) - t2) + t4; + const unsigned int t0 = blk[0 * step]; + const unsigned int t1 = blk[1 * step]; + const unsigned int t2 = (int)(t1 * 473U) >> 8; + const unsigned int t3 = t2 - t1; + const unsigned int t4 = ((int)(t1 * 362U) >> 8) - t3; + const unsigned int t5 = (((int)(t1 * 277U) >> 8) - t2) + t4; blk[0 * step] = t1 + t0; blk[1 * step] = t0 + t3; @@ -305,14 +305,14 @@ static int decode_intra_block(AVCodecContext *avctx, int mode, case 1: fill = sign_extend(bytestream2_get_ne16(gbyte), 16); pfill[0] += fill; - block[0] = ((pfill[0] * qtab[0]) >> 5) + 128; + block[0] = ((int)((unsigned)pfill[0] * qtab[0]) >> 5) + 128; s->bdsp.fill_block_tab[1](dst, block[0], linesize, 8); break; case 2: memset(block, 0, sizeof(*block) * 64); fill = sign_extend(bytestream2_get_ne16(gbyte), 16); pfill[0] += fill; - block[0] = pfill[0] * qtab[0]; + block[0] = (unsigned)pfill[0] * qtab[0]; block[1] = sign_extend(bytestream2_get_ne16(gbyte), 16) * qtab[1]; block[8] = sign_extend(bytestream2_get_ne16(gbyte), 16) * qtab[8]; block[9] = sign_extend(bytestream2_get_ne16(gbyte), 16) * qtab[9]; @@ -321,7 +321,7 @@ static int decode_intra_block(AVCodecContext *avctx, int mode, case 3: fill = sign_extend(bytestream2_get_ne16(gbyte), 16); pfill[0] += fill; - block[0] = pfill[0] * qtab[0]; + block[0] = (unsigned)pfill[0] * qtab[0]; for (int i = 1; i < 64; i++) block[zigzag[i]] = sign_extend(bytestream2_get_ne16(gbyte), 16) * qtab[zigzag[i]]; idct_put(dst, linesize, block); @@ -346,14 +346,14 @@ static int decode_inter_block(AVCodecContext *avctx, int mode, case 1: fill = sign_extend(bytestream2_get_ne16(gbyte), 16); pfill[0] += fill; - block[0] = (pfill[0] * qtab[0]) >> 5; + block[0] = (int)((unsigned)pfill[0] * qtab[0]) >> 5; update_inter_block(dst, linesize, src, in_linesize, block[0]); break; case 2: memset(block, 0, sizeof(*block) * 64); fill = sign_extend(bytestream2_get_ne16(gbyte), 16); pfill[0] += fill; - block[0] = pfill[0] * qtab[0]; + block[0] = (unsigned)pfill[0] * qtab[0]; block[1] = sign_extend(bytestream2_get_ne16(gbyte), 16) * qtab[1]; block[8] = sign_extend(bytestream2_get_ne16(gbyte), 16) * qtab[8]; block[9] = sign_extend(bytestream2_get_ne16(gbyte), 16) * qtab[9]; @@ -362,7 +362,7 @@ static int decode_inter_block(AVCodecContext *avctx, int mode, case 3: fill = sign_extend(bytestream2_get_ne16(gbyte), 16); pfill[0] += fill; - block[0] = pfill[0] * qtab[0]; + block[0] = (unsigned)pfill[0] * qtab[0]; for (int i = 1; i < 64; i++) block[zigzag[i]] = sign_extend(bytestream2_get_ne16(gbyte), 16) * qtab[zigzag[i]]; idct_add(dst, linesize, src, in_linesize, block); @@ -531,8 +531,13 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, for (int x = 0; x < avctx->width; x += 16) { if (cnt >= 4) cnt = 0; - if (cnt == 0) + if (cnt == 0) { + if (get_bits_left(&mask) < 8) { + ret = AVERROR_INVALIDDATA; + goto fail; + } flags = get_bits(&mask, 8); + } dst[0] = frame->data[0] + linesize[0] * y + x; dst[1] = frame->data[0] + linesize[0] * y + x + 8; diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c index 55ec6e928e..f89226fefa 100644 --- a/libavcodec/mxpegdec.c +++ b/libavcodec/mxpegdec.c @@ -247,16 +247,17 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, "Multiple SOF in a frame\n"); return AVERROR_INVALIDDATA; } - s->got_sof_data = 0; ret = ff_mjpeg_decode_sof(jpg); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "SOF data decode error\n"); + s->got_sof_data = 0; return ret; } if (jpg->interlaced) { av_log(avctx, AV_LOG_ERROR, "Interlaced mode not supported in MxPEG\n"); + s->got_sof_data = 0; return AVERROR(EINVAL); } s->got_sof_data ++; diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index e269c716a4..03fdd70029 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1829,7 +1829,7 @@ static int nvenc_set_timestamp(AVCodecContext *avctx, pkt->pts = params->outputTimeStamp; pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list); - pkt->dts -= FFMAX(avctx->max_b_frames, 0) * FFMIN(avctx->ticks_per_frame, 1); + pkt->dts -= FFMAX(avctx->max_b_frames, 0) * FFMAX(avctx->ticks_per_frame, 1); return 0; } diff --git a/libavcodec/opus_silk.c b/libavcodec/opus_silk.c index 2fcbf3b9d3..913053c5e2 100644 --- a/libavcodec/opus_silk.c +++ b/libavcodec/opus_silk.c @@ -506,7 +506,8 @@ static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc, #define LTP_ORDER 5 static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc, - int frame_num, int channel, int coded_channels, int active, int active1) + int frame_num, int channel, int coded_channels, + int active, int active1, int redundant) { /* per frame */ int voiced; // combines with active to indicate inactive, active, or active+voiced @@ -665,8 +666,9 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc, silk_decode_excitation(s, rc, residual + SILK_MAX_LAG, qoffset_high, active, voiced); - /* skip synthesising the side channel if we want mono-only */ - if (s->output_channels == channel) + /* skip synthesising the output if we do not need it */ + // TODO: implement error recovery + if (s->output_channels == channel || redundant) return; /* generate the output signal */ @@ -814,15 +816,27 @@ int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc, active[i][j] = ff_opus_rc_dec_log(rc, 1); redundancy[i] = ff_opus_rc_dec_log(rc, 1); - if (redundancy[i]) { - avpriv_report_missing_feature(s->avctx, "LBRR frames"); - return AVERROR_PATCHWELCOME; + } + + /* read the per-frame LBRR flags */ + for (i = 0; i < coded_channels; i++) + if (redundancy[i] && duration_ms > 20) { + redundancy[i] = ff_opus_rc_dec_cdf(rc, duration_ms == 40 ? + ff_silk_model_lbrr_flags_40 : ff_silk_model_lbrr_flags_60); } + + /* decode the LBRR frames */ + for (i = 0; i < nb_frames; i++) { + for (j = 0; j < coded_channels; j++) + if (redundancy[j] & (1 << i)) { + int active1 = (j == 0 && !(redundancy[1] & (1 << i))) ? 0 : 1; + silk_decode_frame(s, rc, i, j, coded_channels, 1, active1, 1); + } } for (i = 0; i < nb_frames; i++) { for (j = 0; j < coded_channels && !s->midonly; j++) - silk_decode_frame(s, rc, i, j, coded_channels, active[j][i], active[1][i]); + silk_decode_frame(s, rc, i, j, coded_channels, active[j][i], active[1][i], 0); /* reset the side channel if it is not coded */ if (s->midonly && s->frame[1].coded) diff --git a/libavcodec/opustab.c b/libavcodec/opustab.c index fb340e07e8..64070f8299 100644 --- a/libavcodec/opustab.c +++ b/libavcodec/opustab.c @@ -26,6 +26,9 @@ const uint8_t ff_opus_default_coupled_streams[] = { 0, 1, 1, 2, 2, 2, 2, 3 }; const uint8_t ff_celt_band_end[] = { 13, 17, 17, 19, 21 }; +const uint16_t ff_silk_model_lbrr_flags_40[] = { 256, 0, 53, 106, 256 }; +const uint16_t ff_silk_model_lbrr_flags_60[] = { 256, 0, 41, 61, 90, 131, 146, 174, 256 }; + const uint16_t ff_silk_model_stereo_s1[] = { 256, 7, 9, 10, 11, 12, 22, 46, 54, 55, 56, 59, 82, 174, 197, 200, 201, 202, 210, 234, 244, 245, 246, 247, 249, 256 diff --git a/libavcodec/opustab.h b/libavcodec/opustab.h index bce5a42830..892126bb23 100644 --- a/libavcodec/opustab.h +++ b/libavcodec/opustab.h @@ -31,6 +31,9 @@ extern const uint8_t ff_celt_band_end[]; extern const uint8_t ff_opus_default_coupled_streams[]; +extern const uint16_t ff_silk_model_lbrr_flags_40[]; +extern const uint16_t ff_silk_model_lbrr_flags_60[]; + extern const uint16_t ff_silk_model_stereo_s1[]; extern const uint16_t ff_silk_model_stereo_s2[]; extern const uint16_t ff_silk_model_stereo_s3[]; diff --git a/libavcodec/pnm_parser.c b/libavcodec/pnm_parser.c index d19dbfe98c..f3be6d640c 100644 --- a/libavcodec/pnm_parser.c +++ b/libavcodec/pnm_parser.c @@ -109,8 +109,10 @@ retry: if (next == END_NOT_FOUND) pnmpc->ascii_scan = sync - pnmctx.bytestream + skip; } else { - next = pnmctx.bytestream - pnmctx.bytestream_start + skip - + av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1); + int ret = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1); + next = pnmctx.bytestream - pnmctx.bytestream_start + skip; + if (ret >= 0) + next += ret; } if (next != END_NOT_FOUND && pnmctx.bytestream_start != buf + skip) next -= pc->index; diff --git a/libavcodec/rasc.c b/libavcodec/rasc.c index cdf20a6db9..706940bf5f 100644 --- a/libavcodec/rasc.c +++ b/libavcodec/rasc.c @@ -70,6 +70,9 @@ static void clear_plane(AVCodecContext *avctx, AVFrame *frame) RASCContext *s = avctx->priv_data; uint8_t *dst = frame->data[0]; + if (!dst) + return; + for (int y = 0; y < avctx->height; y++) { memset(dst, 0, avctx->width * s->bpp); dst += frame->linesize[0]; diff --git a/libavcodec/rscc.c b/libavcodec/rscc.c index bd0520950f..07a7c3dca3 100644 --- a/libavcodec/rscc.c +++ b/libavcodec/rscc.c @@ -300,6 +300,10 @@ static int rscc_decode_frame(AVCodecContext *avctx, void *data, ret = AVERROR_INVALIDDATA; goto end; } + if (ctx->inflated_size < pixel_size) { + ret = AVERROR_INVALIDDATA; + goto end; + } ret = uncompress(ctx->inflated_buf, &len, gbc->buffer, packed_size); if (ret) { av_log(avctx, AV_LOG_ERROR, "Pixel deflate error %d.\n", ret); diff --git a/libavcodec/simple_idct.c b/libavcodec/simple_idct.c index 3b2e736538..0ef167491a 100644 --- a/libavcodec/simple_idct.c +++ b/libavcodec/simple_idct.c @@ -175,7 +175,8 @@ static inline void idct4col_add(uint8_t *dest, ptrdiff_t line_size, const int16_ #define R_SHIFT 11 static inline void idct4row(int16_t *row) { - int c0, c1, c2, c3, a0, a1, a2, a3; + unsigned c0, c1, c2, c3; + int a0, a1, a2, a3; a0 = row[0]; a1 = row[1]; diff --git a/libavcodec/siren.c b/libavcodec/siren.c index 1c17d4505d..1998fa4e6e 100644 --- a/libavcodec/siren.c +++ b/libavcodec/siren.c @@ -341,12 +341,12 @@ static const float mlt_quant[7][14] = { { 0.0f, 1.964f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }; -static const float noise_category5[20] = { +static const float noise_category5[21] = { 0.70711f, 0.6179f, 0.5005f, 0.3220f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f, 0.17678f }; -static const float noise_category6[20] = { +static const float noise_category6[21] = { 0.70711f, 0.5686f, 0.3563f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f }; diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index b4c463b4b9..07c713c90a 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -491,6 +491,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, case SMK_BLK_FULL: mode = 0; if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes + if (get_bits_left(&gb) < 1) + return AVERROR_INVALIDDATA; if(get_bits1(&gb)) mode = 1; else if(get_bits1(&gb)) mode = 2; } diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c index 88664dc472..5e69f39022 100644 --- a/libavcodec/snowdec.c +++ b/libavcodec/snowdec.c @@ -369,7 +369,10 @@ static int decode_header(SnowContext *s){ htaps = htaps*2 + 2; p->htaps= htaps; for(i= htaps/2; i; i--){ - p->hcoeff[i]= get_symbol(&s->c, s->header_state, 0) * (1-2*(i&1)); + unsigned hcoeff = get_symbol(&s->c, s->header_state, 0); + if (hcoeff > 127) + return AVERROR_INVALIDDATA; + p->hcoeff[i]= hcoeff * (1-2*(i&1)); sum += p->hcoeff[i]; } p->hcoeff[0]= 32-sum; diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c index b82c44344c..c635005bec 100644 --- a/libavcodec/sonic.c +++ b/libavcodec/sonic.c @@ -980,9 +980,7 @@ static av_cold int sonic_decode_close(AVCodecContext *avctx) av_freep(&s->int_samples); av_freep(&s->tap_quant); av_freep(&s->predictor_k); - - for (i = 0; i < s->channels; i++) - { + for (i = 0; i < MAX_CHANNELS; i++) { av_freep(&s->predictor_state[i]); av_freep(&s->coded_samples[i]); } @@ -1033,6 +1031,9 @@ static int sonic_decode_frame(AVCodecContext *avctx, { int x = ch; + if (c.overread > MAX_OVERREAD) + return AVERROR_INVALIDDATA; + predictor_init_state(s->predictor_k, s->predictor_state[ch], s->num_taps); intlist_read(&c, state, s->coded_samples[ch], s->block_align, 1); diff --git a/libavcodec/takdsp.c b/libavcodec/takdsp.c index 2441c2baa6..9cb8052596 100644 --- a/libavcodec/takdsp.c +++ b/libavcodec/takdsp.c @@ -65,7 +65,7 @@ static void decorrelate_sf(int32_t *p1, int32_t *p2, int length, int dshift, int for (i = 0; i < length; i++) { int32_t a = p1[i]; int32_t b = p2[i]; - b = dfactor * (b >> dshift) + 128 >> 8 << dshift; + b = (unsigned)(dfactor * (b >> dshift) + 128 >> 8) << dshift; p1[i] = b - a; } } diff --git a/libavcodec/tdsc.c b/libavcodec/tdsc.c index eaea41c1f5..3617911071 100644 --- a/libavcodec/tdsc.c +++ b/libavcodec/tdsc.c @@ -390,7 +390,7 @@ static int tdsc_decode_tiles(AVCodecContext *avctx, int number_tiles) for (i = 0; i < number_tiles; i++) { int tile_size; int tile_mode; - int x, y, w, h; + int x, y, x2, y2, w, h; int ret; if (bytestream2_get_bytes_left(&ctx->gbc) < 4 || @@ -408,20 +408,19 @@ static int tdsc_decode_tiles(AVCodecContext *avctx, int number_tiles) bytestream2_skip(&ctx->gbc, 4); // unknown x = bytestream2_get_le32(&ctx->gbc); y = bytestream2_get_le32(&ctx->gbc); - w = bytestream2_get_le32(&ctx->gbc) - x; - h = bytestream2_get_le32(&ctx->gbc) - y; + x2 = bytestream2_get_le32(&ctx->gbc); + y2 = bytestream2_get_le32(&ctx->gbc); - if (x >= ctx->width || y >= ctx->height) { + if (x < 0 || y < 0 || x2 <= x || y2 <= y || + x2 > ctx->width || y2 > ctx->height + ) { av_log(avctx, AV_LOG_ERROR, - "Invalid tile position (%d.%d outside %dx%d).\n", - x, y, ctx->width, ctx->height); - return AVERROR_INVALIDDATA; - } - if (x + w > ctx->width || y + h > ctx->height) { - av_log(avctx, AV_LOG_ERROR, - "Invalid tile size %dx%d\n", w, h); + "Invalid tile position (%d.%d %d.%d outside %dx%d).\n", + x, y, x2, y2, ctx->width, ctx->height); return AVERROR_INVALIDDATA; } + w = x2 - x; + h = y2 - y; ret = av_reallocp(&ctx->tilebuffer, tile_size); if (!ctx->tilebuffer) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 18b327e800..59a993ec8b 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -79,6 +79,7 @@ typedef struct TiffContext { int fill_order; uint32_t res[4]; int is_thumbnail; + unsigned last_tag; int is_bayer; uint8_t pattern[4]; @@ -709,7 +710,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid if (is_dng) { int is_u16, pixel_size_bytes, pixel_size_bits, elements; - is_u16 = (s->bpp > 8); + is_u16 = (s->bpp / s->bppcount > 8); pixel_size_bits = (is_u16 ? 16 : 8); pixel_size_bytes = (is_u16 ? sizeof(uint16_t) : sizeof(uint8_t)); @@ -918,6 +919,11 @@ static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame, /* Copy the outputted tile's pixels from 'jpgframe' to 'frame' (final buffer) */ + if (s->jpgframe->width != s->avctx_mjpeg->width || + s->jpgframe->height != s->avctx_mjpeg->height || + s->jpgframe->format != s->avctx_mjpeg->pix_fmt) + return AVERROR_INVALIDDATA; + /* See dng_blit for explanation */ if (s->avctx_mjpeg->width == w * 2 && s->avctx_mjpeg->height == h / 2 && @@ -1252,6 +1258,12 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) if (ret < 0) { goto end; } + if (tag <= s->last_tag) + return AVERROR_INVALIDDATA; + + // We ignore TIFF_STRIP_SIZE as it is sometimes in the logic but wrong order around TIFF_STRIP_OFFS + if (tag != TIFF_STRIP_SIZE) + s->last_tag = tag; off = bytestream2_tell(&s->gb); if (count == 1) { @@ -1290,7 +1302,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) s->height = value; break; case TIFF_BPP: - if (count > 5U) { + if (count > 5 || count <= 0) { av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", value, count); @@ -1321,9 +1333,9 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) "Samples per pixel requires a single value, many provided\n"); return AVERROR_INVALIDDATA; } - if (value > 5U) { + if (value > 5 || value <= 0) { av_log(s->avctx, AV_LOG_ERROR, - "Samples per pixel %d is too large\n", value); + "Invalid samples per pixel %d\n", value); return AVERROR_INVALIDDATA; } if (s->bppcount == 1) @@ -1434,7 +1446,9 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) s->sub_ifd = ff_tget(&s->gb, TIFF_LONG, s->le); /** Only get the first SubIFD */ break; case DNG_LINEARIZATION_TABLE: - for (int i = 0; i < FFMIN(count, 1 << s->bpp); i++) + if (count > FF_ARRAY_ELEMS(s->dng_lut)) + return AVERROR_INVALIDDATA; + for (int i = 0; i < count; i++) s->dng_lut[i] = ff_tget(&s->gb, type, s->le); break; case DNG_BLACK_LEVEL: @@ -1805,6 +1819,7 @@ again: s->is_tiled = 0; s->is_jpeg = 0; s->cur_page = 0; + s->last_tag = 0; for (i = 0; i < 65536; i++) s->dng_lut[i] = i; @@ -1883,8 +1898,14 @@ again: if (is_dng) { int bps; + if (s->bpp % s->bppcount) + return AVERROR_INVALIDDATA; + bps = s->bpp / s->bppcount; + if (bps < 8 || bps > 32) + return AVERROR_INVALIDDATA; + if (s->white_level == 0) - s->white_level = (1 << s->bpp) - 1; /* Default value as per the spec */ + s->white_level = (1LL << bps) - 1; /* Default value as per the spec */ if (s->white_level <= s->black_level) { av_log(avctx, AV_LOG_ERROR, "BlackLevel (%"PRId32") must be less than WhiteLevel (%"PRId32")\n", @@ -1892,11 +1913,6 @@ again: return AVERROR_INVALIDDATA; } - if (s->bpp % s->bppcount) - return AVERROR_INVALIDDATA; - bps = s->bpp / s->bppcount; - if (bps < 8 || bps > 32) - return AVERROR_INVALIDDATA; if (s->planar) return AVERROR_PATCHWELCOME; } diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 77551e1470..5dcfb8a506 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -511,7 +511,14 @@ static int64_t get_bit_rate(AVCodecContext *ctx) break; case AVMEDIA_TYPE_AUDIO: bits_per_sample = av_get_bits_per_sample(ctx->codec_id); - bit_rate = bits_per_sample ? ctx->sample_rate * (int64_t)ctx->channels * bits_per_sample : ctx->bit_rate; + if (bits_per_sample) { + bit_rate = ctx->sample_rate * (int64_t)ctx->channels; + if (bit_rate > INT64_MAX / bits_per_sample) { + bit_rate = 0; + } else + bit_rate *= bits_per_sample; + } else + bit_rate = ctx->bit_rate; break; default: bit_rate = 0; @@ -1594,7 +1601,10 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, case AV_CODEC_ID_MP1: return 384; case AV_CODEC_ID_ATRAC1: return 512; case AV_CODEC_ID_ATRAC9: - case AV_CODEC_ID_ATRAC3: return 1024 * framecount; + case AV_CODEC_ID_ATRAC3: + if (framecount > INT_MAX/1024) + return 0; + return 1024 * framecount; case AV_CODEC_ID_ATRAC3P: return 2048; case AV_CODEC_ID_MP2: case AV_CODEC_ID_MUSEPACK7: return 1152; @@ -1610,8 +1620,11 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, if (ch > 0) { /* calc from sample rate and channels */ - if (id == AV_CODEC_ID_BINKAUDIO_DCT) + if (id == AV_CODEC_ID_BINKAUDIO_DCT) { + if (sr / 22050 > 22) + return 0; return (480 << (sr / 22050)) / ch; + } } if (id == AV_CODEC_ID_MP3) @@ -1657,7 +1670,10 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, return frame_bytes / (9 * ch) * 16; case AV_CODEC_ID_ADPCM_PSX: case AV_CODEC_ID_ADPCM_DTK: - return frame_bytes / (16 * ch) * 28; + frame_bytes /= 16 * ch; + if (frame_bytes > INT_MAX / 28) + return 0; + return frame_bytes * 28; case AV_CODEC_ID_ADPCM_4XM: case AV_CODEC_ID_ADPCM_IMA_DAT4: case AV_CODEC_ID_ADPCM_IMA_ISS: @@ -1755,22 +1771,20 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) { - int duration = get_audio_frame_duration(avctx->codec_id, avctx->sample_rate, + return get_audio_frame_duration(avctx->codec_id, avctx->sample_rate, avctx->channels, avctx->block_align, avctx->codec_tag, avctx->bits_per_coded_sample, avctx->bit_rate, avctx->extradata, avctx->frame_size, frame_bytes); - return FFMAX(0, duration); } int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes) { - int duration = get_audio_frame_duration(par->codec_id, par->sample_rate, + return get_audio_frame_duration(par->codec_id, par->sample_rate, par->channels, par->block_align, par->codec_tag, par->bits_per_coded_sample, par->bit_rate, par->extradata, par->frame_size, frame_bytes); - return FFMAX(0, duration); } #if !HAVE_THREADS diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c index 1d221c6e85..e48b3a8ccf 100644 --- a/libavcodec/v4l2_m2m.c +++ b/libavcodec/v4l2_m2m.c @@ -329,7 +329,6 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context) sem_destroy(&s->refsync); close(s->fd); - av_packet_unref(&s->buf_pkt); av_free(s); } @@ -339,10 +338,6 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv) V4L2m2mContext *s = priv->context; int ret; - if (!s) - return 0; - - if (s->fd >= 0) { ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); if (ret) av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name); @@ -350,7 +345,6 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv) ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF); if (ret) av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name); - } ff_v4l2_context_release(&s->output); diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c index a2ea0ff73a..3e17e0fcac 100644 --- a/libavcodec/v4l2_m2m_dec.c +++ b/libavcodec/v4l2_m2m_dec.c @@ -212,6 +212,9 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx) ret = ff_v4l2_m2m_codec_init(priv); if (ret) { av_log(avctx, AV_LOG_ERROR, "can't configure decoder\n"); + s->self_ref = NULL; + av_buffer_unref(&priv->context_ref); + return ret; } @@ -220,7 +223,10 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx) static av_cold int v4l2_decode_close(AVCodecContext *avctx) { - return ff_v4l2_m2m_codec_end(avctx->priv_data); + V4L2m2mPriv *priv = avctx->priv_data; + V4L2m2mContext *s = priv->context; + av_packet_unref(&s->buf_pkt); + return ff_v4l2_m2m_codec_end(priv); } #define OFFSET(x) offsetof(V4L2m2mPriv, x) @@ -255,7 +261,7 @@ static const AVOption options[] = { .close = v4l2_decode_close, \ .bsfs = bsf_name, \ .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \ - .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_INIT_CLEANUP, \ + .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, \ .wrapper_name = "v4l2m2m", \ } diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index 9f1b2c2ffc..32321f392f 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -416,7 +416,6 @@ static const AVCodecDefault v4l2_m2m_defaults[] = { .close = v4l2_encode_close, \ .defaults = v4l2_m2m_defaults, \ .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \ - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \ .wrapper_name = "v4l2m2m", \ } diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 16542dba3a..5c33170933 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -1080,7 +1080,7 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n, q2 = FFABS(q2) * 2 + ((q2 < 0) ? 0 : v->halfpq) - 1; if (q2 && q1 != q2) { for (k = 1; k < 8; k++) - ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; + ac_val2[k] = (int)(ac_val2[k] * (unsigned)q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } } } else { // top @@ -1093,7 +1093,7 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n, q2 = FFABS(q2) * 2 + ((q2 < 0) ? 0 : v->halfpq) - 1; if (q2 && q1 != q2) { for (k = 1; k < 8; k++) - ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; + ac_val2[k + 8] = (int)(ac_val2[k + 8] * (unsigned)q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } } } diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 6fe1ca46a3..c79b57e124 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -2920,6 +2920,9 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) int ret; AVRational fps, aspect; + if (get_bits_left(gb) < 206) + return AVERROR_INVALIDDATA; + s->theora_header = 0; s->theora = get_bits(gb, 24); av_log(avctx, AV_LOG_DEBUG, "Theora bitstream version %X\n", s->theora); diff --git a/libavcodec/vp3dsp.c b/libavcodec/vp3dsp.c index f485fba1f6..ec859a679d 100644 --- a/libavcodec/vp3dsp.c +++ b/libavcodec/vp3dsp.c @@ -490,5 +490,5 @@ void ff_vp3dsp_set_bounding_values(int * bounding_values_array, int filter_limit } if (value) bounding_values[128] = value; - bounding_values[129] = bounding_values[130] = filter_limit * 0x02020202; + bounding_values[129] = bounding_values[130] = filter_limit * 0x02020202U; } diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index bab4223aca..e84fcdeaa1 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -2289,10 +2289,10 @@ int vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, s->mv_bounds.mv_min.x = -MARGIN; s->mv_bounds.mv_max.x = ((s->mb_width - 1) << 6) + MARGIN; - if (vpX_rac_is_end(&s->c)) { - return AVERROR_INVALIDDATA; - } for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) { + if (vpX_rac_is_end(&s->c)) { + return AVERROR_INVALIDDATA; + } if (mb_y == 0) AV_WN32A((mb - s->mb_width - 1)->intra4x4_pred_mode_top, DC_PRED * 0x01010101); diff --git a/libavcodec/vp9dsp_template.c b/libavcodec/vp9dsp_template.c index c6944f5ce3..9b11661704 100644 --- a/libavcodec/vp9dsp_template.c +++ b/libavcodec/vp9dsp_template.c @@ -1138,7 +1138,7 @@ static void type_a##_##type_b##_##sz##x##sz##_add_c(uint8_t *_dst, \ for (j = 0; j < sz; j++) \ dst[j * stride] = av_clip_pixel(dst[j * stride] + \ (bits ? \ - (t + (1 << (bits - 1))) >> bits : \ + (int)(t + (1U << (bits - 1))) >> bits : \ t)); \ dst++; \ } \ @@ -1153,7 +1153,7 @@ static void type_a##_##type_b##_##sz##x##sz##_add_c(uint8_t *_dst, \ for (j = 0; j < sz; j++) \ dst[j * stride] = av_clip_pixel(dst[j * stride] + \ (bits ? \ - (out[j] + (1 << (bits - 1))) >> bits : \ + (int)(out[j] + (1U << (bits - 1))) >> bits : \ out[j])); \ dst++; \ } \ @@ -1260,25 +1260,25 @@ static av_always_inline void iadst8_1d(const dctcoef *in, ptrdiff_t stride, t6 = (t2a - t6a + (1 << 13)) >> 14; t7 = (t3a - t7a + (1 << 13)) >> 14; - t4a = 15137 * t4 + 6270 * t5; - t5a = 6270 * t4 - 15137 * t5; - t6a = 15137 * t7 - 6270 * t6; - t7a = 6270 * t7 + 15137 * t6; + t4a = 15137U * t4 + 6270U * t5; + t5a = 6270U * t4 - 15137U * t5; + t6a = 15137U * t7 - 6270U * t6; + t7a = 6270U * t7 + 15137U * t6; out[0] = t0 + t2; out[7] = -(t1 + t3); t2 = t0 - t2; t3 = t1 - t3; - out[1] = -((t4a + t6a + (1 << 13)) >> 14); - out[6] = (t5a + t7a + (1 << 13)) >> 14; - t6 = (t4a - t6a + (1 << 13)) >> 14; - t7 = (t5a - t7a + (1 << 13)) >> 14; + out[1] = -((dctint)((1U << 13) + t4a + t6a) >> 14); + out[6] = (dctint)((1U << 13) + t5a + t7a) >> 14; + t6 = (dctint)((1U << 13) + t4a - t6a) >> 14; + t7 = (dctint)((1U << 13) + t5a - t7a) >> 14; - out[3] = -(((t2 + t3) * 11585 + (1 << 13)) >> 14); - out[4] = ((t2 - t3) * 11585 + (1 << 13)) >> 14; - out[2] = ((t6 + t7) * 11585 + (1 << 13)) >> 14; - out[5] = -(((t6 - t7) * 11585 + (1 << 13)) >> 14); + out[3] = -((dctint)((t2 + t3) * 11585U + (1 << 13)) >> 14); + out[4] = (dctint)((t2 - t3) * 11585U + (1 << 13)) >> 14; + out[2] = (dctint)((t6 + t7) * 11585U + (1 << 13)) >> 14; + out[5] = -((dctint)((t6 - t7) * 11585U + (1 << 13)) >> 14); } itxfm_wrap(8, 5) @@ -1290,22 +1290,22 @@ static av_always_inline void idct16_1d(const dctcoef *in, ptrdiff_t stride, dctint t0a, t1a, t2a, t3a, t4a, t5a, t6a, t7a; dctint t8a, t9a, t10a, t11a, t12a, t13a, t14a, t15a; - t0a = ((IN(0) + IN(8)) * 11585 + (1 << 13)) >> 14; - t1a = ((IN(0) - IN(8)) * 11585 + (1 << 13)) >> 14; - t2a = (IN(4) * 6270 - IN(12) * 15137 + (1 << 13)) >> 14; - t3a = (IN(4) * 15137 + IN(12) * 6270 + (1 << 13)) >> 14; - t4a = (IN(2) * 3196 - IN(14) * 16069 + (1 << 13)) >> 14; - t7a = (IN(2) * 16069 + IN(14) * 3196 + (1 << 13)) >> 14; - t5a = (IN(10) * 13623 - IN(6) * 9102 + (1 << 13)) >> 14; - t6a = (IN(10) * 9102 + IN(6) * 13623 + (1 << 13)) >> 14; - t8a = (IN(1) * 1606 - IN(15) * 16305 + (1 << 13)) >> 14; - t15a = (IN(1) * 16305 + IN(15) * 1606 + (1 << 13)) >> 14; - t9a = (IN(9) * 12665 - IN(7) * 10394 + (1 << 13)) >> 14; - t14a = (IN(9) * 10394 + IN(7) * 12665 + (1 << 13)) >> 14; - t10a = (IN(5) * 7723 - IN(11) * 14449 + (1 << 13)) >> 14; - t13a = (IN(5) * 14449 + IN(11) * 7723 + (1 << 13)) >> 14; - t11a = (IN(13) * 15679 - IN(3) * 4756 + (1 << 13)) >> 14; - t12a = (IN(13) * 4756 + IN(3) * 15679 + (1 << 13)) >> 14; + t0a = (dctint)((IN(0) + IN(8)) * 11585U + (1 << 13)) >> 14; + t1a = (dctint)((IN(0) - IN(8)) * 11585U + (1 << 13)) >> 14; + t2a = (dctint)(IN(4) * 6270U - IN(12) * 15137U + (1 << 13)) >> 14; + t3a = (dctint)(IN(4) * 15137U + IN(12) * 6270U + (1 << 13)) >> 14; + t4a = (dctint)(IN(2) * 3196U - IN(14) * 16069U + (1 << 13)) >> 14; + t7a = (dctint)(IN(2) * 16069U + IN(14) * 3196U + (1 << 13)) >> 14; + t5a = (dctint)(IN(10) * 13623U - IN(6) * 9102U + (1 << 13)) >> 14; + t6a = (dctint)(IN(10) * 9102U + IN(6) * 13623U + (1 << 13)) >> 14; + t8a = (dctint)(IN(1) * 1606U - IN(15) * 16305U + (1 << 13)) >> 14; + t15a = (dctint)(IN(1) * 16305U + IN(15) * 1606U + (1 << 13)) >> 14; + t9a = (dctint)(IN(9) * 12665U - IN(7) * 10394U + (1 << 13)) >> 14; + t14a = (dctint)(IN(9) * 10394U + IN(7) * 12665U + (1 << 13)) >> 14; + t10a = (dctint)(IN(5) * 7723U - IN(11) * 14449U + (1 << 13)) >> 14; + t13a = (dctint)(IN(5) * 14449U + IN(11) * 7723U + (1 << 13)) >> 14; + t11a = (dctint)(IN(13) * 15679U - IN(3) * 4756U + (1 << 13)) >> 14; + t12a = (dctint)(IN(13) * 4756U + IN(3) * 15679U + (1 << 13)) >> 14; t0 = t0a + t3a; t1 = t1a + t2a; @@ -1324,12 +1324,12 @@ static av_always_inline void idct16_1d(const dctcoef *in, ptrdiff_t stride, t14 = t15a - t14a; t15 = t15a + t14a; - t5a = ((t6 - t5) * 11585 + (1 << 13)) >> 14; - t6a = ((t6 + t5) * 11585 + (1 << 13)) >> 14; - t9a = ( t14 * 6270 - t9 * 15137 + (1 << 13)) >> 14; - t14a = ( t14 * 15137 + t9 * 6270 + (1 << 13)) >> 14; - t10a = (-(t13 * 15137 + t10 * 6270) + (1 << 13)) >> 14; - t13a = ( t13 * 6270 - t10 * 15137 + (1 << 13)) >> 14; + t5a = (dctint)((t6 - t5) * 11585U + (1 << 13)) >> 14; + t6a = (dctint)((t6 + t5) * 11585U + (1 << 13)) >> 14; + t9a = (dctint)( t14 * 6270U - t9 * 15137U + (1 << 13)) >> 14; + t14a = (dctint)( t14 * 15137U + t9 * 6270U + (1 << 13)) >> 14; + t10a = (dctint)(-(t13 * 15137U + t10 * 6270U) + (1 << 13)) >> 14; + t13a = (dctint)( t13 * 6270U - t10 * 15137U + (1 << 13)) >> 14; t0a = t0 + t7; t1a = t1 + t6a; @@ -1348,10 +1348,10 @@ static av_always_inline void idct16_1d(const dctcoef *in, ptrdiff_t stride, t14 = t14a + t13a; t15a = t15 + t12; - t10a = ((t13 - t10) * 11585 + (1 << 13)) >> 14; - t13a = ((t13 + t10) * 11585 + (1 << 13)) >> 14; - t11 = ((t12a - t11a) * 11585 + (1 << 13)) >> 14; - t12 = ((t12a + t11a) * 11585 + (1 << 13)) >> 14; + t10a = (dctint)((t13 - t10) * 11585U + (1 << 13)) >> 14; + t13a = (dctint)((t13 + t10) * 11585U + (1 << 13)) >> 14; + t11 = (dctint)((t12a - t11a) * 11585U + (1 << 13)) >> 14; + t12 = (dctint)((t12a + t11a) * 11585U + (1 << 13)) >> 14; out[ 0] = t0a + t15a; out[ 1] = t1a + t14; diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index 725e811070..b8d0f6220d 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -932,6 +932,8 @@ static int decode_subframe(WmallDecodeCtx *s) s->do_lpc = 0; } + if (get_bits_left(&s->gb) < 1) + return AVERROR_INVALIDDATA; if (get_bits1(&s->gb)) padding_zeroes = get_bits(&s->gb, 5); diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index cbf5fa7fd5..5d76050e3a 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -1719,6 +1719,12 @@ static int decode_packet(AVCodecContext *avctx, WMAProDecodeCtx *s, } } else { int frame_size; + + if (avpkt->size < s->next_packet_start) { + s->packet_loss = 1; + return AVERROR_INVALIDDATA; + } + s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3; init_get_bits(gb, avpkt->data, s->buf_bit_size); skip_bits(gb, s->packet_offset); diff --git a/libavcodec/x86/h264_deblock.asm b/libavcodec/x86/h264_deblock.asm index 6702ae98d4..a2e745cd8e 100644 --- a/libavcodec/x86/h264_deblock.asm +++ b/libavcodec/x86/h264_deblock.asm @@ -1185,7 +1185,7 @@ cglobal deblock_h_chroma_8, 5, 7, 8, 0-16, pix_, stride_, alpha_, beta_, tc0_ STORE_8_ROWS PASS8ROWS(pix_q - 2, r5 - 2, stride_q, r6) RET -cglobal deblock_h_chroma422_8, 5, 7, 8, 0-16, pix_, stride_, alpha_, beta_, tc0_, +cglobal deblock_h_chroma422_8, 5, 7, 8, 0-16, pix_, stride_, alpha_, beta_, tc0_ CHROMA_H_START_XMM r5, r6 LOAD_8_ROWS PASS8ROWS(pix_q - 2, r5 - 2, stride_q, r6) TRANSPOSE_8x4B_XMM diff --git a/libavfilter/vf_framerate.c b/libavfilter/vf_framerate.c index 6c8d01c94b..f5085705a4 100644 --- a/libavfilter/vf_framerate.c +++ b/libavfilter/vf_framerate.c @@ -170,7 +170,9 @@ static int process_work_frame(AVFilterContext *ctx) return 0; if (!s->f0) { - s->work = av_frame_clone(s->f1); + av_assert1(s->flush); + s->work = s->f1; + s->f1 = NULL; } else { if (work_pts >= s->pts1 + s->delta && s->flush) return 0; diff --git a/libavfilter/vf_vmafmotion.c b/libavfilter/vf_vmafmotion.c index 0730147e7d..88d0b35095 100644 --- a/libavfilter/vf_vmafmotion.c +++ b/libavfilter/vf_vmafmotion.c @@ -238,9 +238,6 @@ int ff_vmafmotion_init(VMAFMotionData *s, int i; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (w < 3 || h < 3) - return AVERROR(EINVAL); - s->width = w; s->height = h; s->stride = FFALIGN(w * sizeof(uint16_t), 32); diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 06fd24ecfa..43dea67add 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -123,22 +123,20 @@ static void filter_edges(void *dst1, void *prev1, void *cur1, void *next1, uint8_t *next2 = parity ? cur : next; const int edge = MAX_ALIGN - 1; - int offset = FFMAX(w - edge, 3); /* Only edge pixels need to be processed here. A constant value of false * for is_not_edge should let the compiler ignore the whole branch. */ - FILTER(0, FFMIN(3, w), 0) + FILTER(0, 3, 0) - dst = (uint8_t*)dst1 + offset; - prev = (uint8_t*)prev1 + offset; - cur = (uint8_t*)cur1 + offset; - next = (uint8_t*)next1 + offset; + dst = (uint8_t*)dst1 + w - edge; + prev = (uint8_t*)prev1 + w - edge; + cur = (uint8_t*)cur1 + w - edge; + next = (uint8_t*)next1 + w - edge; prev2 = (uint8_t*)(parity ? prev : cur); next2 = (uint8_t*)(parity ? cur : next); - FILTER(offset, w - 3, 1) - offset = FFMAX(offset, w - 3); - FILTER(offset, w, 0) + FILTER(w - edge, w - 3, 1) + FILTER(w - 3, w, 0) } @@ -172,23 +170,21 @@ static void filter_edges_16bit(void *dst1, void *prev1, void *cur1, void *next1, uint16_t *next2 = parity ? cur : next; const int edge = MAX_ALIGN / 2 - 1; - int offset = FFMAX(w - edge, 3); mrefs /= 2; prefs /= 2; - FILTER(0, FFMIN(3, w), 0) + FILTER(0, 3, 0) - dst = (uint16_t*)dst1 + offset; - prev = (uint16_t*)prev1 + offset; - cur = (uint16_t*)cur1 + offset; - next = (uint16_t*)next1 + offset; + dst = (uint16_t*)dst1 + w - edge; + prev = (uint16_t*)prev1 + w - edge; + cur = (uint16_t*)cur1 + w - edge; + next = (uint16_t*)next1 + w - edge; prev2 = (uint16_t*)(parity ? prev : cur); next2 = (uint16_t*)(parity ? cur : next); - FILTER(offset, w - 3, 1) - offset = FFMAX(offset, w - 3); - FILTER(offset, w, 0) + FILTER(w - edge, w - 3, 1) + FILTER(w - 3, w, 0) } static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) diff --git a/libavfilter/x86/vf_blend.asm b/libavfilter/x86/vf_blend.asm index 251bbb5a12..766e5b7bc1 100644 --- a/libavfilter/x86/vf_blend.asm +++ b/libavfilter/x86/vf_blend.asm @@ -38,11 +38,11 @@ pb_255: times 16 db 255 SECTION .text -%macro BLEND_INIT 2-3 +%macro BLEND_INIT 2-3 0 %if ARCH_X86_64 cglobal blend_%1, 6, 9, %2, top, top_linesize, bottom, bottom_linesize, dst, dst_linesize, width, end, x mov widthd, dword widthm - %if %0 == 3; is 16 bit + %if %3; is 16 bit add widthq, widthq ; doesn't compile on x86_32 %endif %else @@ -66,7 +66,7 @@ cglobal blend_%1, 5, 7, %2, top, top_linesize, bottom, bottom_linesize, dst, end REP_RET %endmacro -%macro BLEND_SIMPLE 2-3 +%macro BLEND_SIMPLE 2-3 0 BLEND_INIT %1, 2, %3 .nextrow: mov xq, widthq @@ -82,10 +82,10 @@ BLEND_END %endmacro ; %1 name , %2 src (b or w), %3 inter (w or d), %4 (1 if 16bit, not set if 8 bit) -%macro GRAINEXTRACT 3-4 +%macro GRAINEXTRACT 3-4 0 BLEND_INIT %1, 6, %4 pxor m4, m4 -%if %0 == 4 ; 16 bit +%if %4 ; 16 bit VBROADCASTI128 m5, [pd_32768] %else VBROADCASTI128 m5, [pw_128] @@ -182,7 +182,7 @@ BLEND_END %endmacro ;%1 name, %2 (b or w), %3 (set if 16 bit) -%macro AVERAGE 2-3 +%macro AVERAGE 2-3 0 BLEND_INIT %1, 3, %3 pcmpeqb m2, m2 @@ -203,10 +203,10 @@ BLEND_END %endmacro ; %1 name , %2 src (b or w), %3 inter (w or d), %4 (1 if 16bit, not set if 8 bit) -%macro GRAINMERGE 3-4 +%macro GRAINMERGE 3-4 0 BLEND_INIT %1, 6, %4 pxor m4, m4 -%if %0 == 4 ; 16 bit +%if %4 ; 16 bit VBROADCASTI128 m5, [pd_32768] %else VBROADCASTI128 m5, [pw_128] @@ -288,7 +288,7 @@ BLEND_INIT divide, 4 BLEND_END %endmacro -%macro PHOENIX 2-3 +%macro PHOENIX 2-3 0 ; %1 name, %2 b or w, %3 (opt) 1 if 16 bit BLEND_INIT %1, 4, %3 VBROADCASTI128 m3, [pb_255] @@ -311,7 +311,7 @@ BLEND_END %endmacro ; %1 name , %2 src (b or w), %3 inter (w or d), %4 (1 if 16bit, not set if 8 bit) -%macro DIFFERENCE 3-4 +%macro DIFFERENCE 3-4 0 BLEND_INIT %1, 5, %4 pxor m2, m2 .nextrow: @@ -326,7 +326,7 @@ BLEND_INIT %1, 5, %4 punpckl%2%3 m1, m2 psub%3 m0, m1 psub%3 m3, m4 -%if %0 == 4; 16 bit +%if %4; 16 bit pabsd m0, m0 pabsd m3, m3 %else @@ -340,10 +340,10 @@ BLEND_END %endmacro ; %1 name , %2 src (b or w), %3 inter (w or d), %4 (1 if 16bit, not set if 8 bit) -%macro EXTREMITY 3-4 +%macro EXTREMITY 3-4 0 BLEND_INIT %1, 8, %4 pxor m2, m2 -%if %0 == 4; 16 bit +%if %4; 16 bit VBROADCASTI128 m4, [pd_65535] %else VBROADCASTI128 m4, [pw_255] @@ -362,7 +362,7 @@ BLEND_INIT %1, 8, %4 psub%3 m7, m4, m5 psub%3 m3, m1 psub%3 m7, m6 -%if %0 == 4; 16 bit +%if %4; 16 bit pabsd m3, m3 pabsd m7, m7 %else @@ -375,10 +375,10 @@ BLEND_INIT %1, 8, %4 BLEND_END %endmacro -%macro NEGATION 3-4 +%macro NEGATION 3-4 0 BLEND_INIT %1, 8, %4 pxor m2, m2 -%if %0 == 4; 16 bit +%if %4; 16 bit VBROADCASTI128 m4, [pd_65535] %else VBROADCASTI128 m4, [pw_255] @@ -397,7 +397,7 @@ BLEND_INIT %1, 8, %4 psub%3 m7, m4, m5 psub%3 m3, m1 psub%3 m7, m6 -%if %0 == 4; 16 bit +%if %4; 16 bit pabsd m3, m3 pabsd m7, m7 %else diff --git a/libavformat/3dostr.c b/libavformat/3dostr.c index 6c49f7589c..e77df9e5c9 100644 --- a/libavformat/3dostr.c +++ b/libavformat/3dostr.c @@ -64,7 +64,7 @@ static int threedostr_read_header(AVFormatContext *s) st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->sample_rate = avio_rb32(s->pb); st->codecpar->channels = avio_rb32(s->pb); - if (st->codecpar->channels <= 0) + if (st->codecpar->channels <= 0 || st->codecpar->sample_rate <= 0) return AVERROR_INVALIDDATA; codec = avio_rl32(s->pb); avio_skip(s->pb, 4); diff --git a/libavformat/4xm.c b/libavformat/4xm.c index 6a227a0b0d..30f1b05324 100644 --- a/libavformat/4xm.c +++ b/libavformat/4xm.c @@ -299,7 +299,7 @@ static int fourxm_read_packet(AVFormatContext *s, unsigned int track_number; int packet_read = 0; unsigned char header[8]; - int audio_frame_count; + int64_t audio_frame_count; while (!packet_read) { if ((ret = avio_read(s->pb, header, 8)) < 0) diff --git a/libavformat/ads.c b/libavformat/ads.c index f25141b3c6..544d652829 100644 --- a/libavformat/ads.c +++ b/libavformat/ads.c @@ -34,8 +34,9 @@ static int ads_probe(const AVProbeData *p) static int ads_read_header(AVFormatContext *s) { - int align, codec, size; + int align, codec; AVStream *st; + int64_t size; st = avformat_new_stream(s, NULL); if (!st) @@ -62,7 +63,7 @@ static int ads_read_header(AVFormatContext *s) st->codecpar->block_align = st->codecpar->channels * align; avio_skip(s->pb, 12); size = avio_rl32(s->pb); - if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_PSX) + if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_PSX && size >= 0x40) st->duration = (size - 0x40) / 16 / st->codecpar->channels * 28; avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index c650e9074d..4d1c9bbb53 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -120,6 +120,8 @@ static int get_aiff_header(AVFormatContext *s, int size, else sample_rate = (val + (1ULL<<(-exp-1))) >> -exp; par->sample_rate = sample_rate; + if (size < 18) + return AVERROR_INVALIDDATA; size -= 18; /* get codec id for AIFF-C */ @@ -406,6 +408,8 @@ static int aiff_read_packet(AVFormatContext *s, break; default: size = st->codecpar->block_align ? (MAX_SIZE / st->codecpar->block_align) * st->codecpar->block_align : MAX_SIZE; + if (!size) + return AVERROR_INVALIDDATA; } size = FFMIN(max_size, size); res = av_get_packet(s->pb, pkt, size); diff --git a/libavformat/alp.c b/libavformat/alp.c index 4c2e8f0652..e1da312b8c 100644 --- a/libavformat/alp.c +++ b/libavformat/alp.c @@ -83,7 +83,7 @@ static int alp_read_header(AVFormatContext *s) if (hdr.header_size == 8) { /* .TUN music file */ - hdr.sample_rate = 11025 * hdr.num_channels; + hdr.sample_rate = 22050; } else { /* .PCM sound file */ hdr.sample_rate = avio_rl32(s->pb); diff --git a/libavformat/ape.c b/libavformat/ape.c index 39a584aa98..d92cb2867d 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -253,7 +253,7 @@ static int ape_read_header(AVFormatContext * s) avio_skip(pb, ape->wavheaderlength); } - if(!ape->totalframes){ + if(!ape->totalframes || pb->eof_reached){ av_log(s, AV_LOG_ERROR, "No frames in the file!\n"); return AVERROR(EINVAL); } @@ -298,8 +298,11 @@ static int ape_read_header(AVFormatContext * s) for (i = 0; i < ape->totalframes && !pb->eof_reached; i++) ape->bittable[i] = avio_r8(pb); } - if (pb->eof_reached) - av_log(s, AV_LOG_WARNING, "File truncated\n"); + if (pb->eof_reached) { + av_log(s, AV_LOG_ERROR, "File truncated\n"); + ret = AVERROR_INVALIDDATA; + goto fail; + } } ape->frames[0].pos = ape->firstframe; diff --git a/libavformat/argo_asf.c b/libavformat/argo_asf.c index 3339425244..abc6e51baa 100644 --- a/libavformat/argo_asf.c +++ b/libavformat/argo_asf.c @@ -175,7 +175,11 @@ static int argo_asf_read_header(AVFormatContext *s) st->codecpar->channels = 1; } - st->codecpar->sample_rate = asf->ckhdr.sample_rate; + /* v1.1 files (FX Fighter) are all marked as 44100, but are actually 22050. */ + if (asf->fhdr.version_major == 1 && asf->fhdr.version_minor == 1) + st->codecpar->sample_rate = 22050; + else + st->codecpar->sample_rate = asf->ckhdr.sample_rate; st->codecpar->bits_per_coded_sample = 4; diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c index e9ddca7151..0aab7c2300 100644 --- a/libavformat/asfdec_f.c +++ b/libavformat/asfdec_f.c @@ -424,7 +424,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) if (!(asf->hdr.flags & 0x01)) { // if we aren't streaming... int64_t fsize = avio_size(pb); if (fsize <= 0 || (int64_t)asf->hdr.file_size <= 0 || - 20*FFABS(fsize - (int64_t)asf->hdr.file_size) < FFMIN(fsize, asf->hdr.file_size)) + FFABS(fsize - (int64_t)asf->hdr.file_size) < FFMIN(fsize, asf->hdr.file_size)/20) st->duration = asf->hdr.play_time / (10000000 / 1000) - start_time; } @@ -516,6 +516,8 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) tag1 = avio_rl32(pb); avio_skip(pb, 20); if (sizeX > 40) { + if (size < sizeX - 40) + return AVERROR_INVALIDDATA; st->codecpar->extradata_size = ffio_limit(pb, sizeX - 40); st->codecpar->extradata = av_mallocz(st->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); @@ -607,6 +609,8 @@ static int asf_read_ext_stream_properties(AVFormatContext *s, int64_t size) ff_get_guid(pb, &g); size = avio_rl16(pb); ext_len = avio_rl32(pb); + if (ext_len < 0) + return AVERROR_INVALIDDATA; avio_skip(pb, ext_len); if (stream_num < 128 && i < FF_ARRAY_ELEMS(asf->streams[stream_num].payload)) { ASFPayload *p = &asf->streams[stream_num].payload[i]; @@ -769,6 +773,8 @@ static int asf_read_marker(AVFormatContext *s, int64_t size) avio_rl32(pb); // send time avio_rl32(pb); // flags name_len = avio_rl32(pb); // name length + if ((unsigned)name_len > INT_MAX / 2) + return AVERROR_INVALIDDATA; if ((ret = avio_get_str16le(pb, name_len * 2, name, sizeof(name))) < name_len) avio_skip(pb, name_len - ret); diff --git a/libavformat/asfdec_o.c b/libavformat/asfdec_o.c index 1b10e47907..893368702e 100644 --- a/libavformat/asfdec_o.c +++ b/libavformat/asfdec_o.c @@ -245,6 +245,9 @@ static int asf_read_marker(AVFormatContext *s, const GUIDParseTable *g) avio_skip(pb, 4); // flags len = avio_rl32(pb); + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; + if ((ret = avio_get_str16le(pb, len, name, sizeof(name))) < len) avio_skip(pb, len - ret); @@ -1679,6 +1682,9 @@ static int detect_unknown_subobject(AVFormatContext *s, int64_t offset, int64_t ff_asf_guid guid; int ret; + if (offset > INT64_MAX - size) + return AVERROR_INVALIDDATA; + while (avio_tell(pb) <= offset + size) { if (avio_tell(pb) == asf->offset) break; diff --git a/libavformat/au.c b/libavformat/au.c index 4afee85a94..1e77dc3cb0 100644 --- a/libavformat/au.c +++ b/libavformat/au.c @@ -86,6 +86,11 @@ static int au_read_annotation(AVFormatContext *s, int size) av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); while (size-- > 0) { + if (avio_feof(pb)) { + av_bprint_finalize(&bprint, NULL); + av_freep(&key); + return AVERROR_EOF; + } c = avio_r8(pb); switch(state) { case PARSE_KEY: diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 5fc3e01aa9..0d66ad2311 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -125,7 +125,7 @@ static inline int get_duration(AVIStream *ast, int len) if (ast->sample_size) return len; else if (ast->dshow_block_align) - return (len + ast->dshow_block_align - 1) / ast->dshow_block_align; + return (len + (int64_t)ast->dshow_block_align - 1) / ast->dshow_block_align; else return 1; } @@ -439,7 +439,7 @@ static int calculate_bitrate(AVFormatContext *s) maxpos = FFMAX(maxpos, st->index_entries[j-1].pos); lensum += len; } - if (maxpos < avi->io_fsize*9/10) // index does not cover the whole file + if (maxpos < av_rescale(avi->io_fsize, 9, 10)) // index does not cover the whole file return 0; if (lensum*9/10 > maxpos || lensum < maxpos*9/10) // frame sum and filesize mismatch return 0; @@ -1422,6 +1422,7 @@ resync: if (avi->stream_index >= 0) { AVStream *st = s->streams[avi->stream_index]; AVIStream *ast = st->priv_data; + int dv_demux = CONFIG_DV_DEMUXER && avi->dv_demux; int size, err; if (get_subtitle_pkt(s, st, pkt)) @@ -1444,7 +1445,7 @@ resync: return err; size = err; - if (ast->has_pal && pkt->size < (unsigned)INT_MAX / 2) { + if (ast->has_pal && pkt->size < (unsigned)INT_MAX / 2 && !dv_demux) { uint8_t *pal; pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, @@ -1458,7 +1459,7 @@ resync: } } - if (CONFIG_DV_DEMUXER && avi->dv_demux) { + if (dv_demux) { AVBufferRef *avbuf = pkt->buf; size = avpriv_dv_produce_packet(avi->dv_demux, pkt, pkt->data, pkt->size, pkt->pos); diff --git a/libavformat/avs.c b/libavformat/avs.c index 54b2c3f2a9..097c171908 100644 --- a/libavformat/avs.c +++ b/libavformat/avs.c @@ -128,7 +128,8 @@ avs_read_video_packet(AVFormatContext * s, AVPacket * pkt, static int avs_read_audio_packet(AVFormatContext * s, AVPacket * pkt) { AvsFormat *avs = s->priv_data; - int ret, size; + int ret; + int64_t size; size = avio_tell(s->pb); ret = ff_voc_get_packet(s, pkt, avs->st_audio, avs->remaining_audio_size); diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c index 47a9a69330..709603daf5 100644 --- a/libavformat/bethsoftvid.c +++ b/libavformat/bethsoftvid.c @@ -28,6 +28,7 @@ */ #include "libavutil/channel_layout.h" +#include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "avformat.h" #include "internal.h" @@ -72,6 +73,7 @@ static int vid_read_header(AVFormatContext *s) { BVID_DemuxContext *vid = s->priv_data; AVIOContext *pb = s->pb; + int ret; /* load main header. Contents: * bytes: 'V' 'I' 'D' @@ -84,6 +86,10 @@ static int vid_read_header(AVFormatContext *s) vid->bethsoft_global_delay = avio_rl16(pb); avio_rl16(pb); + ret = av_image_check_size(vid->width, vid->height, 0, s); + if (ret < 0) + return ret; + // wait until the first packet to create each stream vid->video_index = -1; vid->audio_index = -1; diff --git a/libavformat/bfi.c b/libavformat/bfi.c index 29e2cf8cf4..2dab986f3a 100644 --- a/libavformat/bfi.c +++ b/libavformat/bfi.c @@ -69,6 +69,9 @@ static int bfi_read_header(AVFormatContext * s) /* Set the total number of frames. */ avio_skip(pb, 8); chunk_header = avio_rl32(pb); + if (chunk_header < 3) + return AVERROR_INVALIDDATA; + bfi->nframes = avio_rl32(pb); avio_rl32(pb); avio_rl32(pb); diff --git a/libavformat/bintext.c b/libavformat/bintext.c index 7dab5f377d..bc0f6bd099 100644 --- a/libavformat/bintext.c +++ b/libavformat/bintext.c @@ -293,6 +293,8 @@ static int adf_read_header(AVFormatContext *s) bin->fsize = avio_size(pb) - 1 - 192 - 4096; st->codecpar->width = 80<<3; ff_sauce_read(s, &bin->fsize, &got_width, 0); + if (st->codecpar->width < 8) + return AVERROR_INVALIDDATA; if (!bin->width) calculate_height(st->codecpar, bin->fsize); avio_seek(pb, 1 + 192 + 4096, SEEK_SET); @@ -344,6 +346,8 @@ static int idf_read_header(AVFormatContext *s) bin->fsize = avio_size(pb) - 12 - 4096 - 48; ff_sauce_read(s, &bin->fsize, &got_width, 0); + if (st->codecpar->width < 8) + return AVERROR_INVALIDDATA; if (!bin->width) calculate_height(st->codecpar, bin->fsize); avio_seek(pb, 12, SEEK_SET); diff --git a/libavformat/boadec.c b/libavformat/boadec.c index 495090c485..74a6ceecb1 100644 --- a/libavformat/boadec.c +++ b/libavformat/boadec.c @@ -54,12 +54,12 @@ static int read_header(AVFormatContext *s) avio_rl32(s->pb); st->codecpar->sample_rate = avio_rl32(s->pb); st->codecpar->channels = avio_rl32(s->pb); - if (st->codecpar->channels > FF_SANE_NB_CHANNELS) + if (st->codecpar->channels > FF_SANE_NB_CHANNELS || st->codecpar->channels <= 0) return AVERROR(ENOSYS); s->internal->data_offset = avio_rl32(s->pb); avio_r8(s->pb); st->codecpar->block_align = avio_rl32(s->pb); - if (st->codecpar->block_align > INT_MAX / FF_SANE_NB_CHANNELS) + if (st->codecpar->block_align > INT_MAX / FF_SANE_NB_CHANNELS || st->codecpar->block_align <= 0) return AVERROR_INVALIDDATA; st->codecpar->block_align *= st->codecpar->channels; diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index d0f942f3e4..c2ac1369fd 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -70,7 +70,7 @@ static int read_desc_chunk(AVFormatContext *s) /* parse format description */ st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; - st->codecpar->sample_rate = av_int2double(avio_rb64(pb)); + st->codecpar->sample_rate = av_clipd(av_int2double(avio_rb64(pb)), 0, INT_MAX); st->codecpar->codec_tag = avio_rl32(pb); flags = avio_rb32(pb); caf->bytes_per_packet = avio_rb32(pb); @@ -79,6 +79,9 @@ static int read_desc_chunk(AVFormatContext *s) st->codecpar->channels = avio_rb32(pb); st->codecpar->bits_per_coded_sample = avio_rb32(pb); + if (caf->bytes_per_packet < 0 || caf->frames_per_packet < 0) + return AVERROR_INVALIDDATA; + /* calculate bit rate for constant size packets */ if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) { st->codecpar->bit_rate = (uint64_t)st->codecpar->sample_rate * (uint64_t)caf->bytes_per_packet * 8 @@ -189,6 +192,7 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size) CafContext *caf = s->priv_data; int64_t pos = 0, ccount, num_packets; int i; + int ret; ccount = avio_tell(pb); @@ -202,7 +206,11 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size) st->duration = 0; for (i = 0; i < num_packets; i++) { - av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME); + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; + ret = av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME); + if (ret < 0) + return ret; pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb); st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb); } diff --git a/libavformat/cdg.c b/libavformat/cdg.c index 05cac6e528..f933819d57 100644 --- a/libavformat/cdg.c +++ b/libavformat/cdg.c @@ -49,7 +49,7 @@ static int read_header(AVFormatContext *s) if (ret < 0) { av_log(s, AV_LOG_WARNING, "Cannot calculate duration as file size cannot be determined\n"); } else - vst->duration = (ret * vst->time_base.den) / (CDG_PACKET_SIZE * 300); + vst->duration = (ret * (int64_t)vst->time_base.den) / (CDG_PACKET_SIZE * 300); return 0; } diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index 4b56b61404..6d5b9914f9 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -113,7 +113,8 @@ static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile, ConcatFile *file; char *url = NULL; const char *proto; - size_t url_len, proto_len; + const char *ptr; + size_t url_len; int ret; if (cat->safe > 0 && !safe_filename(filename)) { @@ -122,9 +123,8 @@ static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile, } proto = avio_find_protocol_name(filename); - proto_len = proto ? strlen(proto) : 0; - if (proto && !memcmp(filename, proto, proto_len) && - (filename[proto_len] == ':' || filename[proto_len] == ',')) { + if (proto && av_strstart(filename, proto, &ptr) && + (*ptr == ':' || *ptr == ',')) { url = filename; filename = NULL; } else { diff --git a/libavformat/dhav.c b/libavformat/dhav.c index 5e9abdb611..91c175498c 100644 --- a/libavformat/dhav.c +++ b/libavformat/dhav.c @@ -173,12 +173,12 @@ static int read_chunk(AVFormatContext *s) if (avio_feof(s->pb)) return AVERROR_EOF; - if (avio_rl32(s->pb) != MKTAG('D','H','A','V')) { + if (avio_rl32(s->pb) != MKTAG('D','H','A','V') && dhav->last_good_pos < INT64_MAX - 0x8000) { dhav->last_good_pos += 0x8000; avio_seek(s->pb, dhav->last_good_pos, SEEK_SET); while (avio_rl32(s->pb) != MKTAG('D','H','A','V')) { - if (avio_feof(s->pb)) + if (avio_feof(s->pb) || dhav->last_good_pos >= INT64_MAX - 0x8000) return AVERROR_EOF; dhav->last_good_pos += 0x8000; ret = avio_skip(s->pb, 0x8000 - 4); @@ -290,6 +290,8 @@ static int dhav_read_header(AVFormatContext *s) int seek_back; seek_back = avio_rl32(s->pb) + 8; + if (seek_back < 9) + break; dhav->last_good_pos = avio_tell(s->pb); avio_seek(s->pb, -seek_back, SEEK_CUR); } diff --git a/libavformat/dsfdec.c b/libavformat/dsfdec.c index c9740cf28f..1df163e114 100644 --- a/libavformat/dsfdec.c +++ b/libavformat/dsfdec.c @@ -124,8 +124,8 @@ static int dsf_read_header(AVFormatContext *s) dsf->audio_size = avio_rl64(pb) / 8 * st->codecpar->channels; st->codecpar->block_align = avio_rl32(pb); - if (st->codecpar->block_align > INT_MAX / st->codecpar->channels) { - avpriv_request_sample(s, "block_align overflow"); + if (st->codecpar->block_align > INT_MAX / st->codecpar->channels || st->codecpar->block_align <= 0) { + avpriv_request_sample(s, "block_align invalid"); return AVERROR_INVALIDDATA; } st->codecpar->block_align *= st->codecpar->channels; diff --git a/libavformat/dxa.c b/libavformat/dxa.c index 27fa6afb6a..909c5ba2ba 100644 --- a/libavformat/dxa.c +++ b/libavformat/dxa.c @@ -143,7 +143,7 @@ static int dxa_read_header(AVFormatContext *s) c->readvid = !c->has_sound; c->vidpos = avio_tell(pb); s->start_time = 0; - s->duration = (int64_t)c->frames * AV_TIME_BASE * num / den; + s->duration = av_rescale(c->frames, AV_TIME_BASE * (int64_t)num, den); av_log(s, AV_LOG_DEBUG, "%d frame(s)\n",c->frames); return 0; diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index 2ee5e1b6fa..5ad7e821d1 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -530,20 +530,17 @@ static int ea_read_header(AVFormatContext *s) if (ea->num_channels <= 0 || ea->num_channels > 2) { av_log(s, AV_LOG_WARNING, "Unsupported number of channels: %d\n", ea->num_channels); - ea->audio_codec = 0; - return 1; + goto no_audio; } if (ea->sample_rate <= 0) { av_log(s, AV_LOG_ERROR, "Unsupported sample rate: %d\n", ea->sample_rate); - ea->audio_codec = 0; - return 1; + goto no_audio; } if (ea->bytes <= 0 || ea->bytes > 2) { av_log(s, AV_LOG_ERROR, "Invalid number of bytes per sample: %d\n", ea->bytes); - ea->audio_codec = AV_CODEC_ID_NONE; - return 1; + goto no_audio; } /* initialize the audio decoder stream */ @@ -564,8 +561,13 @@ static int ea_read_header(AVFormatContext *s) st->codecpar->bits_per_coded_sample; ea->audio_stream_index = st->index; st->start_time = 0; + return 1; } +no_audio: + ea->audio_codec = AV_CODEC_ID_NONE; + if (!ea->video.codec) + return AVERROR_INVALIDDATA; return 1; } @@ -580,6 +582,8 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) int av_uninit(num_samples); while ((!packet_read && !hit_end) || partial_packet) { + if (avio_feof(pb)) + return AVERROR_EOF; chunk_type = avio_rl32(pb); chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb); if (chunk_size < 8) @@ -603,10 +607,14 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) break; } else if (ea->audio_codec == AV_CODEC_ID_PCM_S16LE_PLANAR || ea->audio_codec == AV_CODEC_ID_MP3) { + if (chunk_size < 12) + return AVERROR_INVALIDDATA; num_samples = avio_rl32(pb); avio_skip(pb, 8); chunk_size -= 12; } else if (ea->audio_codec == AV_CODEC_ID_ADPCM_PSX) { + if (chunk_size < 8) + return AVERROR_INVALIDDATA; avio_skip(pb, 8); chunk_size -= 8; } @@ -689,6 +697,8 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) case fVGT_TAG: case MADm_TAG: case MADe_TAG: + if (chunk_size > INT_MAX - 8) + return AVERROR_INVALIDDATA; avio_seek(pb, -8, SEEK_CUR); // include chunk preamble chunk_size += 8; goto get_video_packet; @@ -718,6 +728,7 @@ get_video_packet: ret = av_get_packet(pb, pkt, chunk_size); if (ret < 0) { packet_read = 1; + partial_packet = 0; break; } partial_packet = chunk_type == MVIh_TAG; diff --git a/libavformat/ffmetadec.c b/libavformat/ffmetadec.c index 45c92f1ff6..6a30b58c41 100644 --- a/libavformat/ffmetadec.c +++ b/libavformat/ffmetadec.c @@ -182,7 +182,7 @@ static int read_header(AVFormatContext *s) AVStream *st = avformat_new_stream(s, NULL); if (!st) - return AVERROR(ENOMEM); + goto nomem; st->codecpar->codec_type = AVMEDIA_TYPE_DATA; st->codecpar->codec_id = AV_CODEC_ID_FFMETADATA; @@ -192,7 +192,7 @@ static int read_header(AVFormatContext *s) AVChapter *ch = read_chapter(s); if (!ch) - return AVERROR(ENOMEM); + goto nomem; m = &ch->metadata; } else @@ -208,6 +208,10 @@ static int read_header(AVFormatContext *s) AV_TIME_BASE_Q); return 0; +nomem: + av_bprint_finalize(&bp, NULL); + + return AVERROR(ENOMEM); } static int read_packet(AVFormatContext *s, AVPacket *pkt) diff --git a/libavformat/fitsdec.c b/libavformat/fitsdec.c index e52ddc7e79..df757e868b 100644 --- a/libavformat/fitsdec.c +++ b/libavformat/fitsdec.c @@ -24,6 +24,7 @@ * FITS demuxer. */ +#include "libavutil/avassert.h" #include "libavutil/intreadwrite.h" #include "internal.h" #include "libavutil/opt.h" @@ -125,14 +126,14 @@ static int64_t is_image(AVFormatContext *s, FITSContext *fits, FITSHeader *heade size += header->pcount; t = (abs(header->bitpix) >> 3) * ((int64_t) header->gcount); - if(size && t > UINT64_MAX / size) + if(size && t > INT64_MAX / size) return AVERROR_INVALIDDATA; size *= t; if (!size) { image = 0; } else { - if(FITS_BLOCK_SIZE - 1 > UINT64_MAX - size) + if(FITS_BLOCK_SIZE - 1 > INT64_MAX - size) return AVERROR_INVALIDDATA; size = ((size + FITS_BLOCK_SIZE - 1) / FITS_BLOCK_SIZE) * FITS_BLOCK_SIZE; } @@ -173,6 +174,11 @@ static int fits_read_packet(AVFormatContext *s, AVPacket *pkt) goto fail; } + av_assert0(avbuf.len <= INT64_MAX && size <= INT64_MAX); + if (avbuf.len + size > INT_MAX - 80) { + ret = AVERROR_INVALIDDATA; + goto fail; + } // Header is sent with the first line removed... ret = av_new_packet(pkt, avbuf.len - 80 + size); if (ret < 0) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 957acedf39..334a5f4a7c 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -41,6 +41,8 @@ #define RESYNC_BUFFER_SIZE (1<<20) +#define MAX_DEPTH 16 ///< arbitrary limit to prevent unbounded recursion + typedef struct FLVContext { const AVClass *class; ///< Class for private options. int trust_metadata; ///< configure streams according onMetaData @@ -382,13 +384,18 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) { + int ret; int length = avio_rb16(ioc); if (length >= buffsize) { avio_skip(ioc, length); return -1; } - avio_read(ioc, buffer, length); + ret = avio_read(ioc, buffer, length); + if (ret < 0) + return ret; + if (ret < length) + return AVERROR_INVALIDDATA; buffer[length] = '\0'; @@ -493,8 +500,13 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, double num_val; amf_date date; + if (depth > MAX_DEPTH) + return AVERROR_PATCHWELCOME; + num_val = 0; ioc = s->pb; + if (avio_feof(ioc)) + return AVERROR_EOF; amf_type = avio_r8(ioc); switch (amf_type) { @@ -837,10 +849,16 @@ static void clear_index_entries(AVFormatContext *s, int64_t pos) } } -static int amf_skip_tag(AVIOContext *pb, AMFDataType type) +static int amf_skip_tag(AVIOContext *pb, AMFDataType type, int depth) { int nb = -1, ret, parse_name = 1; + if (depth > MAX_DEPTH) + return AVERROR_PATCHWELCOME; + + if (avio_feof(pb)) + return AVERROR_EOF; + switch (type) { case AMF_DATA_TYPE_NUMBER: avio_skip(pb, 8); @@ -865,7 +883,7 @@ static int amf_skip_tag(AVIOContext *pb, AMFDataType type) } avio_skip(pb, size); } - if ((ret = amf_skip_tag(pb, avio_r8(pb))) < 0) + if ((ret = amf_skip_tag(pb, avio_r8(pb), depth + 1)) < 0) return ret; } break; @@ -909,7 +927,7 @@ static int flv_data_packet(AVFormatContext *s, AVPacket *pkt, else break; } else { - if ((ret = amf_skip_tag(pb, type)) < 0) + if ((ret = amf_skip_tag(pb, type, 0)) < 0) goto skip; } } @@ -1161,7 +1179,7 @@ retry_duration: avio_seek(s->pb, fsize - 3 - size, SEEK_SET); if (size == avio_rb24(s->pb) + 11) { uint32_t ts = avio_rb24(s->pb); - ts |= avio_r8(s->pb) << 24; + ts |= (unsigned)avio_r8(s->pb) << 24; if (ts) s->duration = ts * (int64_t)AV_TIME_BASE / 1000; else if (fsize >= 8 && fsize - 8 >= size) { @@ -1234,7 +1252,7 @@ retry_duration: if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { // sign extension int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000; - pts = dts + cts; + pts = av_sat_add64(dts, cts); if (cts < 0) { // dts might be wrong if (!flv->wrong_dts) av_log(s, AV_LOG_WARNING, diff --git a/libavformat/genh.c b/libavformat/genh.c index 61adf49964..698104a9d6 100644 --- a/libavformat/genh.c +++ b/libavformat/genh.c @@ -87,7 +87,9 @@ static int genh_read_header(AVFormatContext *s) case 5: st->codecpar->codec_id = st->codecpar->block_align > 0 ? AV_CODEC_ID_PCM_S8_PLANAR : AV_CODEC_ID_PCM_S8; break; - case 6: st->codecpar->codec_id = AV_CODEC_ID_SDX2_DPCM; break; + case 6: if (st->codecpar->block_align > INT_MAX/1024) + return AVERROR_INVALIDDATA; + st->codecpar->codec_id = AV_CODEC_ID_SDX2_DPCM; break; case 7: ret = ff_alloc_extradata(st->codecpar, 2); if (ret < 0) return ret; @@ -144,6 +146,9 @@ static int genh_read_header(AVFormatContext *s) } } + if (st->codecpar->block_align <= 0) + return AVERROR_INVALIDDATA; + avio_skip(s->pb, start_offset - avio_tell(s->pb)); avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); diff --git a/libavformat/gxf.c b/libavformat/gxf.c index 49364b7205..bbad47c240 100644 --- a/libavformat/gxf.c +++ b/libavformat/gxf.c @@ -285,9 +285,12 @@ static void gxf_track_tags(AVIOContext *pb, int *len, struct gxf_stream_info *si static void gxf_read_index(AVFormatContext *s, int pkt_len) { AVIOContext *pb = s->pb; AVStream *st; - uint32_t fields_per_map = avio_rl32(pb); - uint32_t map_cnt = avio_rl32(pb); + uint32_t fields_per_map, map_cnt; int i; + if (pkt_len < 8) + return; + fields_per_map = avio_rl32(pb); + map_cnt = avio_rl32(pb); pkt_len -= 8; if ((s->flags & AVFMT_FLAG_IGNIDX) || !s->streams) { avio_skip(pb, pkt_len); diff --git a/libavformat/icodec.c b/libavformat/icodec.c index b47fa98f80..93179bb41e 100644 --- a/libavformat/icodec.c +++ b/libavformat/icodec.c @@ -84,6 +84,9 @@ static int read_header(AVFormatContext *s) avio_skip(pb, 4); ico->nb_images = avio_rl16(pb); + if (!ico->nb_images) + return AVERROR_INVALIDDATA; + ico->images = av_malloc_array(ico->nb_images, sizeof(IcoImage)); if (!ico->images) return AVERROR(ENOMEM); @@ -93,7 +96,7 @@ static int read_header(AVFormatContext *s) int tmp; if (avio_seek(pb, 6 + i * 16, SEEK_SET) < 0) - break; + goto fail; st = avformat_new_stream(s, NULL); if (!st) { @@ -113,13 +116,12 @@ static int read_header(AVFormatContext *s) ico->images[i].size = avio_rl32(pb); if (ico->images[i].size <= 0) { av_log(s, AV_LOG_ERROR, "Invalid image size %d\n", ico->images[i].size); - av_freep(&ico->images); - return AVERROR_INVALIDDATA; + goto fail; } ico->images[i].offset = avio_rl32(pb); if (avio_seek(pb, ico->images[i].offset, SEEK_SET) < 0) - break; + goto fail; codec = avio_rl32(pb); switch (codec) { @@ -130,8 +132,7 @@ static int read_header(AVFormatContext *s) break; case 40: if (ico->images[i].size < 40) { - av_freep(&ico->images); - return AVERROR_INVALIDDATA; + goto fail; } st->codecpar->codec_id = AV_CODEC_ID_BMP; tmp = avio_rl32(pb); @@ -143,12 +144,14 @@ static int read_header(AVFormatContext *s) break; default: avpriv_request_sample(s, "codec %d", codec); - av_freep(&ico->images); - return AVERROR_INVALIDDATA; + goto fail; } } return 0; +fail: + av_freep(&ico->images); + return AVERROR_INVALIDDATA; } static int read_packet(AVFormatContext *s, AVPacket *pkt) @@ -156,12 +159,14 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) IcoDemuxContext *ico = s->priv_data; IcoImage *image; AVIOContext *pb = s->pb; - AVStream *st = s->streams[0]; + AVStream *st; int ret; if (ico->current_image >= ico->nb_images) return AVERROR_EOF; + st = s->streams[0]; + image = &ico->images[ico->current_image]; if ((ret = avio_seek(pb, image->offset, SEEK_SET)) < 0) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index cecd9b9f6d..775fc0d514 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -605,7 +605,10 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, /* mimetype */ if (isv34) { - taglen -= avio_get_str(pb, taglen, mimetype, sizeof(mimetype)); + int ret = avio_get_str(pb, taglen, mimetype, sizeof(mimetype)); + if (ret < 0 || ret >= taglen) + goto fail; + taglen -= ret; } else { if (avio_read(pb, mimetype, 3) < 0) goto fail; @@ -993,6 +996,9 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, av_log(s, AV_LOG_DEBUG, "Compresssed frame %s tlen=%d dlen=%ld\n", tag, tlen, dlen); + if (tlen <= 0) + goto seek; + av_fast_malloc(&uncompressed_buffer, &uncompressed_buffer_size, dlen); if (!uncompressed_buffer) { av_log(s, AV_LOG_ERROR, "Failed to alloc %ld bytes\n", dlen); diff --git a/libavformat/iff.c b/libavformat/iff.c index 7feb121cd0..b07b6c8b18 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -223,6 +223,9 @@ static int parse_dsd_diin(AVFormatContext *s, AVStream *st, uint64_t eof) uint64_t orig_pos = avio_tell(pb); const char * metadata_tag = NULL; + if (size >= INT64_MAX) + return AVERROR_INVALIDDATA; + switch(tag) { case MKTAG('D','I','A','R'): metadata_tag = "artist"; break; case MKTAG('D','I','T','I'): metadata_tag = "title"; break; @@ -256,6 +259,9 @@ static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof) uint64_t size = avio_rb64(pb); uint64_t orig_pos = avio_tell(pb); + if (size >= INT64_MAX) + return AVERROR_INVALIDDATA; + switch(tag) { case MKTAG('A','B','S','S'): if (size < 8) @@ -362,7 +368,7 @@ static int read_dst_frame(AVFormatContext *s, AVPacket *pkt) data_size = iff->is_64bit ? avio_rb64(pb) : avio_rb32(pb); data_pos = avio_tell(pb); - if (data_size < 1) + if (data_size < 1 || data_size >= INT64_MAX) return AVERROR_INVALIDDATA; switch (chunk_id) { @@ -449,6 +455,9 @@ static int iff_read_header(AVFormatContext *s) data_size = iff->is_64bit ? avio_rb64(pb) : avio_rb32(pb); orig_pos = avio_tell(pb); + if (data_size >= INT64_MAX) + return AVERROR_INVALIDDATA; + switch(chunk_id) { case ID_VHDR: st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; @@ -754,7 +763,7 @@ static int iff_read_header(AVFormatContext *s) st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id); st->codecpar->bit_rate = (int64_t)st->codecpar->channels * st->codecpar->sample_rate * st->codecpar->bits_per_coded_sample; st->codecpar->block_align = st->codecpar->channels * st->codecpar->bits_per_coded_sample; - if (st->codecpar->codec_tag == ID_DSD && st->codecpar->block_align <= 0) + if ((st->codecpar->codec_tag == ID_DSD || st->codecpar->codec_tag == ID_MAUD) && st->codecpar->block_align <= 0) return AVERROR_INVALIDDATA; break; @@ -836,7 +845,7 @@ static int iff_read_packet(AVFormatContext *s, } else if (st->codecpar->codec_tag == ID_DST) { return read_dst_frame(s, pkt); } else { - if (iff->body_size > INT_MAX) + if (iff->body_size > INT_MAX || !iff->body_size) return AVERROR_INVALIDDATA; ret = av_get_packet(pb, pkt, iff->body_size); } @@ -872,6 +881,8 @@ static int iff_read_packet(AVFormatContext *s, pkt->flags |= AV_PKT_FLAG_KEY; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->codecpar->codec_tag != ID_ANIM) { + if (iff->body_size > INT_MAX || !iff->body_size) + return AVERROR_INVALIDDATA; ret = av_get_packet(pb, pkt, iff->body_size); pkt->pos = pos; if (pos == iff->body_pos) diff --git a/libavformat/ifv.c b/libavformat/ifv.c index f95e9b0e52..4e904fa828 100644 --- a/libavformat/ifv.c +++ b/libavformat/ifv.c @@ -210,6 +210,7 @@ static int ifv_read_packet(AVFormatContext *s, AVPacket *pkt) } if (!ev) { + uint64_t vframes, aframes; if (ifv->is_audio_present && !ea) { /*read new video and audio indexes*/ @@ -217,8 +218,12 @@ static int ifv_read_packet(AVFormatContext *s, AVPacket *pkt) ifv->next_audio_index = ifv->total_aframes; avio_skip(s->pb, 0x1c); - ifv->total_vframes += avio_rl32(s->pb); - ifv->total_aframes += avio_rl32(s->pb); + vframes = ifv->total_vframes + (uint64_t)avio_rl32(s->pb); + aframes = ifv->total_aframes + (uint64_t)avio_rl32(s->pb); + if (vframes > INT_MAX || aframes > INT_MAX) + return AVERROR_INVALIDDATA; + ifv->total_vframes = vframes; + ifv->total_aframes = aframes; avio_skip(s->pb, 0xc); if (avio_feof(s->pb)) @@ -240,7 +245,10 @@ static int ifv_read_packet(AVFormatContext *s, AVPacket *pkt) ifv->next_video_index = ifv->total_vframes; avio_skip(s->pb, 0x1c); - ifv->total_vframes += avio_rl32(s->pb); + vframes = ifv->total_vframes + (uint64_t)avio_rl32(s->pb); + if (vframes > INT_MAX) + return AVERROR_INVALIDDATA; + ifv->total_vframes = vframes; avio_skip(s->pb, 0x10); if (avio_feof(s->pb)) diff --git a/libavformat/jacosubdec.c b/libavformat/jacosubdec.c index 3414eb3938..e70ceeaafd 100644 --- a/libavformat/jacosubdec.c +++ b/libavformat/jacosubdec.c @@ -136,6 +136,7 @@ static int get_shift(int timeres, const char *buf) { int sign = 1; int a = 0, b = 0, c = 0, d = 0; + int64_t ret; #define SSEP "%*1[.:]" int n = sscanf(buf, "%d"SSEP"%d"SSEP"%d"SSEP"%d", &a, &b, &c, &d); #undef SSEP @@ -145,13 +146,16 @@ static int get_shift(int timeres, const char *buf) a = FFABS(a); } + ret = 0; switch (n) { - case 4: return sign * ((a*3600 + b*60 + c) * timeres + d); - case 3: return sign * (( a*60 + b) * timeres + c); - case 2: return sign * (( a) * timeres + b); + case 4: ret = sign * (((int64_t)a*3600 + b*60 + c) * timeres + d); + case 3: ret = sign * (( (int64_t)a*60 + b) * timeres + c); + case 2: ret = sign * (( (int64_t)a) * timeres + b); } + if ((int)ret != ret) + ret = 0; - return 0; + return ret; } static int jacosub_read_header(AVFormatContext *s) diff --git a/libavformat/kvag.c b/libavformat/kvag.c index 0a11fc0556..8f641873b9 100644 --- a/libavformat/kvag.c +++ b/libavformat/kvag.c @@ -83,7 +83,7 @@ static int kvag_read_header(AVFormatContext *s) par->bits_per_raw_sample = 16; par->block_align = 1; par->bit_rate = par->channels * - par->sample_rate * + (uint64_t)par->sample_rate * par->bits_per_coded_sample; avpriv_set_pts_info(st, 64, 1, par->sample_rate); diff --git a/libavformat/libsrt.c b/libavformat/libsrt.c index 4de575b37c..f73e7dbfa5 100644 --- a/libavformat/libsrt.c +++ b/libavformat/libsrt.c @@ -53,6 +53,7 @@ enum SRTMode { typedef struct SRTContext { const AVClass *class; int fd; + int listen_fd; int eid; int64_t rw_timeout; int64_t listen_timeout; @@ -313,8 +314,12 @@ static int libsrt_set_options_pre(URLContext *h, int fd) (s->pbkeylen >= 0 && libsrt_setsockopt(h, fd, SRTO_PBKEYLEN, "SRTO_PBKEYLEN", &s->pbkeylen, sizeof(s->pbkeylen)) < 0) || (s->passphrase && libsrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", s->passphrase, strlen(s->passphrase)) < 0) || #if SRT_VERSION_VALUE >= 0x010302 +#if SRT_VERSION_VALUE >= 0x010401 + (s->enforced_encryption >= 0 && libsrt_setsockopt(h, fd, SRTO_ENFORCEDENCRYPTION, "SRTO_ENFORCEDENCRYPTION", &s->enforced_encryption, sizeof(s->enforced_encryption)) < 0) || +#else /* SRTO_STRICTENC == SRTO_ENFORCEDENCRYPTION (53), but for compatibility, we used SRTO_STRICTENC */ (s->enforced_encryption >= 0 && libsrt_setsockopt(h, fd, SRTO_STRICTENC, "SRTO_STRICTENC", &s->enforced_encryption, sizeof(s->enforced_encryption)) < 0) || +#endif (s->kmrefreshrate >= 0 && libsrt_setsockopt(h, fd, SRTO_KMREFRESHRATE, "SRTO_KMREFRESHRATE", &s->kmrefreshrate, sizeof(s->kmrefreshrate)) < 0) || (s->kmpreannounce >= 0 && libsrt_setsockopt(h, fd, SRTO_KMPREANNOUNCE, "SRTO_KMPREANNOUNCE", &s->kmpreannounce, sizeof(s->kmpreannounce)) < 0) || #endif @@ -333,7 +338,11 @@ static int libsrt_set_options_pre(URLContext *h, int fd) (s->lossmaxttl >= 0 && libsrt_setsockopt(h, fd, SRTO_LOSSMAXTTL, "SRTO_LOSSMAXTTL", &s->lossmaxttl, sizeof(s->lossmaxttl)) < 0) || (s->minversion >= 0 && libsrt_setsockopt(h, fd, SRTO_MINVERSION, "SRTO_MINVERSION", &s->minversion, sizeof(s->minversion)) < 0) || (s->streamid && libsrt_setsockopt(h, fd, SRTO_STREAMID, "SRTO_STREAMID", s->streamid, strlen(s->streamid)) < 0) || +#if SRT_VERSION_VALUE >= 0x010401 + (s->smoother && libsrt_setsockopt(h, fd, SRTO_CONGESTION, "SRTO_CONGESTION", s->smoother, strlen(s->smoother)) < 0) || +#else (s->smoother && libsrt_setsockopt(h, fd, SRTO_SMOOTHER, "SRTO_SMOOTHER", s->smoother, strlen(s->smoother)) < 0) || +#endif (s->messageapi >= 0 && libsrt_setsockopt(h, fd, SRTO_MESSAGEAPI, "SRTO_MESSAGEAPI", &s->messageapi, sizeof(s->messageapi)) < 0) || (s->payload_size >= 0 && libsrt_setsockopt(h, fd, SRTO_PAYLOADSIZE, "SRTO_PAYLOADSIZE", &s->payload_size, sizeof(s->payload_size)) < 0) || ((h->flags & AVIO_FLAG_WRITE) && libsrt_setsockopt(h, fd, SRTO_SENDER, "SRTO_SENDER", &yes, sizeof(yes)) < 0)) { @@ -354,7 +363,7 @@ static int libsrt_set_options_pre(URLContext *h, int fd) static int libsrt_setup(URLContext *h, const char *uri, int flags) { struct addrinfo hints = { 0 }, *ai, *cur_ai; - int port, fd = -1; + int port, fd = -1, listen_fd = -1; SRTContext *s = h->priv_data; const char *p; char buf[256]; @@ -364,11 +373,6 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) int64_t open_timeout = 0; int eid; - eid = srt_epoll_create(); - if (eid < 0) - return libsrt_neterrno(h); - s->eid = eid; - av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), uri); if (strcmp(proto, "srt")) @@ -404,6 +408,11 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) cur_ai = ai; + eid = srt_epoll_create(); + if (eid < 0) + return libsrt_neterrno(h); + s->eid = eid; + restart: fd = srt_socket(cur_ai->ai_family, cur_ai->ai_socktype, 0); @@ -431,6 +440,7 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) // multi-client if ((ret = libsrt_listen(s->eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen, h, s->listen_timeout)) < 0) goto fail1; + listen_fd = fd; fd = ret; } else { if (s->mode == SRT_MODE_RENDEZVOUS) { @@ -463,6 +473,7 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) h->is_streamed = 1; s->fd = fd; + s->listen_fd = listen_fd; freeaddrinfo(ai); return 0; @@ -473,13 +484,18 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) cur_ai = cur_ai->ai_next; if (fd >= 0) srt_close(fd); + if (listen_fd >= 0) + srt_close(listen_fd); ret = 0; goto restart; } fail1: if (fd >= 0) srt_close(fd); + if (listen_fd >= 0) + srt_close(listen_fd); freeaddrinfo(ai); + srt_epoll_release(s->eid); return ret; } @@ -569,7 +585,8 @@ static int libsrt_open(URLContext *h, const char *uri, int flags) } else if (!strcmp(buf, "rendezvous")) { s->mode = SRT_MODE_RENDEZVOUS; } else { - return AVERROR(EIO); + ret = AVERROR(EINVAL); + goto err; } } if (av_find_info_tag(buf, sizeof(buf), "sndbuf", p)) { @@ -617,10 +634,15 @@ static int libsrt_open(URLContext *h, const char *uri, int flags) s->linger = strtol(buf, NULL, 10); } } - return libsrt_setup(h, uri, flags); + ret = libsrt_setup(h, uri, flags); + if (ret < 0) + goto err; + return 0; + err: av_freep(&s->smoother); av_freep(&s->streamid); + srt_cleanup(); return ret; } @@ -668,6 +690,9 @@ static int libsrt_close(URLContext *h) srt_close(s->fd); + if (s->listen_fd >= 0) + srt_close(s->listen_fd); + srt_epoll_release(s->eid); srt_cleanup(); diff --git a/libavformat/lrcdec.c b/libavformat/lrcdec.c index 46d5e2bc6a..ca23a60f84 100644 --- a/libavformat/lrcdec.c +++ b/libavformat/lrcdec.c @@ -185,6 +185,8 @@ static int lrc_read_header(AVFormatContext *s) sscanf(comma_offset + 1, "%"SCNd64, &lrc->ts_offset) != 1) { av_dict_set(&s->metadata, line.str + 1, comma_offset + 1, 0); } + lrc->ts_offset = av_clip64(lrc->ts_offset, INT64_MIN/4, INT64_MAX/4); + *comma_offset = ':'; *right_bracket_offset = ']'; } @@ -198,6 +200,7 @@ static int lrc_read_header(AVFormatContext *s) while((ts_stroffset_incr = read_ts(line.str + ts_stroffset, &ts_start)) != 0) { + ts_start = av_clip64(ts_start, INT64_MIN/4, INT64_MAX/4); ts_stroffset += ts_stroffset_incr; sub = ff_subtitles_queue_insert(&lrc->q, line.str + ts_strlength, line.len - ts_strlength, 0); diff --git a/libavformat/lvfdec.c b/libavformat/lvfdec.c index 8b8d6f01b9..4c87728def 100644 --- a/libavformat/lvfdec.c +++ b/libavformat/lvfdec.c @@ -106,6 +106,7 @@ static int lvf_read_packet(AVFormatContext *s, AVPacket *pkt) unsigned size, flags, timestamp, id; int64_t pos; int ret, is_video = 0; + int stream_index; pos = avio_tell(s->pb); while (!avio_feof(s->pb)) { @@ -121,12 +122,15 @@ static int lvf_read_packet(AVFormatContext *s, AVPacket *pkt) case MKTAG('0', '1', 'w', 'b'): if (size < 8) return AVERROR_INVALIDDATA; + stream_index = is_video ? 0 : 1; + if (stream_index >= s->nb_streams) + return AVERROR_INVALIDDATA; timestamp = avio_rl32(s->pb); flags = avio_rl32(s->pb); ret = av_get_packet(s->pb, pkt, size - 8); if (flags & (1 << 12)) pkt->flags |= AV_PKT_FLAG_KEY; - pkt->stream_index = is_video ? 0 : 1; + pkt->stream_index = stream_index; pkt->pts = timestamp; pkt->pos = pos; return ret; diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index cff7f0cb54..22d1ca5754 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2321,6 +2321,15 @@ static int matroska_parse_tracks(AVFormatContext *s) if (!track->codec_id) continue; + if ( track->type == MATROSKA_TRACK_TYPE_AUDIO && track->codec_id[0] != 'A' + || track->type == MATROSKA_TRACK_TYPE_VIDEO && track->codec_id[0] != 'V' + || track->type == MATROSKA_TRACK_TYPE_SUBTITLE && track->codec_id[0] != 'D' && track->codec_id[0] != 'S' + || track->type == MATROSKA_TRACK_TYPE_METADATA && track->codec_id[0] != 'D' && track->codec_id[0] != 'S' + ) { + av_log(matroska->ctx, AV_LOG_INFO, "Inconsistent track type\n"); + continue; + } + if (track->audio.samplerate < 0 || track->audio.samplerate > INT_MAX || isnan(track->audio.samplerate)) { av_log(matroska->ctx, AV_LOG_WARNING, diff --git a/libavformat/mov.c b/libavformat/mov.c index dfb41b93bf..702fc7fac5 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -290,6 +290,8 @@ static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len) return 0; n_hmmt = avio_rb32(pb); + if (n_hmmt > len / 4) + return AVERROR_INVALIDDATA; for (i = 0; i < n_hmmt && !pb->eof_reached; i++) { int moment_time = avio_rb32(pb); avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL); @@ -1119,7 +1121,7 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0); comp_brand_size = atom.size - 8; - if (comp_brand_size < 0) + if (comp_brand_size < 0 || comp_brand_size == INT_MAX) return AVERROR_INVALIDDATA; comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */ if (!comp_brands_str) @@ -2328,12 +2330,10 @@ FF_ENABLE_DEPRECATION_WARNINGS if (tmcd_ctx->tmcd_flags & 0x0008) { int timescale = AV_RB32(st->codecpar->extradata + 8); int framedur = AV_RB32(st->codecpar->extradata + 12); - st->avg_frame_rate.num *= timescale; - st->avg_frame_rate.den *= framedur; + st->avg_frame_rate = av_mul_q(st->avg_frame_rate, (AVRational){timescale, framedur}); #if FF_API_LAVF_AVCTX FF_DISABLE_DEPRECATION_WARNINGS - st->codec->time_base.den *= timescale; - st->codec->time_base.num *= framedur; + st->codec->time_base = av_mul_q(st->codec->time_base , (AVRational){framedur, timescale}); FF_ENABLE_DEPRECATION_WARNINGS #endif } @@ -4396,7 +4396,7 @@ static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom) { - int64_t end = avio_tell(pb) + atom.size; + int64_t end = av_sat_add64(avio_tell(pb), atom.size); uint8_t *key = NULL, *val = NULL, *mean = NULL; int i; int ret = 0; @@ -5520,6 +5520,10 @@ static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n"); return AVERROR_INVALIDDATA; } + + if (sc->stereo3d) + return AVERROR_INVALIDDATA; + avio_skip(pb, 4); /* version + flags */ mode = avio_r8(pb); @@ -6980,6 +6984,8 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) uint32_t type; avio_skip(pb, 4); type = avio_rl32(pb); + if (avio_feof(pb)) + break; avio_seek(pb, -8, SEEK_CUR); if (type == MKTAG('m','v','h','d') || type == MKTAG('c','m','o','v')) { @@ -7044,7 +7050,7 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) c->atom_depth --; return err; } - if (c->found_moov && c->found_mdat && + if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos && ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) || start_pos + a.size == avio_size(pb))) { if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index dd13bbd0a4..f33323a599 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -178,12 +178,16 @@ static void mpc8_parse_seektable(AVFormatContext *s, int64_t off) av_add_index_entry(s->streams[0], pos, i, 0, 0, AVINDEX_KEYFRAME); } for(; i < size; i++){ + if (get_bits_left(&gb) < 13) { + av_free(buf); + return; + } t = get_unary(&gb, 1, 33) << 12; t += get_bits(&gb, 12); if(t & 1) t = -(t & ~1); - pos = (t >> 1) + ppos[0]*2 - ppos[1]; - av_add_index_entry(s->streams[0], pos, i << seekd, 0, 0, AVINDEX_KEYFRAME); + pos = (t >> 1) + (uint64_t)ppos[0]*2 - ppos[1]; + av_add_index_entry(s->streams[0], pos, (int64_t)i << seekd, 0, 0, AVINDEX_KEYFRAME); ppos[1] = ppos[0]; ppos[0] = pos; } @@ -258,7 +262,7 @@ static int mpc8_read_header(AVFormatContext *s) st->codecpar->channels = (st->codecpar->extradata[1] >> 4) + 1; st->codecpar->sample_rate = mpc8_rate[st->codecpar->extradata[0] >> 5]; - avpriv_set_pts_info(st, 32, 1152 << (st->codecpar->extradata[1]&3)*2, st->codecpar->sample_rate); + avpriv_set_pts_info(st, 64, 1152 << (st->codecpar->extradata[1]&3)*2, st->codecpar->sample_rate); st->start_time = 0; st->duration = c->samples / (1152 << (st->codecpar->extradata[1]&3)*2); size -= avio_tell(pb) - pos; @@ -288,7 +292,7 @@ static int mpc8_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR_EOF; mpc8_get_chunk_header(s->pb, &tag, &size); - if (size < 0) + if (size < 0 || size > INT_MAX) return -1; if(tag == TAG_AUDIOPACKET){ if ((ret = av_get_packet(s->pb, pkt, size)) < 0) diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index 265b2bd1ad..a5e17925ce 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -147,9 +147,12 @@ static int mpegps_read_header(AVFormatContext *s) static int64_t get_pts(AVIOContext *pb, int c) { uint8_t buf[5]; + int ret; buf[0] = c < 0 ? avio_r8(pb) : c; - avio_read(pb, buf + 1, 4); + ret = avio_read(pb, buf + 1, 4); + if (ret < 4) + return AV_NOPTS_VALUE; return ff_parse_pes_pts(buf); } diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index c6fd3e1cef..bc24d89cd0 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -135,7 +135,7 @@ struct MpegTSContext { int fix_teletext_pts; int64_t cur_pcr; /**< used to estimate the exact PCR */ - int pcr_incr; /**< used to estimate the exact PCR */ + int64_t pcr_incr; /**< used to estimate the exact PCR */ /* data needed to handle file based ts */ /** stop parsing loop */ @@ -2352,7 +2352,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len goto out; // stop parsing after pmt, we found header - if (!ts->stream->nb_streams) + if (!ts->pkt) ts->stop_parse = 2; set_pmt_found(ts, h->id); @@ -3138,7 +3138,7 @@ static int mpegts_read_header(AVFormatContext *s) s->bit_rate = TS_PACKET_SIZE * 8 * 27000000LL / ts->pcr_incr; st->codecpar->bit_rate = s->bit_rate; st->start_time = ts->cur_pcr; - av_log(ts->stream, AV_LOG_TRACE, "start=%0.3f pcr=%0.3f incr=%d\n", + av_log(ts->stream, AV_LOG_TRACE, "start=%0.3f pcr=%0.3f incr=%"PRId64"\n", st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr); } @@ -3165,7 +3165,7 @@ static int mpegts_raw_read_packet(AVFormatContext *s, AVPacket *pkt) return ret; } if (data != pkt->data) - memcpy(pkt->data, data, ts->raw_packet_size); + memcpy(pkt->data, data, TS_PACKET_SIZE); finished_reading_packet(s, ts->raw_packet_size); if (ts->mpeg2ts_compute_pcr) { /* compute exact PCR for each packet */ diff --git a/libavformat/mpsubdec.c b/libavformat/mpsubdec.c index e7b83a1d85..2e6dc883eb 100644 --- a/libavformat/mpsubdec.c +++ b/libavformat/mpsubdec.c @@ -72,8 +72,8 @@ static int parse_line(const char *line, int64_t *value, int64_t *value2) fracval *= 10; for (;p2 - p1 > 7 + 1; p1++) fracval /= 10; - if (intval > 0) intval += fracval; - else intval -= fracval; + if (intval > 0) intval = av_sat_add64(intval, fracval); + else intval = av_sat_sub64(intval, fracval); line += p2; } else line += p1; diff --git a/libavformat/mvdec.c b/libavformat/mvdec.c index d5b400213d..7d59d82b13 100644 --- a/libavformat/mvdec.c +++ b/libavformat/mvdec.c @@ -159,7 +159,10 @@ static int parse_audio_var(AVFormatContext *avctx, AVStream *st, st->codecpar->sample_rate = var_read_int(pb, size); avpriv_set_pts_info(st, 33, 1, st->codecpar->sample_rate); } else if (!strcmp(name, "SAMPLE_WIDTH")) { - st->codecpar->bits_per_coded_sample = var_read_int(pb, size) * 8; + uint64_t bpc = var_read_int(pb, size) * (uint64_t)8; + if (bpc > 16) + return AVERROR_INVALIDDATA; + st->codecpar->bits_per_coded_sample = bpc; } else return AVERROR_INVALIDDATA; @@ -266,6 +269,8 @@ static void read_index(AVIOContext *pb, AVStream *st) uint32_t pos = avio_rb32(pb); uint32_t size = avio_rb32(pb); avio_skip(pb, 8); + if (avio_feof(pb)) + return ; av_add_index_entry(st, pos, timestamp, size, 0, AVINDEX_KEYFRAME); if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { timestamp += size / (st->codecpar->channels * 2LL); diff --git a/libavformat/mvi.c b/libavformat/mvi.c index ff5c08bf51..2d4b11aa32 100644 --- a/libavformat/mvi.c +++ b/libavformat/mvi.c @@ -94,7 +94,7 @@ static int read_header(AVFormatContext *s) vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; vst->codecpar->codec_id = AV_CODEC_ID_MOTIONPIXELS; - mvi->get_int = (vst->codecpar->width * vst->codecpar->height < (1 << 16)) ? avio_rl16 : avio_rl24; + mvi->get_int = (vst->codecpar->width * (int64_t)vst->codecpar->height < (1 << 16)) ? avio_rl16 : avio_rl24; mvi->audio_frame_size = ((uint64_t)mvi->audio_data_size << MVI_FRAC_BITS) / frames_count; if (mvi->audio_frame_size <= 1 << MVI_FRAC_BITS - 1) { @@ -123,6 +123,8 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) count = (mvi->audio_size_counter + mvi->audio_frame_size + 512) >> MVI_FRAC_BITS; if (count > mvi->audio_size_left) count = mvi->audio_size_left; + if ((int64_t)count << MVI_FRAC_BITS > INT_MAX) + return AVERROR_INVALIDDATA; if ((ret = av_get_packet(pb, pkt, count)) < 0) return ret; pkt->stream_index = MVI_AUDIO_STREAM_INDEX; diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 90546d42b3..ebbbbea2fb 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -330,9 +330,8 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx) MXFIndexTableSegment *seg; switch ((*ctx)->type) { case Descriptor: - av_freep(&((MXFDescriptor *)*ctx)->extradata); - break; case MultipleDescriptor: + av_freep(&((MXFDescriptor *)*ctx)->extradata); av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs); break; case Sequence: @@ -2737,8 +2736,11 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF int ret; int tag = avio_rb16(pb); int size = avio_rb16(pb); /* KLV specified by 0x53 */ - uint64_t next = avio_tell(pb) + size; + int64_t next = avio_tell(pb); UID uid = {0}; + if (next < 0 || next > INT64_MAX - size) + return next < 0 ? next : AVERROR_INVALIDDATA; + next += size; av_log(mxf->fc, AV_LOG_TRACE, "local tag %#04x size %d\n", tag, size); if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */ diff --git a/libavformat/nistspheredec.c b/libavformat/nistspheredec.c index 3ef3843d5e..78e938da10 100644 --- a/libavformat/nistspheredec.c +++ b/libavformat/nistspheredec.c @@ -90,6 +90,8 @@ static int nist_read_header(AVFormatContext *s) return 0; } else if (!memcmp(buffer, "channel_count", 13)) { sscanf(buffer, "%*s %*s %u", &st->codecpar->channels); + if (st->codecpar->channels <= 0 || st->codecpar->channels > INT16_MAX) + return AVERROR_INVALIDDATA; } else if (!memcmp(buffer, "sample_byte_format", 18)) { sscanf(buffer, "%*s %*s %31s", format); @@ -109,10 +111,14 @@ static int nist_read_header(AVFormatContext *s) sscanf(buffer, "%*s %*s %"SCNd64, &st->duration); } else if (!memcmp(buffer, "sample_n_bytes", 14)) { sscanf(buffer, "%*s %*s %d", &bps); + if (bps > INT16_MAX/8U) + return AVERROR_INVALIDDATA; } else if (!memcmp(buffer, "sample_rate", 11)) { sscanf(buffer, "%*s %*s %d", &st->codecpar->sample_rate); } else if (!memcmp(buffer, "sample_sig_bits", 15)) { sscanf(buffer, "%*s %*s %d", &st->codecpar->bits_per_coded_sample); + if (st->codecpar->bits_per_coded_sample <= 0 || st->codecpar->bits_per_coded_sample > INT16_MAX) + return AVERROR_INVALIDDATA; } else { char key[32], value[32]; if (sscanf(buffer, "%31s %*s %31s", key, value) == 2) { diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index 3779dce2a8..8b0ccf4aa8 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -193,13 +193,13 @@ static int decode_main_header(NUTContext *nut) { AVFormatContext *s = nut->avf; AVIOContext *bc = s->pb; - uint64_t tmp, end; + uint64_t tmp, end, length; unsigned int stream_count; int i, j, count, ret; int tmp_stream, tmp_mul, tmp_pts, tmp_size, tmp_res, tmp_head_idx; - end = get_packetheader(nut, bc, 1, MAIN_STARTCODE); - end += avio_tell(bc); + length = get_packetheader(nut, bc, 1, MAIN_STARTCODE); + end = length + avio_tell(bc); nut->version = ffio_read_varlen(bc); if (nut->version < NUT_MIN_VERSION || @@ -219,7 +219,7 @@ static int decode_main_header(NUTContext *nut) nut->max_distance = 65536; } - GET_V(nut->time_base_count, tmp > 0 && tmp < INT_MAX / sizeof(AVRational)); + GET_V(nut->time_base_count, tmp > 0 && tmp < INT_MAX / sizeof(AVRational) && tmp < length/2); nut->time_base = av_malloc_array(nut->time_base_count, sizeof(AVRational)); if (!nut->time_base) return AVERROR(ENOMEM); @@ -260,7 +260,7 @@ static int decode_main_header(NUTContext *nut) if (tmp_fields > 5) count = ffio_read_varlen(bc); else - count = tmp_mul - tmp_size; + count = tmp_mul - (unsigned)tmp_size; if (tmp_fields > 6) get_s(bc); if (tmp_fields > 7) diff --git a/libavformat/nuv.c b/libavformat/nuv.c index d99770d41d..df90df4938 100644 --- a/libavformat/nuv.c +++ b/libavformat/nuv.c @@ -117,6 +117,10 @@ static int get_codec_data(AVFormatContext *s, AVIOContext *pb, AVStream *vst, ast->codecpar->bits_per_coded_sample = avio_rl32(pb); ast->codecpar->channels = avio_rl32(pb); ast->codecpar->channel_layout = 0; + if (ast->codecpar->channels <= 0) { + av_log(s, AV_LOG_ERROR, "Invalid channels %d\n", ast->codecpar->channels); + return AVERROR_INVALIDDATA; + } id = ff_wav_codec_get_id(ast->codecpar->codec_tag, ast->codecpar->bits_per_coded_sample); diff --git a/libavformat/paf.c b/libavformat/paf.c index a31d01502b..9587111643 100644 --- a/libavformat/paf.c +++ b/libavformat/paf.c @@ -75,14 +75,18 @@ static int read_close(AVFormatContext *s) return 0; } -static void read_table(AVFormatContext *s, uint32_t *table, uint32_t count) +static int read_table(AVFormatContext *s, uint32_t *table, uint32_t count) { int i; - for (i = 0; i < count; i++) + for (i = 0; i < count; i++) { + if (avio_feof(s->pb)) + return AVERROR_INVALIDDATA; table[i] = avio_rl32(s->pb); + } avio_skip(s->pb, 4 * (FFALIGN(count, 512) - count)); + return 0; } static int read_header(AVFormatContext *s) @@ -171,9 +175,15 @@ static int read_header(AVFormatContext *s) avio_seek(pb, p->buffer_size, SEEK_SET); - read_table(s, p->blocks_count_table, p->nb_frames); - read_table(s, p->frames_offset_table, p->nb_frames); - read_table(s, p->blocks_offset_table, p->frame_blks); + ret = read_table(s, p->blocks_count_table, p->nb_frames); + if (ret < 0) + goto fail; + ret = read_table(s, p->frames_offset_table, p->nb_frames); + if (ret < 0) + goto fail; + ret = read_table(s, p->blocks_offset_table, p->frame_blks); + if (ret < 0) + goto fail; p->got_audio = 0; p->current_frame = 0; diff --git a/libavformat/pcm.c b/libavformat/pcm.c index 767bbd045a..1effc0b6f8 100644 --- a/libavformat/pcm.c +++ b/libavformat/pcm.c @@ -39,7 +39,11 @@ int ff_pcm_read_packet(AVFormatContext *s, AVPacket *pkt) * Clamp to RAW_SAMPLES if larger. */ size = FFMAX(par->sample_rate/25, 1); - size = FFMIN(size, RAW_SAMPLES) * par->block_align; + if (par->block_align <= INT_MAX / RAW_SAMPLES) { + size = FFMIN(size, RAW_SAMPLES) * par->block_align; + } else { + size = par->block_align; + } ret = av_get_packet(s->pb, pkt, size); diff --git a/libavformat/r3d.c b/libavformat/r3d.c index 7aa0c5a2c3..edd80ab4fa 100644 --- a/libavformat/r3d.c +++ b/libavformat/r3d.c @@ -322,7 +322,8 @@ static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom) pkt->stream_index = 1; pkt->dts = dts; - if (st->codecpar->sample_rate) + + if (st->codecpar->sample_rate && samples > 0) pkt->duration = av_rescale(samples, st->time_base.den, st->codecpar->sample_rate); av_log(s, AV_LOG_TRACE, "pkt dts %"PRId64" duration %"PRId64" samples %d sample rate %d\n", pkt->dts, pkt->duration, samples, st->codecpar->sample_rate); diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index a36e693ab2..49048ac4eb 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -162,7 +162,11 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, avio_rb16(pb); /* version2 */ avio_rb32(pb); /* header size */ flavor= avio_rb16(pb); /* add codec info / flavor */ - ast->coded_framesize = coded_framesize = avio_rb32(pb); /* coded frame size */ + coded_framesize = avio_rb32(pb); /* coded frame size */ + if (coded_framesize < 0) + return AVERROR_INVALIDDATA; + ast->coded_framesize = coded_framesize; + avio_rb32(pb); /* ??? */ bytes_per_minute = avio_rb32(pb); if (version == 4) { @@ -216,7 +220,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, if (version == 5) avio_r8(pb); codecdata_length = avio_rb32(pb); - if(codecdata_length + AV_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ + if((unsigned)codecdata_length > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE){ av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); return -1; } @@ -247,7 +251,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, if (version == 5) avio_r8(pb); codecdata_length = avio_rb32(pb); - if(codecdata_length + AV_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ + if((unsigned)codecdata_length > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE){ av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); return -1; } @@ -451,6 +455,8 @@ static int rm_read_index(AVFormatContext *s) } for (n = 0; n < n_pkts; n++) { + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; avio_skip(pb, 2); pts = avio_rb32(pb); pos = avio_rb32(pb); @@ -694,21 +700,23 @@ static int rm_sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stre state= (state<<8) + avio_r8(pb); if(state == MKBETAG('I', 'N', 'D', 'X')){ - int n_pkts, expected_len; + int n_pkts; + int64_t expected_len; len = avio_rb32(pb); avio_skip(pb, 2); n_pkts = avio_rb32(pb); - expected_len = 20 + n_pkts * 14; - if (len == 20) + expected_len = 20 + n_pkts * 14LL; + + if (len == 20 && expected_len <= INT_MAX) /* some files don't add index entries to chunk size... */ len = expected_len; else if (len != expected_len) av_log(s, AV_LOG_WARNING, - "Index size %d (%d pkts) is wrong, should be %d.\n", + "Index size %d (%d pkts) is wrong, should be %"PRId64".\n", len, n_pkts, expected_len); - len -= 14; // we already read part of the index header - if(len<0) + if(len < 14) continue; + len -= 14; // we already read part of the index header goto skip; } else if (state == MKBETAG('D','A','T','A')) { av_log(s, AV_LOG_WARNING, @@ -1278,8 +1286,11 @@ static int ivr_read_header(AVFormatContext *s) int j; av_log(s, AV_LOG_DEBUG, "%s = '0x", key); - for (j = 0; j < len; j++) + for (j = 0; j < len; j++) { + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; av_log(s, AV_LOG_DEBUG, "%X", avio_r8(pb)); + } av_log(s, AV_LOG_DEBUG, "'\n"); } else if (len == 4 && type == 3 && !strncmp(key, "Duration", tlen)) { st->duration = avio_rb32(pb); diff --git a/libavformat/rpl.c b/libavformat/rpl.c index 208c50f00c..0f00c03a52 100644 --- a/libavformat/rpl.c +++ b/libavformat/rpl.c @@ -253,6 +253,9 @@ static int rpl_read_header(AVFormatContext *s) error |= read_line(pb, line, sizeof(line)); } + if (s->nb_streams == 0) + return AVERROR_INVALIDDATA; + rpl->frames_per_chunk = read_line_and_int(pb, &error); // video frames per chunk if (vst && rpl->frames_per_chunk > 1 && vst->codecpar->codec_tag != 124) av_log(s, AV_LOG_WARNING, diff --git a/libavformat/rsd.c b/libavformat/rsd.c index e23c8abae5..9785a55726 100644 --- a/libavformat/rsd.c +++ b/libavformat/rsd.c @@ -103,13 +103,9 @@ static int rsd_read_header(AVFormatContext *s) break; case AV_CODEC_ID_ADPCM_PSX: par->block_align = 16 * par->channels; - if (pb->seekable & AVIO_SEEKABLE_NORMAL) - st->duration = av_get_audio_frame_duration2(par, avio_size(pb) - start); break; case AV_CODEC_ID_ADPCM_IMA_RAD: par->block_align = 20 * par->channels; - if (pb->seekable & AVIO_SEEKABLE_NORMAL) - st->duration = av_get_audio_frame_duration2(par, avio_size(pb) - start); break; case AV_CODEC_ID_ADPCM_IMA_WAV: if (version == 2) @@ -117,8 +113,6 @@ static int rsd_read_header(AVFormatContext *s) par->bits_per_coded_sample = 4; par->block_align = 36 * par->channels; - if (pb->seekable & AVIO_SEEKABLE_NORMAL) - st->duration = av_get_audio_frame_duration2(par, avio_size(pb) - start); break; case AV_CODEC_ID_ADPCM_THP_LE: /* RSD3GADP is mono, so only alloc enough memory @@ -128,8 +122,6 @@ static int rsd_read_header(AVFormatContext *s) if ((ret = ff_get_extradata(s, par, s->pb, 32)) < 0) return ret; - if (pb->seekable & AVIO_SEEKABLE_NORMAL) - st->duration = av_get_audio_frame_duration2(par, avio_size(pb) - start); break; case AV_CODEC_ID_ADPCM_THP: par->block_align = 8 * par->channels; @@ -139,21 +131,41 @@ static int rsd_read_header(AVFormatContext *s) return ret; for (i = 0; i < par->channels; i++) { + if (avio_feof(pb)) + return AVERROR_EOF; avio_read(s->pb, st->codecpar->extradata + 32 * i, 32); avio_skip(s->pb, 8); } - if (pb->seekable & AVIO_SEEKABLE_NORMAL) - st->duration = (avio_size(pb) - start) / (8 * par->channels) * 14; break; case AV_CODEC_ID_PCM_S16LE: case AV_CODEC_ID_PCM_S16BE: if (version != 4) start = avio_rl32(pb); - if (pb->seekable & AVIO_SEEKABLE_NORMAL) - st->duration = (avio_size(pb) - start) / 2 / par->channels; break; } + if (start < 0) + return AVERROR_INVALIDDATA; + + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { + int64_t remaining = avio_size(pb); + + if (remaining >= start && remaining - start <= INT_MAX) + switch (par->codec_id) { + case AV_CODEC_ID_ADPCM_PSX: + case AV_CODEC_ID_ADPCM_IMA_RAD: + case AV_CODEC_ID_ADPCM_IMA_WAV: + case AV_CODEC_ID_ADPCM_THP_LE: + st->duration = av_get_audio_frame_duration2(par, remaining - start); + break; + case AV_CODEC_ID_ADPCM_THP: + st->duration = (remaining - start) / (8 * par->channels) * 14; + break; + case AV_CODEC_ID_PCM_S16LE: + case AV_CODEC_ID_PCM_S16BE: + st->duration = (remaining - start) / 2 / par->channels; + } + } avio_skip(pb, start - avio_tell(pb)); if (par->codec_id == AV_CODEC_ID_XMA2) { diff --git a/libavformat/samidec.c b/libavformat/samidec.c index 3070ef9bac..cf5076c7b8 100644 --- a/libavformat/samidec.c +++ b/libavformat/samidec.c @@ -95,6 +95,11 @@ static int sami_read_header(AVFormatContext *s) const char *p = ff_smil_get_attr_ptr(buf.str, "Start"); sub->pos = pos; sub->pts = p ? strtol(p, NULL, 10) : 0; + if (sub->pts <= INT64_MIN/2 || sub->pts >= INT64_MAX/2) { + res = AVERROR_PATCHWELCOME; + goto end; + } + sub->duration = -1; } } diff --git a/libavformat/sbgdec.c b/libavformat/sbgdec.c index de1de271bb..d2a5a82c27 100644 --- a/libavformat/sbgdec.c +++ b/libavformat/sbgdec.c @@ -181,6 +181,7 @@ static int str_to_time(const char *str, int64_t *rtime) char *end; int hours, minutes; double seconds = 0; + int64_t ts = 0; if (*cur < '0' || *cur > '9') return 0; @@ -196,8 +197,9 @@ static int str_to_time(const char *str, int64_t *rtime) seconds = strtod(cur + 1, &end); if (end > cur + 1) cur = end; + ts = av_clipd(seconds * AV_TIME_BASE, INT64_MIN/2, INT64_MAX/2); } - *rtime = (hours * 3600LL + minutes * 60LL + seconds) * AV_TIME_BASE; + *rtime = av_sat_add64((hours * 3600LL + minutes * 60LL) * AV_TIME_BASE, ts); return cur - str; } @@ -536,6 +538,9 @@ static int parse_time_sequence(struct sbg_parser *p, int inblock) return AVERROR_INVALIDDATA; } ts.type = p->current_time.type; + + if (av_sat_add64(p->current_time.t, rel_ts) != p->current_time.t + (uint64_t)rel_ts) + return AVERROR_INVALIDDATA; ts.t = p->current_time.t + rel_ts; r = parse_fade(p, &fade); if (r < 0) @@ -1411,6 +1416,11 @@ static av_cold int sbg_read_header(AVFormatContext *avf) if (r < 0) goto fail; + if (script.end_ts != AV_NOPTS_VALUE && script.end_ts < script.start_ts) { + r = AVERROR_INVALIDDATA; + goto fail; + } + st = avformat_new_stream(avf, NULL); if (!st) return AVERROR(ENOMEM); diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index 777606bcb6..01422bdee6 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -144,8 +144,11 @@ static int film_read_header(AVFormatContext *s) film->video_type = AV_CODEC_ID_NONE; } + if (film->video_type == AV_CODEC_ID_NONE && film->audio_type == AV_CODEC_ID_NONE) + return AVERROR_INVALIDDATA; + /* initialize the decoder streams */ - if (film->video_type) { + if (film->video_type != AV_CODEC_ID_NONE) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); @@ -166,7 +169,7 @@ static int film_read_header(AVFormatContext *s) } } - if (film->audio_type) { + if (film->audio_type != AV_CODEC_ID_NONE) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); @@ -241,7 +244,7 @@ static int film_read_header(AVFormatContext *s) film->sample_table[i].pts = AV_RB32(&scratch[8]) & 0x7FFFFFFF; film->sample_table[i].keyframe = (scratch[8] & 0x80) ? 0 : AVINDEX_KEYFRAME; video_frame_counter++; - if (film->video_type) + if (film->video_type != AV_CODEC_ID_NONE) av_add_index_entry(s->streams[film->video_stream_index], film->sample_table[i].sample_offset, film->sample_table[i].pts, @@ -250,10 +253,10 @@ static int film_read_header(AVFormatContext *s) } } - if (film->audio_type) + if (film->audio_type != AV_CODEC_ID_NONE) s->streams[film->audio_stream_index]->duration = audio_frame_counter; - if (film->video_type) + if (film->video_type != AV_CODEC_ID_NONE) s->streams[film->video_stream_index]->duration = video_frame_counter; film->current_sample = 0; diff --git a/libavformat/siff.c b/libavformat/siff.c index f6815b2f26..60a867df14 100644 --- a/libavformat/siff.c +++ b/libavformat/siff.c @@ -201,6 +201,8 @@ static int siff_read_packet(AVFormatContext *s, AVPacket *pkt) if (c->curstrm == -1) { c->pktsize = avio_rl32(s->pb) - 4; c->flags = avio_rl16(s->pb); + if (c->flags & VB_HAS_AUDIO && !c->has_audio) + return AVERROR_INVALIDDATA; c->gmcsize = (c->flags & VB_HAS_GMC) ? 4 : 0; if (c->gmcsize) avio_read(s->pb, c->gmc, c->gmcsize); diff --git a/libavformat/smacker.c b/libavformat/smacker.c index 8b1e185817..14c5e3c1c7 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -104,8 +104,8 @@ static int smacker_read_header(AVFormatContext *s) height = avio_rl32(pb); smk->frames = avio_rl32(pb); pts_inc = avio_rl32(pb); - if (pts_inc > INT_MAX / 100) { - av_log(s, AV_LOG_ERROR, "pts_inc %d is too large\n", pts_inc); + if (pts_inc > INT_MAX / 100 || pts_inc == INT_MIN) { + av_log(s, AV_LOG_ERROR, "pts_inc %d is invalid\n", pts_inc); return AVERROR_INVALIDDATA; } diff --git a/libavformat/soxdec.c b/libavformat/soxdec.c index d3f709f9a6..35e11feec6 100644 --- a/libavformat/soxdec.c +++ b/libavformat/soxdec.c @@ -90,7 +90,7 @@ static int sox_read_header(AVFormatContext *s) sample_rate_frac); if ((header_size + 4) & 7 || header_size < SOX_FIXED_HDR + comment_size - || st->codecpar->channels > 65535) /* Reserve top 16 bits */ { + || st->codecpar->channels > 65535 || st->codecpar->channels <= 0) /* Reserve top 16 bits */ { av_log(s, AV_LOG_ERROR, "invalid header\n"); return AVERROR_INVALIDDATA; } diff --git a/libavformat/subviewerdec.c b/libavformat/subviewerdec.c index fdca3a4820..5c2fe676f1 100644 --- a/libavformat/subviewerdec.c +++ b/libavformat/subviewerdec.c @@ -148,6 +148,10 @@ static int subviewer_read_header(AVFormatContext *s) new_event = 1; pos = avio_tell(s->pb); } else if (*line) { + if (pts_start == AV_NOPTS_VALUE) { + res = AVERROR_INVALIDDATA; + goto end; + } if (!new_event) { sub = ff_subtitles_queue_insert(&subviewer->q, "\n", 1, 1); if (!sub) { diff --git a/libavformat/tedcaptionsdec.c b/libavformat/tedcaptionsdec.c index 3255819e77..8b44528982 100644 --- a/libavformat/tedcaptionsdec.c +++ b/libavformat/tedcaptionsdec.c @@ -181,6 +181,8 @@ static int parse_int(AVIOContext *pb, int *cur_byte, int64_t *result) if ((unsigned)*cur_byte - '0' > 9) return AVERROR_INVALIDDATA; while (BETWEEN(*cur_byte, '0', '9')) { + if (val > INT_MAX/10 - (*cur_byte - '0')) + return AVERROR_INVALIDDATA; val = val * 10 + (*cur_byte - '0'); next_byte(pb, cur_byte); } diff --git a/libavformat/tests/url.c b/libavformat/tests/url.c index 1d961a1b43..2eb597bb5e 100644 --- a/libavformat/tests/url.c +++ b/libavformat/tests/url.c @@ -21,10 +21,41 @@ #include "libavformat/url.h" #include "libavformat/avformat.h" +static void test_decompose(const char *url) +{ + URLComponents uc; + int len, ret; + + printf("%s =>\n", url); + ret = ff_url_decompose(&uc, url, NULL); + if (ret < 0) { + printf(" error: %s\n", av_err2str(ret)); + return; + } +#define PRINT_COMPONENT(comp) \ + len = uc.url_component_end_##comp - uc.comp; \ + if (len) printf(" "#comp": %.*s\n", len, uc.comp); + PRINT_COMPONENT(scheme); + PRINT_COMPONENT(authority); + PRINT_COMPONENT(userinfo); + PRINT_COMPONENT(host); + PRINT_COMPONENT(port); + PRINT_COMPONENT(path); + PRINT_COMPONENT(query); + PRINT_COMPONENT(fragment); + printf("\n"); +} + static void test(const char *base, const char *rel) { char buf[200], buf2[200]; - ff_make_absolute_url(buf, sizeof(buf), base, rel); + int ret; + + ret = ff_make_absolute_url(buf, sizeof(buf), base, rel); + if (ret < 0) { + printf("%50s %-20s => error %s\n", base, rel, av_err2str(ret)); + return; + } printf("%50s %-20s => %s\n", base, rel, buf); if (base) { /* Test in-buffer replacement */ @@ -51,6 +82,17 @@ static void test2(const char *url) int main(void) { + printf("Testing ff_url_decompose:\n\n"); + test_decompose("http://user:pass@ffmpeg:8080/dir/file?query#fragment"); + test_decompose("http://ffmpeg/dir/file"); + test_decompose("file:///dev/null"); + test_decompose("file:/dev/null"); + test_decompose("http://[::1]/dev/null"); + test_decompose("http://[::1]:8080/dev/null"); + test_decompose("//ffmpeg/dev/null"); + test_decompose("test?url=http://server/path"); + test_decompose("dummy.mp4#t=0:02:00,121.5"); + printf("Testing ff_make_absolute_url:\n"); test(NULL, "baz"); test("/foo/bar", "baz"); @@ -70,6 +112,58 @@ int main(void) test("http://server/foo/bar", "/../../../../../other/url"); test("http://server/foo/bar", "/test/../../../../../other/url"); test("http://server/foo/bar", "/test/../../test/../../../other/url"); + test("http://server/foo/bar", "file:../baz/qux"); + test("http://server/foo//bar/", "../../"); + test("file:../tmp/foo", "../bar/"); + test("file:../tmp/foo", "file:../bar/"); + test("http://server/foo/bar", "./"); + test("http://server/foo/bar", ".dotfile"); + test("http://server/foo/bar", "..doubledotfile"); + test("http://server/foo/bar", "double..dotfile"); + test("http://server/foo/bar", "doubledotfile.."); + + /* From https://tools.ietf.org/html/rfc3986#section-5.4 */ + test("http://a/b/c/d;p?q", "g:h"); // g:h + test("http://a/b/c/d;p?q", "g"); // http://a/b/c/g + test("http://a/b/c/d;p?q", "./g"); // http://a/b/c/g + test("http://a/b/c/d;p?q", "g/"); // http://a/b/c/g/ + test("http://a/b/c/d;p?q", "/g"); // http://a/g + test("http://a/b/c/d;p?q", "//g"); // http://g + test("http://a/b/c/d;p?q", "?y"); // http://a/b/c/d;p?y + test("http://a/b/c/d;p?q", "g?y"); // http://a/b/c/g?y + test("http://a/b/c/d;p?q", "#s"); // http://a/b/c/d;p?q#s + test("http://a/b/c/d;p?q", "g#s"); // http://a/b/c/g#s + test("http://a/b/c/d;p?q", "g?y#s"); // http://a/b/c/g?y#s + test("http://a/b/c/d;p?q", ";x"); // http://a/b/c/;x + test("http://a/b/c/d;p?q", "g;x"); // http://a/b/c/g;x + test("http://a/b/c/d;p?q", "g;x?y#s"); // http://a/b/c/g;x?y#s + test("http://a/b/c/d;p?q", ""); // http://a/b/c/d;p?q + test("http://a/b/c/d;p?q", "."); // http://a/b/c/ + test("http://a/b/c/d;p?q", "./"); // http://a/b/c/ + test("http://a/b/c/d;p?q", ".."); // http://a/b/ + test("http://a/b/c/d;p?q", "../"); // http://a/b/ + test("http://a/b/c/d;p?q", "../g"); // http://a/b/g + test("http://a/b/c/d;p?q", "../.."); // http://a/ + test("http://a/b/c/d;p?q", "../../"); // http://a/ + test("http://a/b/c/d;p?q", "../../g"); // http://a/g + test("http://a/b/c/d;p?q", "../../../g"); // http://a/g + test("http://a/b/c/d;p?q", "../../../../g"); // http://a/g + test("http://a/b/c/d;p?q", "/./g"); // http://a/g + test("http://a/b/c/d;p?q", "/../g"); // http://a/g + test("http://a/b/c/d;p?q", "g."); // http://a/b/c/g. + test("http://a/b/c/d;p?q", ".g"); // http://a/b/c/.g + test("http://a/b/c/d;p?q", "g.."); // http://a/b/c/g.. + test("http://a/b/c/d;p?q", "..g"); // http://a/b/c/..g + test("http://a/b/c/d;p?q", "./../g"); // http://a/b/g + test("http://a/b/c/d;p?q", "./g/."); // http://a/b/c/g/ + test("http://a/b/c/d;p?q", "g/./h"); // http://a/b/c/g/h + test("http://a/b/c/d;p?q", "g/../h"); // http://a/b/c/h + test("http://a/b/c/d;p?q", "g;x=1/./y"); // http://a/b/c/g;x=1/y + test("http://a/b/c/d;p?q", "g;x=1/../y"); // http://a/b/c/y + test("http://a/b/c/d;p?q", "g?y/./x"); // http://a/b/c/g?y/./x + test("http://a/b/c/d;p?q", "g?y/../x"); // http://a/b/c/g?y/../x + test("http://a/b/c/d;p?q", "g#s/./x"); // http://a/b/c/g#s/./x + test("http://a/b/c/d;p?q", "g#s/../x"); // http://a/b/c/g#s/../x printf("\nTesting av_url_split:\n"); test2("/foo/bar"); diff --git a/libavformat/tta.c b/libavformat/tta.c index 467c24455c..07faa82eb3 100644 --- a/libavformat/tta.c +++ b/libavformat/tta.c @@ -119,7 +119,7 @@ static int tta_read_header(AVFormatContext *s) for (i = 0; i < c->totalframes; i++) { uint32_t size = avio_rl32(s->pb); int r; - if ((r = av_add_index_entry(st, framepos, i * c->frame_size, size, 0, + if ((r = av_add_index_entry(st, framepos, i * (int64_t)c->frame_size, size, 0, AVINDEX_KEYFRAME)) < 0) return r; framepos += size; diff --git a/libavformat/url.c b/libavformat/url.c index 20463a6674..77d610d95f 100644 --- a/libavformat/url.c +++ b/libavformat/url.c @@ -27,6 +27,7 @@ #if CONFIG_NETWORK #include "network.h" #endif +#include "libavutil/avassert.h" #include "libavutil/avstring.h" /** @@ -78,146 +79,219 @@ int ff_url_join(char *str, int size, const char *proto, return strlen(str); } -static void trim_double_dot_url(char *buf, const char *rel, int size) +static const char *find_delim(const char *delim, const char *cur, const char *end) { - const char *p = rel; - const char *root = rel; - char tmp_path[MAX_URL_SIZE] = {0, }; - char *sep; - char *node; - - /* Get the path root of the url which start by "://" */ - if (p && (sep = strstr(p, "://"))) { - sep += 3; - root = strchr(sep, '/'); - if (!root) - return; - } - - /* set new current position if the root node is changed */ - p = root; - while (p && (node = strstr(p, ".."))) { - av_strlcat(tmp_path, p, node - p + strlen(tmp_path)); - p = node + 3; - sep = strrchr(tmp_path, '/'); - if (sep) - sep[0] = '\0'; - else - tmp_path[0] = '\0'; - } - - if (!av_stristart(p, "/", NULL) && root != rel) - av_strlcat(tmp_path, "/", size); - - av_strlcat(tmp_path, p, size); - /* start set buf after temp path process. */ - av_strlcpy(buf, rel, root - rel + 1); - - if (!av_stristart(tmp_path, "/", NULL) && root != rel) - av_strlcat(buf, "/", size); - - av_strlcat(buf, tmp_path, size); + while (cur < end && !strchr(delim, *cur)) + cur++; + return cur; } -void ff_make_absolute_url(char *buf, int size, const char *base, +int ff_url_decompose(URLComponents *uc, const char *url, const char *end) +{ + const char *cur, *aend, *p; + + av_assert0(url); + if (!end) + end = url + strlen(url); + cur = uc->url = url; + + /* scheme */ + uc->scheme = cur; + p = find_delim(":/?#", cur, end); /* lavf "schemes" can contain options but not some RFC 3986 delimiters */ + if (*p == ':') + cur = p + 1; + + /* authority */ + uc->authority = cur; + if (end - cur >= 2 && cur[0] == '/' && cur[1] == '/') { + cur += 2; + aend = find_delim("/?#", cur, end); + + /* userinfo */ + uc->userinfo = cur; + p = find_delim("@", cur, aend); + if (*p == '@') + cur = p + 1; + + /* host */ + uc->host = cur; + if (*cur == '[') { /* hello IPv6, thanks for using colons! */ + p = find_delim("]", cur, aend); + if (*p != ']') + return AVERROR(EINVAL); + if (p + 1 < aend && p[1] != ':') + return AVERROR(EINVAL); + cur = p + 1; + } else { + cur = find_delim(":", cur, aend); + } + + /* port */ + uc->port = cur; + cur = aend; + } else { + uc->userinfo = uc->host = uc->port = cur; + } + + /* path */ + uc->path = cur; + cur = find_delim("?#", cur, end); + + /* query */ + uc->query = cur; + if (*cur == '?') + cur = find_delim("#", cur, end); + + /* fragment */ + uc->fragment = cur; + + uc->end = end; + return 0; +} + +static int append_path(char *root, char *out_end, char **rout, + const char *in, const char *in_end) +{ + char *out = *rout; + const char *d, *next; + + if (in < in_end && *in == '/') + in++; /* already taken care of */ + while (in < in_end) { + d = find_delim("/", in, in_end); + next = d + (d < in_end && *d == '/'); + if (d - in == 1 && in[0] == '.') { + /* skip */ + } else if (d - in == 2 && in[0] == '.' && in[1] == '.') { + av_assert1(out[-1] == '/'); + if (out - root > 1) + while (out > root && (--out)[-1] != '/'); + } else { + if (out_end - out < next - in) + return AVERROR(ENOMEM); + memmove(out, in, next - in); + out += next - in; + } + in = next; + } + *rout = out; + return 0; +} + +int ff_make_absolute_url(char *buf, int size, const char *base, const char *rel) { - char *sep, *path_query; - char *root, *p; - char tmp_path[MAX_URL_SIZE]; + URLComponents ub, uc; + char *out, *out_end, *path; + const char *keep, *base_path_end; + int use_base_path, simplify_path = 0, ret; - memset(tmp_path, 0, sizeof(tmp_path)); - /* Absolute path, relative to the current server */ - if (base && strstr(base, "://") && rel[0] == '/') { - if (base != buf) - av_strlcpy(buf, base, size); - sep = strstr(buf, "://"); - if (sep) { - /* Take scheme from base url */ - if (rel[1] == '/') { - sep[1] = '\0'; - } else { - /* Take scheme and host from base url */ - sep += 3; - sep = strchr(sep, '/'); - if (sep) - *sep = '\0'; - } + /* This is tricky. + For HTTP, http://server/site/page + ../media/file + should resolve into http://server/media/file + but for filesystem access, dir/playlist + ../media/file + should resolve into dir/../media/file + because dir could be a symlink, and .. points to + the actual parent of the target directory. + + We'll consider that URLs with an actual scheme and authority, + i.e. starting with scheme://, need parent dir simplification, + while bare paths or pseudo-URLs starting with proto: without + the double slash do not. + + For real URLs, the processing is similar to the algorithm described + here: + https://tools.ietf.org/html/rfc3986#section-5 + */ + + if (!size) + return AVERROR(ENOMEM); + out = buf; + out_end = buf + size - 1; + + if (!base) + base = ""; + if ((ret = ff_url_decompose(&ub, base, NULL)) < 0 || + (ret = ff_url_decompose(&uc, rel, NULL)) < 0) + goto error; + + keep = ub.url; +#define KEEP(component, also) do { \ + if (uc.url_component_end_##component == uc.url && \ + ub.url_component_end_##component > keep) { \ + keep = ub.url_component_end_##component; \ + also \ + } \ + } while (0) + KEEP(scheme, ); + KEEP(authority_full, simplify_path = 1;); + KEEP(path,); + KEEP(query,); + KEEP(fragment,); +#undef KEEP +#define COPY(start, end) do { \ + size_t len = end - start; \ + if (len > out_end - out) { \ + ret = AVERROR(ENOMEM); \ + goto error; \ + } \ + memmove(out, start, len); \ + out += len; \ + } while (0) + COPY(ub.url, keep); + COPY(uc.url, uc.path); + + use_base_path = URL_COMPONENT_HAVE(ub, path) && keep <= ub.path; + if (uc.path > uc.url) + use_base_path = 0; + if (URL_COMPONENT_HAVE(uc, path) && uc.path[0] == '/') + use_base_path = 0; + if (use_base_path) { + base_path_end = ub.url_component_end_path; + if (URL_COMPONENT_HAVE(uc, path)) + while (base_path_end > ub.path && base_path_end[-1] != '/') + base_path_end--; + } + if (keep > ub.path) + simplify_path = 0; + if (URL_COMPONENT_HAVE(uc, scheme)) + simplify_path = 0; + if (URL_COMPONENT_HAVE(uc, authority)) + simplify_path = 1; + /* No path at all, leave it */ + if (!use_base_path && !URL_COMPONENT_HAVE(uc, path)) + simplify_path = 0; + + if (simplify_path) { + const char *root = "/"; + COPY(root, root + 1); + path = out; + if (use_base_path) { + ret = append_path(path, out_end, &out, ub.path, base_path_end); + if (ret < 0) + goto error; } - av_strlcat(buf, rel, size); - trim_double_dot_url(tmp_path, buf, size); - memset(buf, 0, size); - av_strlcpy(buf, tmp_path, size); - return; - } - /* If rel actually is an absolute url, just copy it */ - if (!base || strstr(rel, "://") || rel[0] == '/') { - memset(buf, 0, size); - trim_double_dot_url(buf, rel, size); - return; - } - if (base != buf) - av_strlcpy(buf, base, size); - - /* Strip off any query string from base */ - path_query = strchr(buf, '?'); - if (path_query) - *path_query = '\0'; - - /* Is relative path just a new query part? */ - if (rel[0] == '?') { - av_strlcat(buf, rel, size); - trim_double_dot_url(tmp_path, buf, size); - memset(buf, 0, size); - av_strlcpy(buf, tmp_path, size); - return; - } - - root = p = buf; - /* Get the path root of the url which start by "://" */ - if (p && strstr(p, "://")) { - sep = strstr(p, "://"); - if (sep) { - sep += 3; - root = strchr(sep, '/'); - if (!root) - return; + if (URL_COMPONENT_HAVE(uc, path)) { + ret = append_path(path, out_end, &out, uc.path, uc.url_component_end_path); + if (ret < 0) + goto error; } + } else { + if (use_base_path) + COPY(ub.path, base_path_end); + COPY(uc.path, uc.url_component_end_path); } - /* Remove the file name from the base url */ - sep = strrchr(buf, '/'); - if (sep && sep <= root) - sep = root; + COPY(uc.url_component_end_path, uc.end); +#undef COPY + *out = 0; + return 0; - if (sep) - sep[1] = '\0'; - else - buf[0] = '\0'; - while (av_strstart(rel, "..", NULL) && sep) { - /* Remove the path delimiter at the end */ - if (sep > root) { - sep[0] = '\0'; - sep = strrchr(buf, '/'); - } - - /* If the next directory name to pop off is "..", break here */ - if (!strcmp(sep ? &sep[1] : buf, "..")) { - /* Readd the slash we just removed */ - av_strlcat(buf, "/", size); - break; - } - /* Cut off the directory name */ - if (sep) - sep[1] = '\0'; - else - buf[0] = '\0'; - rel += 3; - } - av_strlcat(buf, rel, size); - trim_double_dot_url(tmp_path, buf, size); - memset(buf, 0, size); - av_strlcpy(buf, tmp_path, size); +error: + snprintf(buf, size, "invalid:%s", + ret == AVERROR(ENOMEM) ? "truncated" : + ret == AVERROR(EINVAL) ? "syntax_error" : ""); + return ret; } AVIODirEntry *ff_alloc_dir_entry(void) diff --git a/libavformat/url.h b/libavformat/url.h index 4750bfff82..728a861bd5 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -312,8 +312,8 @@ int ff_url_join(char *str, int size, const char *proto, * @param base the base url, may be equal to buf. * @param rel the new url, which is interpreted relative to base */ -void ff_make_absolute_url(char *buf, int size, const char *base, - const char *rel); +int ff_make_absolute_url(char *buf, int size, const char *base, + const char *rel); /** * Allocate directory entry with default values. @@ -340,4 +340,45 @@ const AVClass *ff_urlcontext_child_class_next(const AVClass *prev); const URLProtocol **ffurl_get_protocols(const char *whitelist, const char *blacklist); +typedef struct URLComponents { + const char *url; /**< whole URL, for reference */ + const char *scheme; /**< possibly including lavf-specific options */ + const char *authority; /**< "//" if it is a real URL */ + const char *userinfo; /**< including final '@' if present */ + const char *host; + const char *port; /**< including initial ':' if present */ + const char *path; + const char *query; /**< including initial '?' if present */ + const char *fragment; /**< including initial '#' if present */ + const char *end; +} URLComponents; + +#define url_component_end_scheme authority +#define url_component_end_authority userinfo +#define url_component_end_userinfo host +#define url_component_end_host port +#define url_component_end_port path +#define url_component_end_path query +#define url_component_end_query fragment +#define url_component_end_fragment end +#define url_component_end_authority_full path + +#define URL_COMPONENT_HAVE(uc, component) \ + ((uc).url_component_end_##component > (uc).component) + +/** + * Parse an URL to find the components. + * + * Each component runs until the start of the next component, + * possibly including a mandatory delimiter. + * + * @param uc structure to fill with pointers to the components. + * @param url URL to parse. + * @param end end of the URL, or NULL to parse to the end of string. + * + * @return >= 0 for success or an AVERROR code, especially if the URL is + * malformed. + */ +int ff_url_decompose(URLComponents *uc, const char *url, const char *end); + #endif /* AVFORMAT_URL_H */ diff --git a/libavformat/utils.c b/libavformat/utils.c index 8846842f33..7185fbfd71 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -243,13 +243,16 @@ int av_format_get_probe_score(const AVFormatContext *s) int ffio_limit(AVIOContext *s, int size) { if (s->maxsize>= 0) { - int64_t remaining= s->maxsize - avio_tell(s); + int64_t pos = avio_tell(s); + int64_t remaining= s->maxsize - pos; if (remaining < size) { int64_t newsize = avio_size(s); if (!s->maxsize || s->maxsizemaxsize = newsize - !newsize; - remaining= s->maxsize - avio_tell(s); - remaining= FFMAX(remaining, 0); + if (pos > s->maxsize && s->maxsize >= 0) + s->maxsize = AVERROR(EIO); + if (s->maxsize >= 0) + remaining = s->maxsize - pos; } if (s->maxsize>= 0 && remaining+1 < size) { @@ -1134,6 +1137,7 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index, dts == AV_NOPTS_VALUE || st->cur_dts == AV_NOPTS_VALUE || st->cur_dts < INT_MIN + RELATIVE_TS_BASE || + dts < INT_MIN + (st->cur_dts - RELATIVE_TS_BASE) || is_relative(dts)) return; @@ -1220,7 +1224,7 @@ static void update_initial_durations(AVFormatContext *s, AVStream *st, if (!st->internal->avctx->has_b_frames) pktl->pkt.pts = cur_dts; // if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) - pktl->pkt.duration = duration; + pktl->pkt.duration = duration; } else break; cur_dts = pktl->pkt.dts + pktl->pkt.duration; @@ -1283,7 +1287,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, presentation_delayed = 1; if (pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && - st->pts_wrap_bits < 63 && + st->pts_wrap_bits < 63 && pkt->dts > INT64_MIN + (1LL << (st->pts_wrap_bits - 1)) && pkt->dts - (1LL << (st->pts_wrap_bits - 1)) > pkt->pts) { if (is_relative(st->cur_dts) || pkt->dts - (1LL<<(st->pts_wrap_bits - 1)) > st->cur_dts) { pkt->dts -= 1LL << st->pts_wrap_bits; @@ -4745,8 +4749,11 @@ int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number if (c == '%') { do { nd = 0; - while (av_isdigit(*p)) + while (av_isdigit(*p)) { + if (nd >= INT_MAX / 10 - 255) + goto fail; nd = nd * 10 + *p++ - '0'; + } c = *p++; } while (av_isdigit(c)); diff --git a/libavformat/vividas.c b/libavformat/vividas.c index 828fbed998..12554f46cd 100644 --- a/libavformat/vividas.c +++ b/libavformat/vividas.c @@ -294,6 +294,8 @@ static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t * for (i=0;itime_base.num = avio_rl32(pb); // frame_time - st->time_base.den = avio_rl32(pb); // time_base + num = avio_rl32(pb); // frame_time + den = avio_rl32(pb); // time_base + avpriv_set_pts_info(st, 64, num, den); st->nb_frames = avio_rl32(pb); // n frames st->codecpar->width = avio_rl16(pb); // width st->codecpar->height = avio_rl16(pb); // height @@ -368,6 +373,8 @@ static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t * avio_rl16(pb); //codec_subid st->codecpar->channels = avio_rl16(pb); // channels st->codecpar->sample_rate = avio_rl32(pb); // sample_rate + if (st->codecpar->sample_rate <= 0 || st->codecpar->channels <= 0) + return AVERROR_INVALIDDATA; avio_seek(pb, 10, SEEK_CUR); // data_1 q = avio_r8(pb); avio_seek(pb, q, SEEK_CUR); // data_2 @@ -384,8 +391,8 @@ static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t * ffio_read_varlen(pb); // len_3 num_data = avio_r8(pb); for (j = 0; j < num_data; j++) { - uint64_t len = ffio_read_varlen(pb); - if (len > INT_MAX/2 - xd_size) { + int64_t len = ffio_read_varlen(pb); + if (len < 0 || len > INT_MAX/2 - xd_size) { return AVERROR_INVALIDDATA; } data_len[j] = len; @@ -666,6 +673,10 @@ static int viv_read_packet(AVFormatContext *s, if (!pb) return AVERROR(EIO); off = avio_tell(pb); + + if (viv->current_sb_entry >= viv->n_sb_entries) + return AVERROR_INVALIDDATA; + off += viv->sb_entries[viv->current_sb_entry].size; if (viv->sb_entries[viv->current_sb_entry].flag == 0) { @@ -675,7 +686,7 @@ static int viv_read_packet(AVFormatContext *s, return AVERROR_INVALIDDATA; ffio_read_varlen(pb); - if (v_size > INT_MAX) + if (v_size > INT_MAX || !v_size) return AVERROR_INVALIDDATA; ret = av_get_packet(pb, pkt, v_size); if (ret < 0) @@ -704,7 +715,7 @@ static int viv_read_packet(AVFormatContext *s, } else { uint64_t v_size = ffio_read_varlen(pb); - if (v_size > INT_MAX) + if (v_size > INT_MAX || !v_size) return AVERROR_INVALIDDATA; ret = av_get_packet(pb, pkt, v_size); if (ret < 0) diff --git a/libavformat/vqf.c b/libavformat/vqf.c index 617a9706f4..449f4061f7 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -132,6 +132,9 @@ static int vqf_read_header(AVFormatContext *s) switch(chunk_tag){ case MKTAG('C','O','M','M'): + if (len < 12) + return AVERROR_INVALIDDATA; + avio_read(s->pb, comm_chunk, 12); st->codecpar->channels = AV_RB32(comm_chunk ) + 1; read_bitrate = AV_RB32(comm_chunk + 4); diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index c35966f970..309bb6573e 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -69,7 +69,7 @@ static void set_spdif(AVFormatContext *s, WAVDemuxContext *wav) int ret = ffio_ensure_seekback(s->pb, len); if (ret >= 0) { - uint8_t *buf = av_malloc(len); + uint8_t *buf = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE); if (!buf) { ret = AVERROR(ENOMEM); } else { @@ -589,7 +589,8 @@ break_loop: } else if (st->codecpar->codec_id == AV_CODEC_ID_XMA1 || st->codecpar->codec_id == AV_CODEC_ID_XMA2) { st->codecpar->block_align = 2048; - } else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS && st->codecpar->channels > 2) { + } else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS && st->codecpar->channels > 2 && + st->codecpar->block_align < INT_MAX / st->codecpar->channels) { st->codecpar->block_align *= st->codecpar->channels; } @@ -613,7 +614,7 @@ static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16]) while (!avio_feof(pb)) { avio_read(pb, guid, 16); size = avio_rl64(pb); - if (size <= 24) + if (size <= 24 || size > INT64_MAX - 8) return AVERROR_INVALIDDATA; if (!memcmp(guid, guid1, 16)) return size; @@ -850,6 +851,7 @@ static int w64_read_header(AVFormatContext *s) } else if (!memcmp(guid, ff_w64_guid_summarylist, 16)) { int64_t start, end, cur; uint32_t count, chunk_size, i; + int64_t filesize = avio_size(s->pb); start = avio_tell(pb); end = start + FFALIGN(size, INT64_C(8)) - 24; @@ -864,7 +866,7 @@ static int w64_read_header(AVFormatContext *s) chunk_key[4] = 0; avio_read(pb, chunk_key, 4); chunk_size = avio_rl32(pb); - if (chunk_size == UINT32_MAX) + if (chunk_size == UINT32_MAX || (filesize >= 0 && chunk_size > filesize)) return AVERROR_INVALIDDATA; value = av_mallocz(chunk_size + 1); @@ -872,6 +874,10 @@ static int w64_read_header(AVFormatContext *s) return AVERROR(ENOMEM); ret = avio_get_str16le(pb, chunk_size, value, chunk_size); + if (ret < 0) { + av_free(value); + return ret; + } avio_skip(pb, chunk_size - ret); av_dict_set(&s->metadata, chunk_key, value, AV_DICT_DONT_STRDUP_VAL); diff --git a/libavformat/wc3movie.c b/libavformat/wc3movie.c index 6577007777..76e945d261 100644 --- a/libavformat/wc3movie.c +++ b/libavformat/wc3movie.c @@ -73,6 +73,16 @@ typedef struct Wc3DemuxContext { } Wc3DemuxContext; +static int wc3_read_close(AVFormatContext *s) +{ + Wc3DemuxContext *wc3 = s->priv_data; + + if (wc3->vpkt.size > 0) + av_packet_unref(&wc3->vpkt); + + return 0; +} + static int wc3_probe(const AVProbeData *p) { if (p->buf_size < 12) @@ -129,10 +139,14 @@ static int wc3_read_header(AVFormatContext *s) /* load up the name */ buffer = av_malloc(size+1); if (!buffer) - return AVERROR(ENOMEM); + if (!buffer) { + ret = AVERROR(ENOMEM); + goto fail; + } if ((ret = avio_read(pb, buffer, size)) != size) { av_freep(&buffer); - return AVERROR(EIO); + ret = AVERROR(EIO); + goto fail; } buffer[size] = 0; av_dict_set(&s->metadata, "title", buffer, @@ -154,21 +168,26 @@ static int wc3_read_header(AVFormatContext *s) default: av_log(s, AV_LOG_ERROR, "unrecognized WC3 chunk: %s\n", av_fourcc2str(fourcc_tag)); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } fourcc_tag = avio_rl32(pb); /* chunk sizes are 16-bit aligned */ size = (avio_rb32(pb) + 1) & (~1); - if (avio_feof(pb)) - return AVERROR(EIO); + if (avio_feof(pb)) { + ret = AVERROR(EIO); + goto fail; + } } while (fourcc_tag != BRCH_TAG); /* initialize the decoder streams */ st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); + if (!st) { + ret = AVERROR(ENOMEM); + goto fail; + } avpriv_set_pts_info(st, 33, 1, WC3_FRAME_FPS); wc3->video_stream_index = st->index; st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; @@ -178,8 +197,10 @@ static int wc3_read_header(AVFormatContext *s) st->codecpar->height = wc3->height; st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); + if (!st) { + ret = AVERROR(ENOMEM); + goto fail; + } avpriv_set_pts_info(st, 33, 1, WC3_FRAME_FPS); wc3->audio_stream_index = st->index; st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; @@ -194,6 +215,9 @@ static int wc3_read_header(AVFormatContext *s) st->codecpar->block_align = WC3_AUDIO_BITS * WC3_AUDIO_CHANNELS; return 0; +fail: + wc3_read_close(s); + return ret; } static int wc3_read_packet(AVFormatContext *s, @@ -286,16 +310,6 @@ static int wc3_read_packet(AVFormatContext *s, return ret; } -static int wc3_read_close(AVFormatContext *s) -{ - Wc3DemuxContext *wc3 = s->priv_data; - - if (wc3->vpkt.size > 0) - av_packet_unref(&wc3->vpkt); - - return 0; -} - AVInputFormat ff_wc3_demuxer = { .name = "wc3movie", .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III movie"), diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c index 83f510b92f..aa6ff78c4b 100644 --- a/libavformat/wtvdec.c +++ b/libavformat/wtvdec.c @@ -273,6 +273,11 @@ static AVIOContext * wtvfile_open2(AVFormatContext *s, const uint8_t *buf, int b "bad filename length, remaining directory entries ignored\n"); break; } + if (dir_length == 0) { + av_log(s, AV_LOG_ERROR, + "bad dir length, remaining directory entries ignored\n"); + break; + } if (48 + (int64_t)name_size > buf_end - buf) { av_log(s, AV_LOG_ERROR, "filename exceeds buffer size; remaining directory entries ignored\n"); break; @@ -789,7 +794,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p ff_get_guid(pb, &g); len = avio_rl32(pb); - if (len < 32) { + if (len < 32 || len > INT_MAX - 7) { int ret; if (avio_feof(pb)) return AVERROR_EOF; diff --git a/libavformat/wvdec.c b/libavformat/wvdec.c index b9fc6a59f9..7a5997c1ee 100644 --- a/libavformat/wvdec.c +++ b/libavformat/wvdec.c @@ -79,8 +79,9 @@ static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb) { WVContext *wc = ctx->priv_data; int ret; - int rate, rate_x, bpp, chan; + int rate, bpp, chan; uint32_t chmask, flags; + unsigned rate_x; wc->pos = avio_tell(pb); @@ -192,7 +193,7 @@ static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb) if (id & 0x40) avio_skip(pb, 1); } - if (rate == -1) { + if (rate == -1 || rate * (uint64_t)rate_x >= INT_MAX) { av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n"); return AVERROR_INVALIDDATA; diff --git a/libavformat/xwma.c b/libavformat/xwma.c index 5a57caa841..aedadcf140 100644 --- a/libavformat/xwma.c +++ b/libavformat/xwma.c @@ -211,6 +211,10 @@ static int xwma_read_header(AVFormatContext *s) } for (i = 0; i < dpds_table_size; ++i) { + if (avio_feof(pb)) { + ret = AVERROR_INVALIDDATA; + goto fail; + } dpds_table[i] = avio_rl32(pb); size -= 4; } diff --git a/libavutil/eval.c b/libavutil/eval.c index d527f6a9d0..c743ee3dfc 100644 --- a/libavutil/eval.c +++ b/libavutil/eval.c @@ -306,7 +306,7 @@ static double eval_expr(Parser *p, AVExpr *e) double d = eval_expr(p, e->param[0]); double d2 = eval_expr(p, e->param[1]); switch (e->type) { - case e_mod: return e->value * (d - floor((!CONFIG_FTRAPV || d2) ? d / d2 : d * INFINITY) * d2); + case e_mod: return e->value * (d - floor(d2 ? d / d2 : d * INFINITY) * d2); case e_gcd: return e->value * av_gcd(d,d2); case e_max: return e->value * (d > d2 ? d : d2); case e_min: return e->value * (d < d2 ? d : d2); diff --git a/libavutil/fixed_dsp.c b/libavutil/fixed_dsp.c index 8c018581df..f1b195f184 100644 --- a/libavutil/fixed_dsp.c +++ b/libavutil/fixed_dsp.c @@ -134,9 +134,10 @@ static int scalarproduct_fixed_c(const int *v1, const int *v2, int len) return (int)(p >> 31); } -static void butterflies_fixed_c(int *v1, int *v2, int len) +static void butterflies_fixed_c(int *v1s, int *v2, int len) { int i; + unsigned int *v1 = v1s; for (i = 0; i < len; i++){ int t = v1[i] - v2[i]; diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c index 16c6e4db03..da0fc17b2e 100644 --- a/libavutil/mathematics.c +++ b/libavutil/mathematics.c @@ -210,6 +210,6 @@ int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t i if (old == INT64_MAX || old == AV_NOPTS_VALUE || old_ts == AV_NOPTS_VALUE) return ts; - return av_rescale_q(old + 1, inc_tb, ts_tb) + (ts - old_ts); + return av_sat_add64(av_rescale_q(old + 1, inc_tb, ts_tb), ts - old_ts); } } diff --git a/libavutil/timecode.c b/libavutil/timecode.c index 60077ba0c0..76163d5553 100644 --- a/libavutil/timecode.c +++ b/libavutil/timecode.c @@ -49,7 +49,7 @@ int av_timecode_adjust_ntsc_framenum2(int framenum, int fps) d = framenum / frames_per_10mins; m = framenum % frames_per_10mins; - return framenum + 9 * drop_frames * d + drop_frames * ((m - drop_frames) / (frames_per_10mins / 10)); + return framenum + 9U * drop_frames * d + drop_frames * ((m - drop_frames) / (frames_per_10mins / 10)); } uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum) diff --git a/libavutil/x86/x86inc.asm b/libavutil/x86/x86inc.asm index 5044ee86f0..01c35e3a4b 100644 --- a/libavutil/x86/x86inc.asm +++ b/libavutil/x86/x86inc.asm @@ -411,16 +411,6 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 %endif %endmacro -%macro DEFINE_ARGS_INTERNAL 3+ - %ifnum %2 - DEFINE_ARGS %3 - %elif %1 == 4 - DEFINE_ARGS %2 - %elif %1 > 4 - DEFINE_ARGS %2, %3 - %endif -%endmacro - %if WIN64 ; Windows x64 ;================================================= DECLARE_REG 0, rcx @@ -439,7 +429,7 @@ DECLARE_REG 12, R15, 104 DECLARE_REG 13, R12, 112 DECLARE_REG 14, R13, 120 -%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... +%macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... %assign num_args %1 %assign regs_used %2 ASSERT regs_used >= num_args @@ -451,7 +441,15 @@ DECLARE_REG 14, R13, 120 WIN64_SPILL_XMM %3 %endif LOAD_IF_USED 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 - DEFINE_ARGS_INTERNAL %0, %4, %5 + %if %0 > 4 + %ifnum %4 + DEFINE_ARGS %5 + %else + DEFINE_ARGS %4, %5 + %endif + %elifnnum %4 + DEFINE_ARGS %4 + %endif %endmacro %macro WIN64_PUSH_XMM 0 @@ -547,7 +545,7 @@ DECLARE_REG 12, R15, 56 DECLARE_REG 13, R12, 64 DECLARE_REG 14, R13, 72 -%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... +%macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... %assign num_args %1 %assign regs_used %2 %assign xmm_regs_used %3 @@ -557,7 +555,15 @@ DECLARE_REG 14, R13, 72 PUSH_IF_USED 9, 10, 11, 12, 13, 14 ALLOC_STACK %4 LOAD_IF_USED 6, 7, 8, 9, 10, 11, 12, 13, 14 - DEFINE_ARGS_INTERNAL %0, %4, %5 + %if %0 > 4 + %ifnum %4 + DEFINE_ARGS %5 + %else + DEFINE_ARGS %4, %5 + %endif + %elifnnum %4 + DEFINE_ARGS %4 + %endif %endmacro %define has_epilogue regs_used > 9 || stack_size > 0 || vzeroupper_required @@ -598,7 +604,7 @@ DECLARE_REG 6, ebp, 28 DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 -%macro PROLOGUE 2-5+ ; #args, #regs, #xmm_regs, [stack_size,] arg_names... +%macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... %assign num_args %1 %assign regs_used %2 ASSERT regs_used >= num_args @@ -613,7 +619,15 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 PUSH_IF_USED 3, 4, 5, 6 ALLOC_STACK %4 LOAD_IF_USED 0, 1, 2, 3, 4, 5, 6 - DEFINE_ARGS_INTERNAL %0, %4, %5 + %if %0 > 4 + %ifnum %4 + DEFINE_ARGS %5 + %else + DEFINE_ARGS %4, %5 + %endif + %elifnnum %4 + DEFINE_ARGS %4 + %endif %endmacro %define has_epilogue regs_used > 3 || stack_size > 0 || vzeroupper_required diff --git a/libswscale/x86/yuv_2_rgb.asm b/libswscale/x86/yuv_2_rgb.asm index 575a84d921..2f0b4130df 100644 --- a/libswscale/x86/yuv_2_rgb.asm +++ b/libswscale/x86/yuv_2_rgb.asm @@ -268,9 +268,9 @@ cglobal %1_420_%2%3, GPR_num, GPR_num, reg_num, parameters por m2, m7 por m1, m6 ; g5 b5 r6 g6 b6 r7 g7 b7 r8 g8 b8 r9 g9 b9 r10 g10 por m2, m3 ; b10 r11 g11 b11 r12 g12 b12 r13 g13 b13 r14 g14 b14 r15 g15 b15 - mova [imageq], m0 - mova [imageq + 16], m1 - mova [imageq + 32], m2 + movu [imageq], m0 + movu [imageq + 16], m1 + movu [imageq + 32], m2 %endif ; mmsize = 16 %else ; PACK RGB15/16/32 packuswb m0, m1 @@ -286,7 +286,7 @@ cglobal %1_420_%2%3, GPR_num, GPR_num, reg_num, parameters %ifidn %1, yuv pcmpeqd m3, m3 ; Set alpha empty %else - mova m3, [pa_2indexq + 2 * indexq] ; Load alpha + movu m3, [pa_2indexq + 2 * indexq] ; Load alpha %endif mova m5, m_blue mova m6, m_red @@ -300,10 +300,10 @@ cglobal %1_420_%2%3, GPR_num, GPR_num, reg_num, parameters punpckhwd m_green, m_red punpcklwd m5, m6 punpckhwd m_alpha, m6 - mova [imageq + 0], m_blue - mova [imageq + 8 * time_num], m_green - mova [imageq + 16 * time_num], m5 - mova [imageq + 24 * time_num], m_alpha + movu [imageq + 0], m_blue + movu [imageq + 8 * time_num], m_green + movu [imageq + 16 * time_num], m5 + movu [imageq + 24 * time_num], m_alpha %else ; PACK RGB15/16 %define depth 2 %if cpuflag(ssse3) @@ -342,8 +342,8 @@ cglobal %1_420_%2%3, GPR_num, GPR_num, reg_num, parameters mova m2, m0 punpcklbw m0, m1 punpckhbw m2, m1 - mova [imageq], m0 - mova [imageq + 8 * time_num], m2 + movu [imageq], m0 + movu [imageq + 8 * time_num], m2 %endif ; PACK RGB15/16 %endif ; PACK RGB15/16/32 diff --git a/tests/checkasm/vf_blend.c b/tests/checkasm/vf_blend.c index a7578fec39..bdd21d4986 100644 --- a/tests/checkasm/vf_blend.c +++ b/tests/checkasm/vf_blend.c @@ -99,7 +99,7 @@ void checkasm_check_blend(void) #define check_and_report(name, val, depth) \ param.mode = val; \ - ff_blend_init(¶m, depth - 1); \ + ff_blend_init(¶m, depth * 8); \ if (check_func(param.blend, #name)) \ check_blend_func(depth); diff --git a/tests/ref/fate/url b/tests/ref/fate/url index 533ba2cb1e..08e80def7d 100644 --- a/tests/ref/fate/url +++ b/tests/ref/fate/url @@ -1,9 +1,62 @@ +Testing ff_url_decompose: + +http://user:pass@ffmpeg:8080/dir/file?query#fragment => + scheme: http: + authority: // + userinfo: user:pass@ + host: ffmpeg + port: :8080 + path: /dir/file + query: ?query + fragment: #fragment + +http://ffmpeg/dir/file => + scheme: http: + authority: // + host: ffmpeg + path: /dir/file + +file:///dev/null => + scheme: file: + authority: // + path: /dev/null + +file:/dev/null => + scheme: file: + path: /dev/null + +http://[::1]/dev/null => + scheme: http: + authority: // + host: [::1] + path: /dev/null + +http://[::1]:8080/dev/null => + scheme: http: + authority: // + host: [::1] + port: :8080 + path: /dev/null + +//ffmpeg/dev/null => + authority: // + host: ffmpeg + path: /dev/null + +test?url=http://server/path => + path: test + query: ?url=http://server/path + +dummy.mp4#t=0:02:00,121.5 => + path: dummy.mp4 + fragment: #t=0:02:00,121.5 + Testing ff_make_absolute_url: (null) baz => baz /foo/bar baz => /foo/baz - /foo/bar ../baz => /baz + /foo/bar ../baz => /foo/../baz /foo/bar /baz => /baz - /foo/bar ../../../baz => /baz + /foo/bar ../../../baz => /foo/../../../baz http://server/foo/ baz => http://server/foo/baz http://server/foo/bar baz => http://server/foo/baz http://server/foo/ ../baz => http://server/baz @@ -17,6 +70,56 @@ Testing ff_make_absolute_url: http://server/foo/bar /../../../../../other/url => http://server/other/url http://server/foo/bar /test/../../../../../other/url => http://server/other/url http://server/foo/bar /test/../../test/../../../other/url => http://server/other/url + http://server/foo/bar file:../baz/qux => file:../baz/qux + http://server/foo//bar/ ../../ => http://server/foo/ + file:../tmp/foo ../bar/ => file:../tmp/../bar/ + file:../tmp/foo file:../bar/ => file:../bar/ + http://server/foo/bar ./ => http://server/foo/ + http://server/foo/bar .dotfile => http://server/foo/.dotfile + http://server/foo/bar ..doubledotfile => http://server/foo/..doubledotfile + http://server/foo/bar double..dotfile => http://server/foo/double..dotfile + http://server/foo/bar doubledotfile.. => http://server/foo/doubledotfile.. + http://a/b/c/d;p?q g:h => g:h + http://a/b/c/d;p?q g => http://a/b/c/g + http://a/b/c/d;p?q ./g => http://a/b/c/g + http://a/b/c/d;p?q g/ => http://a/b/c/g/ + http://a/b/c/d;p?q /g => http://a/g + http://a/b/c/d;p?q //g => http://g + http://a/b/c/d;p?q ?y => http://a/b/c/d;p?y + http://a/b/c/d;p?q g?y => http://a/b/c/g?y + http://a/b/c/d;p?q #s => http://a/b/c/d;p?q#s + http://a/b/c/d;p?q g#s => http://a/b/c/g#s + http://a/b/c/d;p?q g?y#s => http://a/b/c/g?y#s + http://a/b/c/d;p?q ;x => http://a/b/c/;x + http://a/b/c/d;p?q g;x => http://a/b/c/g;x + http://a/b/c/d;p?q g;x?y#s => http://a/b/c/g;x?y#s + http://a/b/c/d;p?q => http://a/b/c/d;p?q + http://a/b/c/d;p?q . => http://a/b/c/ + http://a/b/c/d;p?q ./ => http://a/b/c/ + http://a/b/c/d;p?q .. => http://a/b/ + http://a/b/c/d;p?q ../ => http://a/b/ + http://a/b/c/d;p?q ../g => http://a/b/g + http://a/b/c/d;p?q ../.. => http://a/ + http://a/b/c/d;p?q ../../ => http://a/ + http://a/b/c/d;p?q ../../g => http://a/g + http://a/b/c/d;p?q ../../../g => http://a/g + http://a/b/c/d;p?q ../../../../g => http://a/g + http://a/b/c/d;p?q /./g => http://a/g + http://a/b/c/d;p?q /../g => http://a/g + http://a/b/c/d;p?q g. => http://a/b/c/g. + http://a/b/c/d;p?q .g => http://a/b/c/.g + http://a/b/c/d;p?q g.. => http://a/b/c/g.. + http://a/b/c/d;p?q ..g => http://a/b/c/..g + http://a/b/c/d;p?q ./../g => http://a/b/g + http://a/b/c/d;p?q ./g/. => http://a/b/c/g/ + http://a/b/c/d;p?q g/./h => http://a/b/c/g/h + http://a/b/c/d;p?q g/../h => http://a/b/c/h + http://a/b/c/d;p?q g;x=1/./y => http://a/b/c/g;x=1/y + http://a/b/c/d;p?q g;x=1/../y => http://a/b/c/y + http://a/b/c/d;p?q g?y/./x => http://a/b/c/g?y/./x + http://a/b/c/d;p?q g?y/../x => http://a/b/c/g?y/../x + http://a/b/c/d;p?q g#s/./x => http://a/b/c/g#s/./x + http://a/b/c/d;p?q g#s/../x => http://a/b/c/g#s/../x Testing av_url_split: /foo/bar => -1 /foo/bar