From: Nuo Mi <nuomi2021@gmail.com> To: Frank Plowman <post@frankplowman.com> Cc: toqsxw@outlook.com, ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH] lavc/vvc: Add max parameter to kth_order_egk_decode Date: Mon, 14 Jul 2025 12:43:04 +0800 Message-ID: <CAFXK13cp6Bd2OP9QwYgWgtGcd4QuxSsqTxH5V3VWkdosU3KsbQ@mail.gmail.com> (raw) In-Reply-To: <20250712104010.92291-1-post@frankplowman.com> Hi Frank, thank you for the patch On Sat, Jul 12, 2025 at 6:41 PM Frank Plowman <post@frankplowman.com> wrote: > Prior to this patch, kth_order_egk_decode could read arbitrarily > large values which then overflowed and caused various issues. > Patch fixes this by making kth_order_egk_decode falliable, > requiring the caller to specify an upper bound and returning an > error if the read value would exceed that bound. > > This patch resolves the same issue as > eb52251c0ab025b6b40b28994bc9dc616813b190, but I think this is the proper > fix as it also addresses issues with syntax elements besides > ff_vvc_num_signalled_palette_entries. > > Patch also includes a minor fix in hls_palette_coding, where the > error code returned by palette_subblock_data was previously unchecked. > It's better to provide a separate patch for this, it will help with bisecting issues more easily. > > Signed-off-by: Frank Plowman <post@frankplowman.com> > --- > I would appreciate a second pair of eyes on my changes to > kth_order_egk_decode, particularly wrt the behaviour concerning > potential overflows. My understanding when writing this was that > overflows can only potentially occur when reading the prefix, hence the > per-prefix bit check there. Then for the suffix no overflow can occur > so we just check the final value. > The suffix involves a shift operation, so overflow is theoretically possible. However, since we provide a max, overflow will not occur. > --- > libavcodec/vvc/cabac.c | 27 ++++++++++++++++----------- > libavcodec/vvc/cabac.h | 6 +++--- > libavcodec/vvc/ctu.c | 39 +++++++++++++++++++++++++-------------- > 3 files changed, 44 insertions(+), 28 deletions(-) > > diff --git a/libavcodec/vvc/cabac.c b/libavcodec/vvc/cabac.c > index 6847ce59af..e0cc82c3e1 100644 > --- a/libavcodec/vvc/cabac.c > +++ b/libavcodec/vvc/cabac.c > @@ -929,24 +929,29 @@ static int truncated_binary_decode(VVCLocalContext > *lc, const int c_max) > } > > // 9.3.3.5 k-th order Exp - Golomb binarization process > -static int kth_order_egk_decode(CABACContext *c, int k) > +static int kth_order_egk_decode(CABACContext *c, int *value, int k, const > int max) The return value is never negative under normal conditions, so we can use a negative value to indicate an error. This allows us to simplify the function signature as follows: static int kth_order_egk_decode(CABACContext *c, int k, const int max) > { > int bit = 1; > - int value = 0; > int symbol = 0; > + *value = 0; > > while (bit) { > bit = get_cabac_bypass(c); > - value += bit << k++; > + if (max - *value < (bit << k)) > + return AVERROR_INVALIDDATA; > + *value += bit << k++; > } > > if (--k) { > for (int i = 0; i < k; i++) > symbol = (symbol << 1) | get_cabac_bypass(c); > - value += symbol; > + *value += symbol; > } > > - return value; > + if (*value > max) > + return AVERROR_INVALIDDATA; > + > + return 0; > } > > // 9.3.3.6 Limited k-th order Exp-Golomb binarization process > @@ -1377,14 +1382,14 @@ int ff_vvc_intra_chroma_pred_mode(VVCLocalContext > *lc) > return (get_cabac_bypass(&lc->ep->cc) << 1) | > get_cabac_bypass(&lc->ep->cc); > } > > -int ff_vvc_palette_predictor_run(VVCLocalContext *lc) > +int ff_vvc_palette_predictor_run(VVCLocalContext *lc, int *value, const > int max) > { > - return kth_order_egk_decode(&lc->ep->cc, 0); > + return kth_order_egk_decode(&lc->ep->cc, value, 0, max); > } > > -int ff_vvc_num_signalled_palette_entries(VVCLocalContext *lc) > +int ff_vvc_num_signalled_palette_entries(VVCLocalContext *lc, int *value, > const int max) > { > - return kth_order_egk_decode(&lc->ep->cc, 0); > + return kth_order_egk_decode(&lc->ep->cc, value, 0, max); > } > > int ff_vvc_new_palette_entries(VVCLocalContext *lc, const int bit_depth) > @@ -1424,9 +1429,9 @@ int ff_vvc_palette_idx_idc(VVCLocalContext *lc, > const int max_palette_index, con > return truncated_binary_decode(lc, max_palette_index - adjust); > } > > -int ff_vvc_palette_escape_val(VVCLocalContext *lc) > +int ff_vvc_palette_escape_val(VVCLocalContext *lc, int *value, const int > max) > { > - return kth_order_egk_decode(&lc->ep->cc, 5); > + return kth_order_egk_decode(&lc->ep->cc, value, 5, max); > } > > int ff_vvc_general_merge_flag(VVCLocalContext *lc) > diff --git a/libavcodec/vvc/cabac.h b/libavcodec/vvc/cabac.h > index 972890317e..a0bea4a426 100644 > --- a/libavcodec/vvc/cabac.h > +++ b/libavcodec/vvc/cabac.h > @@ -81,15 +81,15 @@ int ff_vvc_intra_luma_mpm_remainder(VVCLocalContext > *lc); > int ff_vvc_cclm_mode_flag(VVCLocalContext *lc); > int ff_vvc_cclm_mode_idx(VVCLocalContext *lc); > int ff_vvc_intra_chroma_pred_mode(VVCLocalContext *lc); > -int ff_vvc_palette_predictor_run(VVCLocalContext *lc); > -int ff_vvc_num_signalled_palette_entries(VVCLocalContext *lc); > +int ff_vvc_palette_predictor_run(VVCLocalContext *lc, int *value, const > int max); > +int ff_vvc_num_signalled_palette_entries(VVCLocalContext *lc, int *value, > const int max); > int ff_vvc_new_palette_entries(VVCLocalContext *lc, int bit_dpeth); > bool ff_vvc_palette_escape_val_present_flag(VVCLocalContext *lc); > bool ff_vvc_palette_transpose_flag(VVCLocalContext *lc); > bool ff_vvc_run_copy_flag(VVCLocalContext *lc, int prev_run_type, int > prev_run_position, int cur_pos); > bool ff_vvc_copy_above_palette_indices_flag(VVCLocalContext *lc); > int ff_vvc_palette_idx_idc(VVCLocalContext *lc, int max_palette_index, > bool adjust); > -int ff_vvc_palette_escape_val(VVCLocalContext *lc); > +int ff_vvc_palette_escape_val(VVCLocalContext *lc, int *value, const int > max); > > //inter > int ff_vvc_general_merge_flag(VVCLocalContext *lc); > diff --git a/libavcodec/vvc/ctu.c b/libavcodec/vvc/ctu.c > index cf7edccb8b..b0fe36e817 100644 > --- a/libavcodec/vvc/ctu.c > +++ b/libavcodec/vvc/ctu.c > @@ -1850,6 +1850,7 @@ static int palette_predicted(VVCLocalContext *lc, > const bool local_dual_tree, in > { > CodingUnit *cu = lc->cu; > int nb_predicted = 0; > + int ret; > > if (local_dual_tree) { > start = LUMA; > @@ -1857,16 +1858,17 @@ static int palette_predicted(VVCLocalContext *lc, > const bool local_dual_tree, in > } > > for (int i = 0; i < predictor_size && nb_predicted < max_entries; > i++) { > - const int run = ff_vvc_palette_predictor_run(lc); > + int run; > + ret = ff_vvc_palette_predictor_run(lc, &run, predictor_size - i); > + if (ret < 0) > + return ret; > + > if (run == 1) > break; > > if (run > 1) > i += run - 1; > > - if (i >= predictor_size) > - return AVERROR_INVALIDDATA; > - > predictor_reused[i] = true; > for (int c = start; c < end; c++) > cu->plt[c].entries[nb_predicted] = lc->ep->pp[c].entries[i]; > @@ -1885,12 +1887,17 @@ static int palette_signaled(VVCLocalContext *lc, > const bool local_dual_tree, > const VVCSPS *sps = lc->fc->ps.sps; > CodingUnit *cu = lc->cu; > const int nb_predicted = cu->plt[start].size; > - const int nb_signaled = nb_predicted < max_entries ? > ff_vvc_num_signalled_palette_entries(lc) : 0; > - const int size = nb_predicted + nb_signaled; > const bool dual_tree_luma = local_dual_tree && cu->tree_type == > DUAL_TREE_LUMA; > + int nb_signaled, size; > - if (size > max_entries || nb_signaled < 0) > - return AVERROR_INVALIDDATA; > + if (nb_predicted < max_entries) { > + const int ret = ff_vvc_num_signalled_palette_entries(lc, > &nb_signaled, max_entries - nb_predicted); > + if (ret < 0) > + return ret; > + } else > + nb_signaled = 0; > + > + size = nb_predicted + nb_signaled; > > for (int c = start; c < end; c++) { > Palette *plt = cu->plt + c; > @@ -2052,10 +2059,11 @@ static int palette_subblock_data(VVCLocalContext > *lc, > if (!(xc & hs) && !(yc & vs)) { > const int v = PALETTE_INDEX(xc, yc); > if (v == esc) { > - const int coeff = ff_vvc_palette_escape_val(lc); > - if (coeff >= (1U << sps->bit_depth)) > - return AVERROR_INVALIDDATA; > - const int pixel = av_clip_intp2(RSHIFT(coeff * scale, > 6), sps->bit_depth); > + int coeff, pixel; > + const int ret = ff_vvc_palette_escape_val(lc, &coeff, > (1 << sps->bit_depth) - 1); > + if (ret < 0) > + return ret; > + pixel = av_clip_intp2(RSHIFT(coeff * scale, 6), > sps->bit_depth); > PALETTE_SET_PIXEL(xc, yc, pixel); > } else { > PALETTE_SET_PIXEL(xc, yc, plt->entries[v]); > @@ -2118,9 +2126,12 @@ static int hls_palette_coding(VVCLocalContext *lc, > const VVCTreeType tree_type) > palette_qp(lc, tree_type, escape_present); > > index[0] = 0; > - for (int i = 0; i <= (cu->cb_width * cu->cb_height - 1) >> 4; i++) > - palette_subblock_data(lc, max_index, i, transpose, > + for (int i = 0; i <= (cu->cb_width * cu->cb_height - 1) >> 4; i++) { > + ret = palette_subblock_data(lc, max_index, i, transpose, > run_type, index, &prev_run_pos, &adjust); > + if (ret < 0) > + return ret; > + } > > return 0; > } > -- > 2.47.0 > > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
prev parent reply other threads:[~2025-07-14 4:43 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2025-07-12 10:37 Frank Plowman 2025-07-14 4:43 ` Nuo Mi [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=CAFXK13cp6Bd2OP9QwYgWgtGcd4QuxSsqTxH5V3VWkdosU3KsbQ@mail.gmail.com \ --to=nuomi2021@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ --cc=post@frankplowman.com \ --cc=toqsxw@outlook.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git