You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-04 22:03:09 +02:00
lavc/vvc: Add max parameter to kth_order_egk_decode
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
eb52251c0a
, but I think this is the proper
fix as it also addresses issues with syntax elements besides
ff_vvc_num_signalled_palette_entries.
Signed-off-by: Frank Plowman <post@frankplowman.com>
This commit is contained in:
@ -929,7 +929,7 @@ static int truncated_binary_decode(VVCLocalContext *lc, const int c_max)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 9.3.3.5 k-th order Exp - Golomb binarization process
|
// 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 k, const int max)
|
||||||
{
|
{
|
||||||
int bit = 1;
|
int bit = 1;
|
||||||
int value = 0;
|
int value = 0;
|
||||||
@ -937,6 +937,8 @@ static int kth_order_egk_decode(CABACContext *c, int k)
|
|||||||
|
|
||||||
while (bit) {
|
while (bit) {
|
||||||
bit = get_cabac_bypass(c);
|
bit = get_cabac_bypass(c);
|
||||||
|
if (max - value < (bit << k))
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
value += bit << k++;
|
value += bit << k++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -946,6 +948,9 @@ static int kth_order_egk_decode(CABACContext *c, int k)
|
|||||||
value += symbol;
|
value += symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value > max)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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);
|
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, const int max)
|
||||||
{
|
{
|
||||||
return kth_order_egk_decode(&lc->ep->cc, 0);
|
return kth_order_egk_decode(&lc->ep->cc, 0, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ff_vvc_num_signalled_palette_entries(VVCLocalContext *lc)
|
int ff_vvc_num_signalled_palette_entries(VVCLocalContext *lc, const int max)
|
||||||
{
|
{
|
||||||
return kth_order_egk_decode(&lc->ep->cc, 0);
|
return kth_order_egk_decode(&lc->ep->cc, 0, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ff_vvc_new_palette_entries(VVCLocalContext *lc, const int bit_depth)
|
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);
|
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, const int max)
|
||||||
{
|
{
|
||||||
return kth_order_egk_decode(&lc->ep->cc, 5);
|
return kth_order_egk_decode(&lc->ep->cc, 5, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ff_vvc_general_merge_flag(VVCLocalContext *lc)
|
int ff_vvc_general_merge_flag(VVCLocalContext *lc)
|
||||||
|
@ -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_flag(VVCLocalContext *lc);
|
||||||
int ff_vvc_cclm_mode_idx(VVCLocalContext *lc);
|
int ff_vvc_cclm_mode_idx(VVCLocalContext *lc);
|
||||||
int ff_vvc_intra_chroma_pred_mode(VVCLocalContext *lc);
|
int ff_vvc_intra_chroma_pred_mode(VVCLocalContext *lc);
|
||||||
int ff_vvc_palette_predictor_run(VVCLocalContext *lc);
|
int ff_vvc_palette_predictor_run(VVCLocalContext *lc, const int max);
|
||||||
int ff_vvc_num_signalled_palette_entries(VVCLocalContext *lc);
|
int ff_vvc_num_signalled_palette_entries(VVCLocalContext *lc, const int max);
|
||||||
int ff_vvc_new_palette_entries(VVCLocalContext *lc, int bit_dpeth);
|
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_escape_val_present_flag(VVCLocalContext *lc);
|
||||||
bool ff_vvc_palette_transpose_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_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);
|
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_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, const int max);
|
||||||
|
|
||||||
//inter
|
//inter
|
||||||
int ff_vvc_general_merge_flag(VVCLocalContext *lc);
|
int ff_vvc_general_merge_flag(VVCLocalContext *lc);
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "libavutil/error.h"
|
||||||
#include "libavutil/refstruct.h"
|
#include "libavutil/refstruct.h"
|
||||||
|
|
||||||
#include "cabac.h"
|
#include "cabac.h"
|
||||||
@ -1857,16 +1858,16 @@ static int palette_predicted(VVCLocalContext *lc, const bool local_dual_tree, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < predictor_size && nb_predicted < max_entries; i++) {
|
for (int i = 0; i < predictor_size && nb_predicted < max_entries; i++) {
|
||||||
const int run = ff_vvc_palette_predictor_run(lc);
|
const int run = ff_vvc_palette_predictor_run(lc, predictor_size - i);
|
||||||
|
if (run < 0)
|
||||||
|
return run;
|
||||||
|
|
||||||
if (run == 1)
|
if (run == 1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (run > 1)
|
if (run > 1)
|
||||||
i += run - 1;
|
i += run - 1;
|
||||||
|
|
||||||
if (i >= predictor_size)
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
|
|
||||||
predictor_reused[i] = true;
|
predictor_reused[i] = true;
|
||||||
for (int c = start; c < end; c++)
|
for (int c = start; c < end; c++)
|
||||||
cu->plt[c].entries[nb_predicted] = lc->ep->pp[c].entries[i];
|
cu->plt[c].entries[nb_predicted] = lc->ep->pp[c].entries[i];
|
||||||
@ -1885,11 +1886,11 @@ static int palette_signaled(VVCLocalContext *lc, const bool local_dual_tree,
|
|||||||
const VVCSPS *sps = lc->fc->ps.sps;
|
const VVCSPS *sps = lc->fc->ps.sps;
|
||||||
CodingUnit *cu = lc->cu;
|
CodingUnit *cu = lc->cu;
|
||||||
const int nb_predicted = cu->plt[start].size;
|
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 nb_signaled = nb_predicted < max_entries ? ff_vvc_num_signalled_palette_entries(lc, max_entries - nb_predicted) : 0;
|
||||||
const int size = nb_predicted + nb_signaled;
|
const int size = nb_predicted + nb_signaled;
|
||||||
const bool dual_tree_luma = local_dual_tree && cu->tree_type == DUAL_TREE_LUMA;
|
const bool dual_tree_luma = local_dual_tree && cu->tree_type == DUAL_TREE_LUMA;
|
||||||
|
|
||||||
if (size > max_entries || nb_signaled < 0)
|
if (nb_signaled < 0)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
for (int c = start; c < end; c++) {
|
for (int c = start; c < end; c++) {
|
||||||
@ -2052,10 +2053,10 @@ static int palette_subblock_data(VVCLocalContext *lc,
|
|||||||
if (!(xc & hs) && !(yc & vs)) {
|
if (!(xc & hs) && !(yc & vs)) {
|
||||||
const int v = PALETTE_INDEX(xc, yc);
|
const int v = PALETTE_INDEX(xc, yc);
|
||||||
if (v == esc) {
|
if (v == esc) {
|
||||||
const int coeff = ff_vvc_palette_escape_val(lc);
|
const int coeff = ff_vvc_palette_escape_val(lc, (1 << sps->bit_depth) - 1);
|
||||||
if (coeff >= (1U << sps->bit_depth))
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
const int pixel = av_clip_intp2(RSHIFT(coeff * scale, 6), sps->bit_depth);
|
const int pixel = av_clip_intp2(RSHIFT(coeff * scale, 6), sps->bit_depth);
|
||||||
|
if (coeff < 0)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
PALETTE_SET_PIXEL(xc, yc, pixel);
|
PALETTE_SET_PIXEL(xc, yc, pixel);
|
||||||
} else {
|
} else {
|
||||||
PALETTE_SET_PIXEL(xc, yc, plt->entries[v]);
|
PALETTE_SET_PIXEL(xc, yc, plt->entries[v]);
|
||||||
|
Reference in New Issue
Block a user