collide: Fix potential use-after-free with transform cache disabled

Fixes #1733
This commit is contained in:
rdb 2025-07-28 15:10:31 +02:00
parent 41e4cf5d11
commit 6ef4699a48
7 changed files with 80 additions and 40 deletions

View File

@ -419,7 +419,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
const CollisionLine *line;
DCAST_INTO_R(line, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = line->get_origin() * wrt_mat;
LVector3 from_direction = line->get_direction() * wrt_mat;
@ -462,7 +463,8 @@ PT(CollisionEntry) CollisionBox::
test_intersection_from_ray(const CollisionEntry &entry) const {
const CollisionRay *ray;
DCAST_INTO_R(ray, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = ray->get_origin() * wrt_mat;
LVector3 from_direction = ray->get_direction() * wrt_mat;
@ -511,7 +513,8 @@ PT(CollisionEntry) CollisionBox::
test_intersection_from_segment(const CollisionEntry &entry) const {
const CollisionSegment *seg;
DCAST_INTO_R(seg, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = seg->get_point_a() * wrt_mat;
LPoint3 from_extent = seg->get_point_b() * wrt_mat;
@ -566,7 +569,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const {
const CollisionCapsule *capsule;
DCAST_INTO_R(capsule, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_a = capsule->get_point_a() * wrt_mat;
LPoint3 from_b = capsule->get_point_b() * wrt_mat;
@ -711,7 +715,8 @@ test_intersection_from_box(const CollisionEntry &entry) const {
const CollisionBox *box;
DCAST_INTO_R(box, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 diff = wrt_mat.xform_point_general(box->get_center()) - _center;
LVector3 from_extents = box->get_dimensions() * 0.5f;

View File

@ -226,7 +226,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
const CollisionLine *line;
DCAST_INTO_R(line, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = line->get_origin() * wrt_mat;
LVector3 from_direction = line->get_direction() * wrt_mat;
@ -274,7 +275,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
const CollisionRay *ray;
DCAST_INTO_R(ray, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = ray->get_origin() * wrt_mat;
LVector3 from_direction = ray->get_direction() * wrt_mat;
@ -335,7 +337,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
const CollisionSegment *segment;
DCAST_INTO_R(segment, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_a = segment->get_point_a() * wrt_mat;
LPoint3 from_b = segment->get_point_b() * wrt_mat;
@ -402,7 +405,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const {
LPoint3 into_a = _a;
LVector3 into_direction = _b - into_a;
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_a = capsule->get_point_a() * wrt_mat;
LPoint3 from_b = capsule->get_point_b() * wrt_mat;
@ -463,7 +467,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const {
const CollisionParabola *parabola;
DCAST_INTO_R(parabola, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
// Convert the parabola into local coordinate space.
LParabola local_p(parabola->get_parabola());

View File

@ -130,7 +130,9 @@ PT(CollisionEntry) CollisionFloorMesh::
test_intersection_from_ray(const CollisionEntry &entry) const {
const CollisionRay *ray;
DCAST_INTO_R(ray, entry.get_from(), nullptr);
LPoint3 from_origin = ray->get_origin() * entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
LPoint3 from_origin = ray->get_origin() * wrt_space->get_mat();
double fx = from_origin[0];
double fy = from_origin[1];
@ -195,7 +197,9 @@ PT(CollisionEntry) CollisionFloorMesh::
test_intersection_from_sphere(const CollisionEntry &entry) const {
const CollisionSphere *sphere;
DCAST_INTO_R(sphere, entry.get_from(), nullptr);
LPoint3 from_origin = sphere->get_center() * entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
LPoint3 from_origin = sphere->get_center() * wrt_space->get_mat();
double fx = from_origin[0];
double fy = from_origin[1];

View File

@ -94,7 +94,8 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
const CollisionSphere *sphere;
DCAST_INTO_R(sphere, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_center = sphere->get_center() * wrt_mat;
LVector3 from_radius_v =
@ -146,7 +147,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
const CollisionLine *line;
DCAST_INTO_R(line, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = line->get_origin() * wrt_mat;
LVector3 from_direction = line->get_direction() * wrt_mat;
@ -187,7 +189,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
const CollisionRay *ray;
DCAST_INTO_R(ray, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = ray->get_origin() * wrt_mat;
LVector3 from_direction = ray->get_direction() * wrt_mat;
@ -230,7 +233,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
const CollisionSegment *segment;
DCAST_INTO_R(segment, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_a = segment->get_point_a() * wrt_mat;
LPoint3 from_b = segment->get_point_b() * wrt_mat;
@ -296,7 +300,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const {
const CollisionCapsule *capsule;
DCAST_INTO_R(capsule, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_a = capsule->get_point_a() * wrt_mat;
LPoint3 from_b = capsule->get_point_b() * wrt_mat;
@ -351,7 +356,8 @@ test_intersection_from_box(const CollisionEntry &entry) const {
const CollisionBox *box;
DCAST_INTO_R(box, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 center = get_center();
PN_stdfloat radius_sq = get_radius();

View File

@ -109,7 +109,8 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
const CollisionSphere *sphere;
DCAST_INTO_R(sphere, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_center = sphere->get_center() * wrt_mat;
LVector3 from_radius_v =
@ -148,7 +149,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
const CollisionLine *line;
DCAST_INTO_R(line, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = line->get_origin() * wrt_mat;
LVector3 from_direction = line->get_direction() * wrt_mat;
@ -193,7 +195,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
const CollisionRay *ray;
DCAST_INTO_R(ray, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = ray->get_origin() * wrt_mat;
LVector3 from_direction = ray->get_direction() * wrt_mat;
@ -245,7 +248,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
const CollisionSegment *segment;
DCAST_INTO_R(segment, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_a = segment->get_point_a() * wrt_mat;
LPoint3 from_b = segment->get_point_b() * wrt_mat;
@ -302,7 +306,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const {
const CollisionCapsule *capsule;
DCAST_INTO_R(capsule, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_a = capsule->get_point_a() * wrt_mat;
LPoint3 from_b = capsule->get_point_b() * wrt_mat;
@ -373,7 +378,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const {
const CollisionParabola *parabola;
DCAST_INTO_R(parabola, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
// Convert the parabola into local coordinate space.
LParabola local_p(parabola->get_parabola());
@ -439,7 +445,8 @@ test_intersection_from_box(const CollisionEntry &entry) const {
const CollisionBox *box;
DCAST_INTO_R(box, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_center = box->get_center() * wrt_mat;
LVector3 from_extents = box->get_dimensions() * 0.5f;

View File

@ -552,7 +552,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
const CollisionLine *line;
DCAST_INTO_R(line, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = line->get_origin() * wrt_mat;
LVector3 from_direction = line->get_direction() * wrt_mat;
@ -620,7 +621,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
const CollisionRay *ray;
DCAST_INTO_R(ray, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = ray->get_origin() * wrt_mat;
LVector3 from_direction = ray->get_direction() * wrt_mat;
@ -693,7 +695,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
const CollisionSegment *segment;
DCAST_INTO_R(segment, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_a = segment->get_point_a() * wrt_mat;
LPoint3 from_b = segment->get_point_b() * wrt_mat;
@ -763,7 +766,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const {
const CollisionCapsule *capsule;
DCAST_INTO_R(capsule, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_a = capsule->get_point_a() * wrt_mat;
LPoint3 from_b = capsule->get_point_b() * wrt_mat;
@ -962,7 +966,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const {
const CollisionParabola *parabola;
DCAST_INTO_R(parabola, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
// Convert the parabola into local coordinate space.
LParabola local_p(parabola->get_parabola());
@ -1049,7 +1054,8 @@ test_intersection_from_box(const CollisionEntry &entry) const {
// To make things easier, transform the box into the coordinate space of the
// plane.
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LMatrix4 plane_mat = wrt_mat * _to_2d_mat;
LPoint3 from_center = box->get_center() * plane_mat;

View File

@ -236,7 +236,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
const CollisionLine *line;
DCAST_INTO_R(line, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = line->get_origin() * wrt_mat;
LVector3 from_direction = line->get_direction() * wrt_mat;
@ -278,10 +279,11 @@ test_intersection_from_box(const CollisionEntry &entry) const {
// Instead of transforming the box into the sphere's coordinate space, we do
// it the other way around. It's easier that way.
const LMatrix4 &wrt_mat = entry.get_inv_wrt_mat();
CPT(TransformState) inv_wrt_space = entry.get_inv_wrt_space();
const LMatrix4 &inv_wrt_mat = inv_wrt_space->get_mat();
LPoint3 center = wrt_mat.xform_point(_center);
PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, _radius)).length_squared();
LPoint3 center = inv_wrt_mat.xform_point(_center);
PN_stdfloat radius_sq = inv_wrt_mat.xform_vec(LVector3(0, 0, _radius)).length_squared();
LPoint3 box_min = box->get_min();
LPoint3 box_max = box->get_max();
@ -330,7 +332,8 @@ test_intersection_from_box(const CollisionEntry &entry) const {
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
// To get the interior point, clamp the sphere center to the AABB.
LPoint3 interior = entry.get_wrt_mat().xform_point(center.fmax(box_min).fmin(box_max));
CPT(TransformState) wrt_space = entry.get_wrt_space();
LPoint3 interior = wrt_space->get_mat().xform_point(center.fmax(box_min).fmin(box_max));
new_entry->set_interior_point(interior);
// Now extrapolate the surface point and normal from that.
@ -352,7 +355,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
const CollisionRay *ray;
DCAST_INTO_R(ray, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_origin = ray->get_origin() * wrt_mat;
LVector3 from_direction = ray->get_direction() * wrt_mat;
@ -399,7 +403,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
const CollisionSegment *segment;
DCAST_INTO_R(segment, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_a = segment->get_point_a() * wrt_mat;
LPoint3 from_b = segment->get_point_b() * wrt_mat;
@ -448,7 +453,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const {
const CollisionCapsule *capsule;
DCAST_INTO_R(capsule, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
LPoint3 from_a = capsule->get_point_a() * wrt_mat;
LPoint3 from_b = capsule->get_point_b() * wrt_mat;
@ -504,7 +510,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const {
const CollisionParabola *parabola;
DCAST_INTO_R(parabola, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat();
CPT(TransformState) wrt_space = entry.get_wrt_space();
const LMatrix4 &wrt_mat = wrt_space->get_mat();
// Convert the parabola into local coordinate space.
LParabola local_p(parabola->get_parabola());