Fix memory being written after the end of the heap buffer

`target_snap_points` could have size 0, but even so
`memset(snap_data->target_snap_points, 0, sizeof(int));` was always
called.

Avoid writing to unallocated memory. And use C++ arrays.
This commit is contained in:
Germano Cavalcante
2023-11-13 19:30:52 -03:00
parent 9dcf73c715
commit f74ed4d45d

View File

@@ -32,10 +32,12 @@
#include "transform_snap.hh"
struct TransSeqSnapData {
int *source_snap_points;
int *target_snap_points;
int source_snap_point_count;
int target_snap_point_count;
blender::Array<int> source_snap_points;
blender::Array<int> target_snap_points;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("TransSeqSnapData")
#endif
};
/* -------------------------------------------------------------------- */
@@ -47,25 +49,21 @@ static int seq_get_snap_source_points_len(blender::Span<Sequence *> snap_sources
return snap_sources.size() * 2;
}
static void seq_snap_source_points_alloc(TransSeqSnapData *snap_data,
blender::Span<Sequence *> snap_sources)
{
const size_t point_count = seq_get_snap_source_points_len(snap_sources);
snap_data->source_snap_points = static_cast<int *>(
MEM_callocN(sizeof(int) * point_count, __func__));
memset(snap_data->source_snap_points, 0, sizeof(int));
snap_data->source_snap_point_count = point_count;
}
static int cmp_fn(const void *a, const void *b)
{
return (*(int *)a - *(int *)b);
}
static void seq_snap_source_points_build(const Scene *scene,
static bool seq_snap_source_points_build(const Scene *scene,
TransSeqSnapData *snap_data,
blender::Span<Sequence *> snap_sources)
{
const size_t point_count_source = seq_get_snap_source_points_len(snap_sources);
if (point_count_source == 0) {
return false;
}
snap_data->source_snap_points.reinitialize(point_count_source);
int i = 0;
for (Sequence *seq : snap_sources) {
int left = 0, right = 0;
@@ -83,10 +81,15 @@ static void seq_snap_source_points_build(const Scene *scene,
snap_data->source_snap_points[i] = left;
snap_data->source_snap_points[i + 1] = right;
i += 2;
BLI_assert(i <= snap_data->source_snap_point_count);
BLI_assert(i <= snap_data->source_snap_points.size());
}
qsort(snap_data->source_snap_points, snap_data->source_snap_point_count, sizeof(int), cmp_fn);
qsort(snap_data->source_snap_points.data(),
snap_data->source_snap_points.size(),
sizeof(int),
cmp_fn);
return true;
}
/** \} */
@@ -169,22 +172,17 @@ static int seq_get_snap_target_points_count(short snap_mode,
return count;
}
static void seq_snap_target_points_alloc(short snap_mode,
TransSeqSnapData *snap_data,
blender::Span<Sequence *> snap_targets)
{
const size_t point_count = seq_get_snap_target_points_count(snap_mode, snap_targets);
snap_data->target_snap_points = static_cast<int *>(
MEM_callocN(sizeof(int) * point_count, __func__));
memset(snap_data->target_snap_points, 0, sizeof(int));
snap_data->target_snap_point_count = point_count;
}
static void seq_snap_target_points_build(Scene *scene,
static bool seq_snap_target_points_build(Scene *scene,
short snap_mode,
TransSeqSnapData *snap_data,
blender::Span<Sequence *> snap_targets)
{
const size_t point_count_target = seq_get_snap_target_points_count(snap_mode, snap_targets);
if (point_count_target == 0) {
return false;
}
snap_data->target_snap_points.reinitialize(point_count_target);
int i = 0;
if (snap_mode & SEQ_SNAP_TO_CURRENT_FRAME) {
@@ -220,8 +218,12 @@ static void seq_snap_target_points_build(Scene *scene,
i += 2;
}
}
BLI_assert(i <= snap_data->target_snap_point_count);
qsort(snap_data->target_snap_points, snap_data->target_snap_point_count, sizeof(int), cmp_fn);
BLI_assert(i <= snap_data->target_snap_points.size());
qsort(snap_data->target_snap_points.data(),
snap_data->target_snap_points.size(),
sizeof(int),
cmp_fn);
return true;
}
/** \} */
@@ -246,35 +248,29 @@ TransSeqSnapData *transform_snap_sequencer_data_alloc(const TransInfo *t)
return nullptr;
}
TransSeqSnapData *snap_data = MEM_new<TransSeqSnapData>(__func__);
Scene *scene = t->scene;
TransSeqSnapData *snap_data = static_cast<TransSeqSnapData *>(
MEM_callocN(sizeof(TransSeqSnapData), __func__));
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
short snap_mode = t->tsnap.mode;
blender::VectorSet<Sequence *> snap_sources = SEQ_query_selected_strips(seqbase);
blender::VectorSet<Sequence *> snap_targets = query_snap_targets(scene, snap_sources, true);
if (snap_sources.is_empty()) {
MEM_freeN(snap_data);
/* Build arrays of snap points. */
if (!seq_snap_source_points_build(scene, snap_data, snap_sources) ||
!seq_snap_target_points_build(scene, snap_mode, snap_data, snap_targets))
{
MEM_delete(snap_data);
return nullptr;
}
/* Build arrays of snap points. */
seq_snap_source_points_alloc(snap_data, snap_sources);
seq_snap_source_points_build(scene, snap_data, snap_sources);
short snap_mode = t->tsnap.mode;
seq_snap_target_points_alloc(snap_mode, snap_data, snap_targets);
seq_snap_target_points_build(scene, snap_mode, snap_data, snap_targets);
return snap_data;
}
void transform_snap_sequencer_data_free(TransSeqSnapData *data)
{
MEM_freeN(data->source_snap_points);
MEM_freeN(data->target_snap_points);
MEM_freeN(data);
MEM_delete(data);
}
bool transform_snap_sequencer_calc(TransInfo *t)
@@ -291,11 +287,9 @@ bool transform_snap_sequencer_calc(TransInfo *t)
int best_dist = MAXFRAME, best_target_frame = 0, best_source_frame = 0;
for (int i = 0; i < snap_data->source_snap_point_count; i++) {
int snap_source_frame = snap_data->source_snap_points[i] + round_fl_to_int(t->values[0]);
for (int j = 0; j < snap_data->target_snap_point_count; j++) {
int snap_target_frame = snap_data->target_snap_points[j];
for (int frame_src : snap_data->source_snap_points) {
int snap_source_frame = frame_src + round_fl_to_int(t->values[0]);
for (int snap_target_frame : snap_data->target_snap_points) {
int dist = abs(snap_target_frame - snap_source_frame);
if (dist > best_dist) {
continue;
@@ -324,21 +318,19 @@ void transform_snap_sequencer_apply_translate(TransInfo *t, float *vec)
static int transform_snap_sequencer_to_closest_strip_ex(TransInfo *t, int frame_1, int frame_2)
{
Scene *scene = t->scene;
TransSeqSnapData *snap_data = static_cast<TransSeqSnapData *>(
MEM_callocN(sizeof(TransSeqSnapData), __func__));
TransSeqSnapData *snap_data = MEM_new<TransSeqSnapData>(__func__);
blender::VectorSet<Sequence *> empty_col;
blender::VectorSet<Sequence *> snap_targets = query_snap_targets(scene, empty_col, false);
snap_data->source_snap_points = static_cast<int *>(MEM_callocN(sizeof(int) * 2, __func__));
snap_data->source_snap_point_count = 2;
BLI_assert(frame_1 <= frame_2);
snap_data->source_snap_points.reinitialize(2);
snap_data->source_snap_points[0] = frame_1;
snap_data->source_snap_points[1] = frame_2;
short snap_mode = t->tsnap.mode;
/* Build arrays of snap points. */
seq_snap_target_points_alloc(snap_mode, snap_data, snap_targets);
seq_snap_target_points_build(scene, snap_mode, snap_data, snap_targets);
t->tsnap.seq_context = snap_data;