From f6631ce742a16b639c20cecb2e5ed85d43b93748 Mon Sep 17 00:00:00 2001 From: Kp Date: Sat, 21 Jun 2014 23:55:24 +0000 Subject: [PATCH] Unpack various structures Prohibit conversion to void* to avoid accidental use with memcpy --- common/include/gr.h | 7 +++--- common/include/pack.h | 46 +++++++++++++++++++++++++++++++++++++ common/main/aistruct.h | 7 +++--- common/main/cntrlcen.h | 3 ++- common/main/config.h | 5 ++-- common/main/effects.h | 3 ++- common/main/fuelcen.h | 7 +++--- common/main/net_udp.h | 8 +++---- common/main/object.h | 18 +++++++-------- common/main/player.h | 3 ++- common/main/powerup.h | 2 +- common/main/switch.h | 3 ++- common/main/vclip.h | 2 +- common/main/wall.h | 14 ++++++----- d1x-rebirth/main/bmread.cpp | 10 ++++++-- 15 files changed, 100 insertions(+), 38 deletions(-) create mode 100644 common/include/pack.h diff --git a/common/include/gr.h b/common/include/gr.h index 450a07516..26883c6e4 100644 --- a/common/include/gr.h +++ b/common/include/gr.h @@ -31,6 +31,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "palette.h" #include "dxxsconf.h" #include "fmtcheck.h" +#include "pack.h" #ifdef DXX_BUILD_DESCENT_I extern int HiresGFXAvailable; @@ -120,7 +121,7 @@ struct grs_bitmap }; //font structure -struct grs_font +struct grs_font : public prohibit_void_ptr { short ft_w; // Width in pixels short ft_h; // Height in pixels @@ -142,7 +143,7 @@ struct grs_font #define GRS_FONT_SIZE 28 // how much space it takes up on disk -struct grs_canvas +struct grs_canvas : public prohibit_void_ptr { grs_bitmap cv_bitmap; // the bitmap for this canvas short cv_color; // current color @@ -154,7 +155,7 @@ struct grs_canvas short cv_font_bg_color; // current font background color (-1==Invisible) }; -struct grs_screen +struct grs_screen : public prohibit_void_ptr { // This is a video screen grs_canvas sc_canvas; // Represents the entire screen u_int32_t sc_mode; // Video mode number diff --git a/common/include/pack.h b/common/include/pack.h new file mode 100644 index 000000000..47c5efb89 --- /dev/null +++ b/common/include/pack.h @@ -0,0 +1,46 @@ +#pragma once + +#include "dxxsconf.h" +#include "compiler-type_traits.h" + +template +class exact_type +{ + T *p; +public: + // Conversion to void* variants is prohibited + operator void *() const DXX_CXX11_EXPLICIT_DELETE; + operator volatile void *() const DXX_CXX11_EXPLICIT_DELETE; + operator const void *() const DXX_CXX11_EXPLICIT_DELETE; + operator const volatile void *() const DXX_CXX11_EXPLICIT_DELETE; + bool operator<(exact_type) const DXX_CXX11_EXPLICIT_DELETE; + bool operator<=(exact_type) const DXX_CXX11_EXPLICIT_DELETE; + bool operator>(exact_type) const DXX_CXX11_EXPLICIT_DELETE; + bool operator>=(exact_type) const DXX_CXX11_EXPLICIT_DELETE; + exact_type(T *t) : p(t) {} + // Conversion to the exact type is permitted + operator T *() const { return p; } + bool operator==(exact_type rhs) const { return p == rhs.p; } + bool operator!=(exact_type rhs) const { return p != rhs.p; } +}; + +template +class prohibit_void_ptr +{ +public: + // Return a proxy when the address is taken + exact_type operator&() { return static_cast(this); } + exact_type operator&() const { return static_cast(this); } +}; + +struct allow_void_ptr {}; + +template +struct has_prohibit_void_ptr : tt::is_base_of, T> {}; + +template +struct has_prohibit_void_ptr {}; + +template +struct inherit_void_ptr_handler : public + tt::conditional::value, prohibit_void_ptr, allow_void_ptr> {}; diff --git a/common/main/aistruct.h b/common/main/aistruct.h index cf9501104..4cf1c9d84 100644 --- a/common/main/aistruct.h +++ b/common/main/aistruct.h @@ -32,6 +32,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "polyobj.h" #ifdef __cplusplus +#include "pack.h" #define GREEN_GUY 1 @@ -165,7 +166,7 @@ enum player_awareness_type_t // This is the stuff that is permanent for an AI object. #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) // Rather temporal AI stuff. -struct ai_local +struct ai_local : public prohibit_void_ptr { // These used to be bytes, changed to ints so I could set watchpoints on them. #if defined(DXX_BUILD_DESCENT_I) @@ -202,7 +203,7 @@ struct ai_local sbyte achieved_state[MAX_SUBMODELS]; // Last achieved state }; -struct ai_static +struct ai_static : public prohibit_void_ptr { ubyte behavior; // sbyte flags[MAX_AI_FLAGS]; // various flags, meaning defined by constants @@ -287,7 +288,7 @@ struct ai_local_rw sbyte achieved_state[MAX_SUBMODELS]; // Last achieved state }; -struct ai_cloak_info +struct ai_cloak_info : public prohibit_void_ptr { fix64 last_time; #if defined(DXX_BUILD_DESCENT_II) diff --git a/common/main/cntrlcen.h b/common/main/cntrlcen.h index 02072f23f..84a46cba5 100644 --- a/common/main/cntrlcen.h +++ b/common/main/cntrlcen.h @@ -32,10 +32,11 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "switch.h" #ifdef __cplusplus +#include "pack.h" #define MAX_CONTROLCEN_LINKS 10 -struct control_center_triggers +struct control_center_triggers : public prohibit_void_ptr { short num_links; array seg; diff --git a/common/main/config.h b/common/main/config.h index cc85e16b0..0d872fddd 100644 --- a/common/main/config.h +++ b/common/main/config.h @@ -31,8 +31,9 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "mission.h" #ifdef __cplusplus +#include "pack.h" -struct Cfg +struct Cfg : public prohibit_void_ptr { ubyte DigiVolume; ubyte MusicVolume; @@ -60,7 +61,7 @@ struct Cfg int MovieTexFilt; int MovieSubtitles; #endif -} __pack__; +}; extern struct Cfg GameCfg; diff --git a/common/main/effects.h b/common/main/effects.h index 026f8fcd0..46092f252 100644 --- a/common/main/effects.h +++ b/common/main/effects.h @@ -32,6 +32,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #ifdef __cplusplus #include "dxxsconf.h" #include "compiler-array.h" +#include "pack.h" #if defined(DXX_BUILD_DESCENT_I) #define MAX_EFFECTS 60 @@ -51,7 +52,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #define ECLIP_NUM_FORCE_FIELD 78 #endif -struct eclip +struct eclip : public prohibit_void_ptr { vclip vc; //imbedded vclip fix time_left; //for sequencing diff --git a/common/main/fuelcen.h b/common/main/fuelcen.h index 9e28a353e..4a83e1def 100644 --- a/common/main/fuelcen.h +++ b/common/main/fuelcen.h @@ -30,6 +30,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "object.h" #ifdef __cplusplus +#include "pack.h" //------------------------------------------------------------ // A refueling center is one segment... to identify it in the @@ -103,7 +104,7 @@ fix repaircen_give_shields(segment *segp, fix MaxAmountCanTake ); //--repair-- abort_repair_center(); // An array of pointers to segments with fuel centers. -struct FuelCenter +struct FuelCenter : public prohibit_void_ptr { int Type; int segnum; @@ -119,7 +120,7 @@ struct FuelCenter // The max number of robot centers per mine. #define MAX_ROBOT_CENTERS 20 -struct d1_matcen_info +struct d1_matcen_info : public prohibit_void_ptr { array robot_flags; // Up to 32 different robots fix hit_points; // How hard it is to destroy this particular matcen @@ -133,7 +134,7 @@ struct d1_matcen_info typedef d1_matcen_info matcen_info; void matcen_info_read(PHYSFS_file *fp, matcen_info &ps, int version); #elif defined(DXX_BUILD_DESCENT_II) -struct matcen_info +struct matcen_info : public prohibit_void_ptr { array robot_flags; // Up to 64 different robots fix hit_points; // How hard it is to destroy this particular matcen diff --git a/common/main/net_udp.h b/common/main/net_udp.h index aa474c344..6c1df1499 100644 --- a/common/main/net_udp.h +++ b/common/main/net_udp.h @@ -98,7 +98,7 @@ void net_udp_send_netgame_update(); #endif // Structure keeping lite game infos (for netlist, etc.) -struct UDP_netgame_info_lite +struct UDP_netgame_info_lite : public prohibit_void_ptr { struct _sockaddr game_addr; short program_iver[3]; @@ -114,7 +114,7 @@ struct UDP_netgame_info_lite ubyte numconnected; ubyte max_numplayers; bit_game_flags game_flag; -} __pack__; +}; struct UDP_sequence_packet { @@ -155,10 +155,10 @@ struct UDP_mdata_store } __pack__; // structure to keep track of MDATA packets we've already got -struct UDP_mdata_recv +struct UDP_mdata_recv : public prohibit_void_ptr { int pkt_num[UDP_MDATA_STOR_QUEUE_SIZE]; int cur_slot; // index we can use for a new pkt_num -} __pack__; +}; #endif diff --git a/common/main/object.h b/common/main/object.h index 84df06e49..effbd9aed 100644 --- a/common/main/object.h +++ b/common/main/object.h @@ -211,7 +211,7 @@ struct quaternionpos #define MATRIX_MAX 0x7f // This is based on MATRIX_PRECISION, 9 => 0x7f // information for physics sim for an object -struct physics_info +struct physics_info : public prohibit_void_ptr { vms_vector velocity; // velocity vector of this object vms_vector thrust; // constant force applied to this object @@ -238,9 +238,9 @@ struct physics_info_rw // stuctures for different kinds of simulation -struct laser_info +struct laser_info : public prohibit_void_ptr { - struct hitobj_list_t + struct hitobj_list_t : public prohibit_void_ptr { typedef unsigned objnum_t; template @@ -325,7 +325,7 @@ struct laser_info_rw fix multiplier; // Power if this is a fusion bolt (or other super weapon to be added). } __pack__; -struct explosion_info +struct explosion_info : public prohibit_void_ptr { fix spawn_time; // when lifeleft is < this, spawn another fix delete_time; // when to delete object @@ -345,7 +345,7 @@ struct explosion_info_rw short next_attach; // next explosion in attach list } __pack__; -struct light_info +struct light_info : public prohibit_void_ptr { fix intensity; // how bright the light is }; @@ -355,14 +355,14 @@ struct light_info_rw fix intensity; // how bright the light is } __pack__; -struct powerup_info +struct powerup_info : public prohibit_void_ptr { int count; // how many/much we pick up (vulcan cannon only?) #if defined(DXX_BUILD_DESCENT_II) int flags; // spat by player? fix64 creation_time; // Absolute time of creation. #endif -} __pack__; +}; struct powerup_info_rw { @@ -374,7 +374,7 @@ struct powerup_info_rw #endif } __pack__; -struct vclip_info +struct vclip_info : public prohibit_void_ptr { int vclip_num; fix frametime; @@ -390,7 +390,7 @@ struct vclip_info_rw // structures for different kinds of rendering -struct polyobj_info +struct polyobj_info : public prohibit_void_ptr { int model_num; // which polygon model vms_angvec anim_angles[MAX_SUBMODELS]; // angles for each subobject diff --git a/common/main/player.h b/common/main/player.h index 3088bc11b..a74bf1316 100644 --- a/common/main/player.h +++ b/common/main/player.h @@ -33,6 +33,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #endif #ifdef __cplusplus +#include "pack.h" #define MAX_PLAYERS 8 #define MAX_MULTI_PLAYERS MAX_PLAYERS+3 @@ -87,7 +88,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) // When this structure changes, increment the constant // SAVE_FILE_VERSION in playsave.c -struct player +struct player : public prohibit_void_ptr { // Who am I data char callsign[CALLSIGN_LEN+1]; // The callsign of this player, for net purposes. diff --git a/common/main/powerup.h b/common/main/powerup.h index 497113c30..127072e25 100644 --- a/common/main/powerup.h +++ b/common/main/powerup.h @@ -117,7 +117,7 @@ enum powerup_type_t #define POWERUP_NAME_LENGTH 16 // Length of a robot or powerup name. extern char Powerup_names[MAX_POWERUP_TYPES][POWERUP_NAME_LENGTH]; -struct powerup_type_info +struct powerup_type_info : public prohibit_void_ptr { int vclip_num; int hit_sound; diff --git a/common/main/switch.h b/common/main/switch.h index cd5a9dd8b..dc679f4e7 100644 --- a/common/main/switch.h +++ b/common/main/switch.h @@ -27,6 +27,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #define _SWITCH_H #ifdef __cplusplus +#include "pack.h" struct segment; @@ -108,7 +109,7 @@ struct v30_trigger //the trigger really should have both a type & a flags, since most of the //flags bits are exclusive of the others. #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) -struct trigger +struct trigger : public prohibit_void_ptr { #if defined(DXX_BUILD_DESCENT_I) short flags; diff --git a/common/main/vclip.h b/common/main/vclip.h index d9cf26f53..19e8fa55f 100644 --- a/common/main/vclip.h +++ b/common/main/vclip.h @@ -58,7 +58,7 @@ struct objptridx_t; // vclip flags #define VF_ROD 1 // draw as a rod, not a blob -struct vclip +struct vclip : public prohibit_void_ptr { fix play_time; // total time (in seconds) of clip unsigned num_frames; diff --git a/common/main/wall.h b/common/main/wall.h index 1e1b10c32..0158df48a 100644 --- a/common/main/wall.h +++ b/common/main/wall.h @@ -32,6 +32,7 @@ struct object; struct objptridx_t; #ifdef __cplusplus +#include "pack.h" #if defined(DXX_BUILD_DESCENT_I) #define MAX_WALLS 175u // Maximum number of walls @@ -117,7 +118,7 @@ struct objptridx_t; #define MAX_STUCK_OBJECTS 32 -struct stuckobj +struct stuckobj : public prohibit_void_ptr { short objnum, wallnum; int signature; @@ -135,7 +136,7 @@ struct v16_wall sbyte keys; }; -struct v19_wall +struct v19_wall : public prohibit_void_ptr { int segnum,sidenum; // Seg & side for this wall sbyte type; // What kind of special wall. @@ -150,7 +151,7 @@ struct v19_wall //End old wall structures #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) -struct wall +struct wall : public prohibit_void_ptr { short segnum; int sidenum; // Seg & side for this wall @@ -172,7 +173,7 @@ struct wall }; #endif -struct active_door +struct active_door : public prohibit_void_ptr { int n_parts; // for linked walls array front_wallnum; // front wall numbers for this door @@ -181,7 +182,7 @@ struct active_door }; #if defined(DXX_BUILD_DESCENT_II) -struct cloaking_wall +struct cloaking_wall : public prohibit_void_ptr { short front_wallnum; // front wall numbers for this door short back_wallnum; // back wall numbers for this door @@ -200,7 +201,8 @@ struct cloaking_wall #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) #define MAX_CLIP_FRAMES_D1 20 -struct wclip { +struct wclip : public prohibit_void_ptr +{ fix play_time; short num_frames; union { diff --git a/d1x-rebirth/main/bmread.cpp b/d1x-rebirth/main/bmread.cpp index 88155eea2..cfd56de1a 100644 --- a/d1x-rebirth/main/bmread.cpp +++ b/d1x-rebirth/main/bmread.cpp @@ -1096,7 +1096,10 @@ static void bm_read_robot(int skip) n_textures = first_bitmap_num[i+1] - first_bitmap_num[i]; - model_num = load_polygon_model(model_name[i],n_textures,first_bitmap_num[i],(i==0)?&Robot_info[N_robot_types]:NULL); + robot_info *ri = NULL; + if (i == 0) + ri = &Robot_info[N_robot_types]; + model_num = load_polygon_model(model_name[i],n_textures,first_bitmap_num[i],ri); if (i==0) Robot_info[N_robot_types].model_num = model_num; @@ -1317,7 +1320,10 @@ void bm_read_player_ship(int skip) n_textures = first_bitmap_num[i+1] - first_bitmap_num[i]; - model_num = load_polygon_model(model_name[i],n_textures,first_bitmap_num[i],(i==0)?&ri:NULL); + robot_info *pri = NULL; + if (i == 0) + pri = &ri; + model_num = load_polygon_model(model_name[i],n_textures,first_bitmap_num[i],pri); if (i==0) Player_ship->model_num = model_num;