Skip to content

Commit 1f5525e

Browse files
authored
Fix virtual POF crashes (#7327)
* Ensure model data isn't deleted twice * shared_ptr-ify model data * fix virtual pof filename issue * Fix tests * remove redundant memsets * Clang Tid
1 parent 7361417 commit 1f5525e

12 files changed

Lines changed: 166 additions & 277 deletions

File tree

code/ai/aicode.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13705,7 +13705,7 @@ int ai_acquire_emerge_path(object *pl_objp, int parent_objnum, int allowed_path_
1370513705
ship_info* parent_sip = &Ship_info[parent_shipp->ship_info_index];
1370613706

1370713707
polymodel *pm = model_get( parent_sip->model_num );
13708-
ship_bay *bay = pm->ship_bay;
13708+
const auto& bay = pm->ship_bay;
1370913709

1371013710
if ( bay == nullptr ) {
1371113711
Warning(LOCATION, "Ship %s was set to arrive from fighter bay on object %s, but no fighter bay exists on that ships' model (%s).\n", shipp->ship_name, parent_shipp->ship_name, pm->filename);
@@ -13920,9 +13920,8 @@ int ai_find_closest_depart_path(ai_info *aip, polymodel *pm, int allowed_path_ma
1392013920
float dist, min_dist, min_free_dist;
1392113921
vec3d *source;
1392213922
model_path *mp;
13923-
ship_bay *bay;
1392413923

13925-
bay = pm->ship_bay;
13924+
const auto& bay = pm->ship_bay;
1392613925

1392713926
best_free_path = best_path = -1;
1392813927
min_free_dist = min_dist = 1e20f;
@@ -13999,9 +13998,9 @@ int ai_acquire_depart_path(object *pl_objp, int parent_objnum, int allowed_path_
1399913998

1400013999
object *parent_objp = &Objects[parent_objnum];
1400114000
polymodel *pm = model_get(Ship_info[Ships[parent_objp->instance].ship_info_index].model_num );
14002-
ship_bay *bay = pm->ship_bay;
14001+
const auto& bay = pm->ship_bay;
1400314002

14004-
if ( bay == NULL )
14003+
if ( bay == nullptr )
1400514004
return -1;
1400614005
if ( bay->num_paths <= 0 )
1400714006
return -1;
@@ -14092,11 +14091,10 @@ void ai_bay_depart()
1409214091

1409314092
// Volition bay code
1409414093
polymodel *pm;
14095-
ship_bay *bay;
1409614094

1409714095
pm = model_get(Ship_info[Ships[Objects[aip->goal_objnum].instance].ship_info_index].model_num);
14098-
bay = pm->ship_bay;
14099-
if ( bay != NULL ) {
14096+
const auto& bay = pm->ship_bay;
14097+
if ( bay != nullptr ) {
1410014098
bay->depart_flags &= ~(1<<aip->submode_parm0);
1410114099
}
1410214100

code/globalincs/type_traits.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,30 @@ struct is_dereferenceable_pointer<T, typename std::enable_if_t<std::is_pointer_v
4646
template<typename T>
4747
inline constexpr bool is_dereferenceable_pointer_v = is_dereferenceable_pointer<T>::value;
4848

49+
template<typename T, typename Enable = void>
50+
struct is_smart_pointer : std::false_type {};
51+
52+
template<typename T>
53+
struct is_smart_pointer<T, std::enable_if_t<std::is_same_v<std::remove_cv_t<T>, std::shared_ptr<typename T::element_type>>>> : std::true_type {};
54+
55+
template<typename T>
56+
struct is_smart_pointer<T, std::enable_if_t<std::is_same_v<std::remove_cv_t<T>, std::shared_ptr<typename T::element_type[]>>>> : std::true_type {};
57+
58+
template<typename T>
59+
struct is_smart_pointer<T, std::enable_if_t<std::is_same_v<std::remove_cv_t<T>, std::unique_ptr<typename T::element_type>>>> : std::true_type {};
60+
61+
template<typename T>
62+
struct is_smart_pointer<T, std::enable_if_t<std::is_same_v<std::remove_cv_t<T>, std::unique_ptr<typename T::element_type[]>>>> : std::true_type {};
63+
64+
template<typename T>
65+
struct is_smart_pointer<T, std::enable_if_t<std::is_same_v<std::remove_cv_t<T>, std::weak_ptr<typename T::element_type>>>> : std::true_type {};
66+
67+
template<typename T>
68+
struct is_smart_pointer<T, std::enable_if_t<std::is_same_v<std::remove_cv_t<T>, std::weak_ptr<typename T::element_type[]>>>> : std::true_type {};
69+
70+
template<typename T>
71+
inline constexpr bool is_smart_pointer_v = is_smart_pointer<T>::value;
72+
4973
template<class T, template<class...> class U>
5074
inline constexpr bool is_instance_of_v = std::false_type{};
5175

code/graphics/2d.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -615,9 +615,8 @@ class vertex_buffer
615615
};
616616

617617
struct indexed_vertex_source {
618-
void* Vertex_list = nullptr;
619-
void* Index_list = nullptr;
620-
618+
std::shared_ptr<uint8_t[]> Vertex_list = nullptr;
619+
std::shared_ptr<uint8_t[]> Index_list = nullptr;
621620
gr_buffer_handle Vbuffer_handle;
622621
size_t Vertex_offset = 0;
623622
size_t Base_vertex_offset = 0;

code/model/model.h

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ class bsp_info
453453
matrix frame_of_reference; // used to be called 'orientation' - this is just used for setting the rotation axis and the animation angles
454454

455455
int bsp_data_size;
456-
ubyte *bsp_data;
456+
std::shared_ptr<ubyte[]> bsp_data;
457457

458458
int collision_tree_index;
459459

@@ -485,7 +485,7 @@ class bsp_info
485485
vertex_buffer buffer;
486486
vertex_buffer trans_buffer;
487487

488-
vertex *outline_buffer;
488+
std::shared_ptr<vertex[]> outline_buffer;
489489
uint n_verts_outline;
490490

491491
vec3d render_box_min;
@@ -508,7 +508,7 @@ class bsp_info
508508
typedef struct mp_vert {
509509
vec3d pos; // xyz coordinates of vertex in object's frame of reference
510510
int nturrets; // number of turrets guarding this vertex
511-
int *turret_ids; // array of indices into ship_subsys linked list (can't index using [] though)
511+
std::shared_ptr<int[]> turret_ids; // array of indices into ship_subsys linked list (can't index using [] though)
512512
float radius; // How far the closest obstruction is from this vertex
513513
} mp_vert;
514514

@@ -517,7 +517,7 @@ typedef struct model_path {
517517
char parent_name[MAX_NAME_LEN]; // parent name of submodel that path is linked to in POF
518518
int parent_submodel;
519519
int nverts;
520-
mp_vert *verts;
520+
std::shared_ptr<mp_vert[]> verts;
521521
int goal; // Which of the verts is the one closest to the goal of this path
522522
int type; // What this path takes you to... See MP_TYPE_??? defines above for details
523523
int value; // This depends on the type.
@@ -567,7 +567,7 @@ struct glow_point{
567567

568568
typedef struct thruster_bank {
569569
int num_points;
570-
glow_point *points;
570+
std::shared_ptr<glow_point[]> points;
571571

572572
// Engine wash info
573573
struct engine_wash_info *wash_info_pointer; // index into Engine_wash_info
@@ -590,7 +590,7 @@ typedef struct glow_point_bank { // glow bank structure -Bobboau
590590
int submodel_parent;
591591
int LOD;
592592
int num_points;
593-
glow_point *points;
593+
std::shared_ptr<glow_point[]> points;
594594
int glow_bitmap;
595595
int glow_neb_bitmap;
596596
} glow_point_bank;
@@ -650,7 +650,7 @@ typedef struct dock_bay {
650650
int num_slots;
651651
int type_flags; // indicates what this docking bay can be used for (i.e. cargo/rearm, etc)
652652
int num_spline_paths; // number of spline paths which lead to this docking bay
653-
int *splines; // array of indices into the Spline_path array
653+
std::shared_ptr<int[]> splines; // array of indices into the Spline_path array
654654
int parent_submodel; // if this dockpoint should be relative to a submodel instead of the main model
655655
char name[MAX_NAME_LEN]; // name of this docking location
656656
vec3d pnt[MAX_DOCK_SLOTS];
@@ -692,14 +692,14 @@ typedef struct shield_vertex {
692692
struct shield_info {
693693
int nverts;
694694
int ntris;
695-
shield_vertex *verts;
696-
shield_tri *tris;
695+
std::shared_ptr<shield_vertex[]> verts;
696+
std::shared_ptr<shield_tri[]> tris;
697697

698-
gr_buffer_handle buffer_id;
698+
std::shared_ptr<gr_buffer_handle> buffer_id;
699699
int buffer_n_verts;
700700
vertex_layout layout;
701701

702-
shield_info() : nverts(0), ntris(0), verts(NULL), tris(NULL), buffer_id(-1), buffer_n_verts(0), layout() { }
702+
shield_info() : nverts(0), ntris(0), verts(nullptr), tris(nullptr), buffer_id(std::make_shared<gr_buffer_handle>(gr_buffer_handle::invalid())), buffer_n_verts(0) { }
703703
};
704704

705705
#define BSP_LIGHT_TYPE_WEAPON 1
@@ -852,7 +852,7 @@ class polymodel
852852
vec3d bounding_box[8];
853853

854854
int num_lights; // how many lights there are
855-
bsp_light * lights; // array of light info
855+
std::shared_ptr<bsp_light[]> lights; // array of light info
856856

857857
int n_view_positions; // number of viewing positions available on this ship
858858
eye view_positions[MAX_EYES]; //viewing positions. Default to {0,0,0}. in location 0
@@ -866,35 +866,35 @@ class polymodel
866866
int n_textures;
867867
texture_map maps[MAX_MODEL_TEXTURES];
868868

869-
bsp_info *submodel; // an array of size n_models of submodel info.
869+
std::shared_ptr<bsp_info[]> submodel; // an array of size n_models of submodel info.
870870

871871
// linked lists for special polygon types on this model. Most ships I think will have most
872872
// of these. (most ships however, probably won't have approach points).
873873
int n_guns; // number of primary weapon banks (not counting turrets)
874874
int n_missiles; // number of secondary weapon banks (not counting turrets)
875875
int n_docks; // number of docking points
876876
int n_thrusters; // number of thrusters on this ship.
877-
w_bank *gun_banks; // array of gun banks
878-
w_bank *missile_banks; // array of missile banks
879-
dock_bay *docking_bays; // array of docking point pairs
880-
thruster_bank *thrusters; // array of thruster objects -- likely to change in the future
881-
ship_bay_t *ship_bay; // contains path indexes for ship bay approach/depart paths
877+
std::shared_ptr<w_bank[]> gun_banks; // array of gun banks
878+
std::shared_ptr<w_bank[]> missile_banks; // array of missile banks
879+
std::shared_ptr<dock_bay[]> docking_bays; // array of docking point pairs
880+
std::shared_ptr<thruster_bank[]> thrusters; // array of thruster objects -- likely to change in the future
881+
std::shared_ptr<ship_bay_t> ship_bay; // contains path indexes for ship bay approach/depart paths
882882

883883
shield_info shield; // new shield information
884-
ubyte *shield_collision_tree;
884+
std::shared_ptr<ubyte[]> shield_collision_tree;
885885
int sldc_size;
886886
SCP_vector<vec3d> shield_points;
887887

888888
int n_paths;
889-
model_path *paths;
889+
std::shared_ptr<model_path[]> paths;
890890

891891
// physics info
892892
float mass;
893893
vec3d center_of_mass;
894894
matrix moment_of_inertia;
895895

896896
int num_xc; // number of cross sections
897-
cross_section* xc; // pointer to array of cross sections (used in big ship explosions)
897+
std::shared_ptr<cross_section[]> xc; // pointer to array of cross sections (used in big ship explosions)
898898

899899
int num_split_plane; // number of split planes
900900
float split_plane[MAX_SPLIT_PLANE]; // actual split plane z coords (for big ship explosions)
@@ -905,13 +905,13 @@ class polymodel
905905
#ifndef NDEBUG
906906
int ram_used; // How much RAM this model uses
907907
int debug_info_size;
908-
char *debug_info;
908+
std::shared_ptr<char[]> debug_info;
909909
#endif
910910

911911
int used_this_mission; // used for page-in system, how many times this model has been loaded per mission - taylor
912912

913913
int n_glow_point_banks; // number of glow points on this ship. -Bobboau
914-
glow_point_bank *glow_point_banks; // array of glow objects -Bobboau
914+
std::shared_ptr<glow_point_bank[]> glow_point_banks; // array of glow objects -Bobboau
915915

916916
indexed_vertex_source vert_source;
917917

code/model/modelcollide.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ bool mc_shield_check_common(shield_tri *tri)
859859
// also finds the uv's where the ray hit.
860860
if ( fvi_point_face(&hitpoint, 3, points, &tri->norm, NULL,NULL,NULL ) ) {
861861
Mc->hit_dist = dist;
862-
Mc->shield_hit_tri = (int)(tri - Mc_pm->shield.tris);
862+
Mc->shield_hit_tri = (int)(tri - Mc_pm->shield.tris.get());
863863
Mc->hit_point = hitpoint;
864864
Mc->hit_normal = tri->norm;
865865
Mc->hit_submodel = -1;
@@ -877,7 +877,7 @@ bool mc_shield_check_common(shield_tri *tri)
877877
// same behavior whether face or edge
878878
// normal, edge_hit, hit_point all updated thru sphereline_face
879879
sphere_check_closest_shield_dist = Mc->hit_dist;
880-
Mc->shield_hit_tri = (int)(tri - Mc_pm->shield.tris);
880+
Mc->shield_hit_tri = (int)(tri - Mc_pm->shield.tris.get());
881881
Mc->hit_submodel = -1;
882882
Mc->num_hits++;
883883
return true; // We hit, so we're done
@@ -893,22 +893,22 @@ bool mc_check_sldc(int offset)
893893
if (offset > Mc_pm->sldc_size - 5) //no way is this big enough
894894
return false;
895895

896-
int* type_p = (int*)(Mc_pm->shield_collision_tree + offset);
896+
int* type_p = (int*)(Mc_pm->shield_collision_tree.get() + offset);
897897

898898
// not used
899899
//int *size_p = (int *)(Mc_pm->shield_collision_tree+offset+4);
900900
// split and polygons
901-
auto* minbox_p = (vec3d*)(Mc_pm->shield_collision_tree + offset + 8);
902-
auto* maxbox_p = (vec3d*)(Mc_pm->shield_collision_tree + offset + 20);
901+
auto* minbox_p = (vec3d*)(Mc_pm->shield_collision_tree.get() + offset + 8);
902+
auto* maxbox_p = (vec3d*)(Mc_pm->shield_collision_tree.get() + offset + 20);
903903

904904
// split
905-
auto* front_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree + offset + 32);
906-
auto* back_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree + offset + 36);
905+
auto* front_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree.get() + offset + 32);
906+
auto* back_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree.get() + offset + 36);
907907

908908
// polygons
909-
auto* num_polygons_p = (unsigned int*)(Mc_pm->shield_collision_tree + offset + 32);
909+
auto* num_polygons_p = (unsigned int*)(Mc_pm->shield_collision_tree.get() + offset + 32);
910910

911-
auto* shld_polys = (unsigned int*)(Mc_pm->shield_collision_tree + offset + 36);
911+
auto* shld_polys = (unsigned int*)(Mc_pm->shield_collision_tree.get() + offset + 36);
912912

913913

914914

0 commit comments

Comments
 (0)