From adb8f7f6cc63a110c8583aaee0d9f7039fbbbe2c Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 30 Sep 2015 23:32:36 +0300 Subject: Add missing checks to homunculus.c --- src/map/homunculus.c | 55 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 874d26fdb..2490bc659 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -49,6 +49,7 @@ struct homunculus_interface *homun; //Returns the viewdata for homunculus struct view_data* homunculus_get_viewdata(int class_) { + Assert_retr(NULL, class_ >= HM_CLASS_BASE && class_ - HM_CLASS_BASE < MAX_HOMUNCULUS_CLASS); if (homdb_checkid(class_)) return &homun->dbs->viewdb[class_-HM_CLASS_BASE]; return NULL; @@ -122,8 +123,11 @@ void homunculus_damaged(struct homun_data *hd) { int homunculus_dead(struct homun_data *hd) { //There's no intimacy penalties on death (from Tharis) - struct map_session_data *sd = hd->master; + struct map_session_data *sd; + nullpo_retr(3, hd); + sd = hd->master; + nullpo_retr(3, sd); clif->emotion(&hd->bl, E_WAH); //Delete timers when dead. @@ -195,6 +199,7 @@ int homunculus_calc_skilltree(struct homun_data *hd, int flag_evolve) { /* load previous homunculus form skills first. */ if( hd->homunculus.prev_class != 0 ) { c = hd->homunculus.prev_class - HM_CLASS_BASE; + Assert_ret(c >= 0 && c < MAX_HOMUNCULUS_CLASS); for( i = 0; i < MAX_SKILL_TREE && ( id = homun->dbs->skill_tree[c][i].id ) > 0; i++ ) { if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id ) @@ -216,6 +221,7 @@ int homunculus_calc_skilltree(struct homun_data *hd, int flag_evolve) { } c = hd->homunculus.class_ - HM_CLASS_BASE; + Assert_ret(c >= 0 && c < MAX_HOMUNCULUS_CLASS); for( i = 0; i < MAX_SKILL_TREE && ( id = homun->dbs->skill_tree[c][i].id ) > 0; i++ ) { if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id ) @@ -246,6 +252,7 @@ int homunculus_checkskill(struct homun_data *hd,uint16 skill_id) { if(!hd) return 0; + Assert_ret(i >= 0 && i < MAX_HOMUNSKILL); if(hd->homunculus.hskill[i].id == skill_id) return (hd->homunculus.hskill[i].lv); @@ -255,6 +262,7 @@ int homunculus_checkskill(struct homun_data *hd,uint16 skill_id) { int homunculus_skill_tree_get_max(int id, int b_class) { int i, skill_id; b_class -= HM_CLASS_BASE; + Assert_ret(b_class >= 0 && b_class < MAX_HOMUNCULUS_CLASS); for(i=0;(skill_id=homun->dbs->skill_tree[b_class][i].id)>0;i++) if (id == skill_id) return homun->dbs->skill_tree[b_class][i].max; @@ -269,6 +277,7 @@ void homunculus_skillup(struct homun_data *hd,uint16 skill_id) { return; i = skill_id - HM_SKILLBASE; + Assert_retv(i >= 0 && i < MAX_HOMUNSKILL); if(hd->homunculus.skillpts > 0 && hd->homunculus.hskill[i].id && hd->homunculus.hskill[i].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex] @@ -293,6 +302,7 @@ bool homunculus_levelup(struct homun_data *hd) { int growth_max_hp, growth_max_sp; enum homun_type htype; + nullpo_retr(false, hd); if( (htype = homun->class2type(hd->homunculus.class_)) == HT_INVALID ) { ShowError("homunculus_levelup: Invalid class %d. \n", hd->homunculus.class_); return false; @@ -365,8 +375,8 @@ bool homunculus_levelup(struct homun_data *hd) { } int homunculus_change_class(struct homun_data *hd, short class_) { - int i; - i = homun->db_search(class_,HOMUNCULUS_CLASS); + int i = homun->db_search(class_,HOMUNCULUS_CLASS); + nullpo_retr(0, hd); if(i < 0) return 0; hd->homunculusDB = &homun->dbs->db[i]; @@ -477,6 +487,7 @@ bool homunculus_mutate(struct homun_data *hd, int homun_id) { int homunculus_gainexp(struct homun_data *hd,unsigned int exp) { enum homun_type htype; + nullpo_ret(hd); if(hd->homunculus.vaporize != HOM_ST_ACTIVE) return 1; @@ -518,6 +529,7 @@ int homunculus_gainexp(struct homun_data *hd,unsigned int exp) { // Return the new value unsigned int homunculus_add_intimacy(struct homun_data *hd, unsigned int value) { + nullpo_ret(hd); if (battle_config.homunculus_friendly_rate != 100) value = (value * battle_config.homunculus_friendly_rate) / 100; @@ -530,6 +542,7 @@ unsigned int homunculus_add_intimacy(struct homun_data *hd, unsigned int value) // Return 0 if decrease fails or intimacy became 0 else the new value unsigned int homunculus_consume_intimacy(struct homun_data *hd, unsigned int value) { + nullpo_ret(hd); if (hd->homunculus.intimacy >= value) hd->homunculus.intimacy -= value; else @@ -539,15 +552,19 @@ unsigned int homunculus_consume_intimacy(struct homun_data *hd, unsigned int val } void homunculus_healed (struct homun_data *hd) { + nullpo_retv(hd); clif->hominfo(hd->master,hd,0); } void homunculus_save(struct homun_data *hd) { // copy data that must be saved in homunculus struct ( hp / sp ) - TBL_PC * sd = hd->master; + TBL_PC * sd; //Do not check for max_hp/max_sp caps as current could be higher to max due //to status changes/skills (they will be capped as needed upon stat //calculation on login) + nullpo_retv(hd); + sd = hd->master; + nullpo_retv(sd); hd->homunculus.hp = hd->battle_status.hp; hd->homunculus.sp = hd->battle_status.sp; intif->homunculus_requestsave(sd->status.account_id, &hd->homunculus); @@ -577,6 +594,8 @@ unsigned char homunculus_menu(struct map_session_data *sd,unsigned char menu_num bool homunculus_feed(struct map_session_data *sd, struct homun_data *hd) { int i, foodID, emotion; + nullpo_retr(false, hd); + nullpo_retr(false, sd); if(hd->homunculus.vaporize == HOM_ST_REST) return false; @@ -617,7 +636,6 @@ bool homunculus_feed(struct map_session_data *sd, struct homun_data *hd) { // Too much food :/ if(hd->homunculus.intimacy == 0) return homun->delete(sd->hd, E_OMG); - return true; } @@ -669,6 +687,7 @@ int homunculus_change_name(struct map_session_data *sd,char *name) { int i; struct homun_data *hd; nullpo_retr(1, sd); + nullpo_retr(1, name); hd = sd->hd; if (!homun_alive(hd)) @@ -685,7 +704,11 @@ int homunculus_change_name(struct map_session_data *sd,char *name) { } bool homunculus_change_name_ack(struct map_session_data *sd, char* name, int flag) { - struct homun_data *hd = sd->hd; + struct homun_data *hd; + nullpo_retr(false, sd); + nullpo_retr(false, name); + hd = sd->hd; + nullpo_retr(false, hd); if (!homun_alive(hd)) return false; normalize_name(name," ");//bugreport:3032 @@ -730,6 +753,7 @@ bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) { int i = 0; nullpo_retr(false, sd); + nullpo_retr(false, hom); Assert_retr(false, sd->status.hom_id == 0 || sd->hd == 0 || sd->hd->master == sd); @@ -772,6 +796,7 @@ bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) { } void homunculus_init_timers(struct homun_data * hd) { + nullpo_retv(hd); if (hd->hungry_timer == INVALID_TIMER) hd->hungry_timer = timer->add(timer->gettick()+hd->homunculusDB->hungryDelay,homun->hunger_timer,hd->master->bl.id,0); hd->regen.state.block = 0; //Restore HP/SP block. @@ -780,6 +805,7 @@ void homunculus_init_timers(struct homun_data * hd) { bool homunculus_call(struct map_session_data *sd) { struct homun_data *hd; + nullpo_retr(false, sd); if (!sd->status.hom_id) //Create a new homun. return homun->creation_request(sd, HM_CLASS_BASE + rnd_value(0, 7)); @@ -818,6 +844,7 @@ bool homunculus_recv_data(int account_id, struct s_homunculus *sh, int flag) { struct map_session_data *sd; struct homun_data *hd; + nullpo_retr(false, sh); sd = map->id2sd(account_id); if(!sd) return false; @@ -916,6 +943,7 @@ bool homunculus_ressurect(struct map_session_data* sd, unsigned char per, short hd = sd->hd; + nullpo_retr(false, hd); if (hd->homunculus.vaporize != HOM_ST_ACTIVE) return false; // vaporized homunculi need to be 'called' @@ -937,7 +965,10 @@ bool homunculus_ressurect(struct map_session_data* sd, unsigned char per, short } void homunculus_revive(struct homun_data *hd, unsigned int hp, unsigned int sp) { - struct map_session_data *sd = hd->master; + struct map_session_data *sd; + + nullpo_retv(hd); + sd = hd->master; hd->homunculus.hp = hd->battle_status.hp; if (!sd) return; @@ -951,6 +982,7 @@ void homunculus_stat_reset(struct homun_data *hd) { struct s_homunculus_db *db; struct s_homunculus *hom; struct h_stats *base; + nullpo_retv(hd); hom = &hd->homunculus; db = hd->homunculusDB; base = &db->base; @@ -976,6 +1008,7 @@ bool homunculus_shuffle(struct homun_data *hd) { unsigned int exp; struct s_skill b_skill[MAX_HOMUNSKILL]; + nullpo_retr(false, hd); if (!homun_alive(hd)) return false; @@ -1022,6 +1055,7 @@ bool homunculus_read_db_sub(char* str[], int columns, int current) { int classid; struct s_homunculus_db *db; + nullpo_retr(false, str); //Base Class,Evo Class classid = atoi(str[0]); if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX) { @@ -1153,13 +1187,14 @@ bool homunculus_read_skill_db_sub(char* split[], int columns, int current) { int j; int minJobLevelPresent = 0; + nullpo_retr(false, split); if( columns == 15 ) minJobLevelPresent = 1; // MinJobLvl has been added - FIXME: is this extra field even needed anymore? // check for bounds [celest] classid = atoi(split[0]) - HM_CLASS_BASE; - if ( classid >= MAX_HOMUNCULUS_CLASS ) { + if ( classid < 0 || classid >= MAX_HOMUNCULUS_CLASS ) { ShowWarning("homunculus_read_skill_db_sub: Invalid homunculus class %d.\n", atoi(split[0])); return false; } @@ -1188,7 +1223,9 @@ bool homunculus_read_skill_db_sub(char* split[], int columns, int current) { } int8 homunculus_get_intimacy_grade(struct homun_data *hd) { - unsigned int val = hd->homunculus.intimacy / 100; + unsigned int val; + nullpo_ret(hd); + val = hd->homunculus.intimacy / 100; if( val > 100 ) { if( val > 250 ) { if( val > 750 ) { -- cgit v1.2.3-60-g2f50