From 7fece7676b6bffd9f697455c1fc99c02fd4d5c27 Mon Sep 17 00:00:00 2001 From: James Almer Date: Mon, 17 Apr 2023 00:11:06 -0300 Subject: [PATCH] avcodec/hevc_ps: further constrain allowed num_ref_loc_offsets values The spec says: "The value of num_ref_loc_offsets shall be in the range of 0 to vps_max_layers_minus1, inclusive". Signed-off-by: James Almer --- libavcodec/hevc_ps.c | 13 +++++++------ libavcodec/hevc_ps.h | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index be1d668c26..69d5504ce1 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -1384,18 +1384,17 @@ static void colour_mapping_table(GetBitContext *gb, HEVCPPS *pps) } static int pps_multilayer_extension(GetBitContext *gb, AVCodecContext *avctx, - HEVCPPS *pps, HEVCSPS *sps) + HEVCPPS *pps, HEVCSPS *sps, HEVCVPS *vps) { pps->poc_reset_info_present_flag = get_bits1(gb); pps->pps_infer_scaling_list_flag = get_bits1(gb); if (pps->pps_infer_scaling_list_flag) pps->pps_scaling_list_ref_layer_id = get_bits(gb, 6); - pps->num_ref_loc_offsets = get_ue_golomb_long(gb); - if (pps->num_ref_loc_offsets > FF_ARRAY_ELEMS(pps->ref_loc_offset_layer_id)) { - pps->num_ref_loc_offsets = 0; + pps->num_ref_loc_offsets = get_ue_golomb(gb); + if (pps->num_ref_loc_offsets > vps->vps_max_layers - 1) return AVERROR_INVALIDDATA; - } + for (int i = 0; i < pps->num_ref_loc_offsets; i++) { pps->ref_loc_offset_layer_id[i] = get_bits(gb, 6); pps->scaled_ref_layer_offset_present_flag[i] = get_bits1(gb); @@ -1693,6 +1692,7 @@ int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, HEVCParamSets *ps) { HEVCSPS *sps = NULL; + HEVCVPS *vps = NULL; int i, ret = 0; unsigned int pps_id = 0; ptrdiff_t nal_size; @@ -1753,6 +1753,7 @@ int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, goto err; } sps = (HEVCSPS *)ps->sps_list[pps->sps_id]->data; + vps = (HEVCVPS *)ps->vps_list[sps->vps_id]->data; pps->dependent_slice_segments_enabled_flag = get_bits1(gb); pps->output_flag_present_flag = get_bits1(gb); @@ -1921,7 +1922,7 @@ int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, } if (pps->pps_multilayer_extension_flag) { - if ((ret = pps_multilayer_extension(gb, avctx, pps, sps)) < 0) + if ((ret = pps_multilayer_extension(gb, avctx, pps, sps, vps)) < 0) goto err; } diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h index 1f704108e3..184f87a001 100644 --- a/libavcodec/hevc_ps.h +++ b/libavcodec/hevc_ps.h @@ -314,7 +314,7 @@ typedef struct HEVCPPS { uint8_t poc_reset_info_present_flag; uint8_t pps_infer_scaling_list_flag; uint8_t pps_scaling_list_ref_layer_id; - uint16_t num_ref_loc_offsets; + uint8_t num_ref_loc_offsets; uint8_t ref_loc_offset_layer_id[64]; uint8_t scaled_ref_layer_offset_present_flag[64]; int8_t scaled_ref_layer_left_offset[64];