From 3633262bf2d8db0dd3bd51370826120371aac4a0 Mon Sep 17 00:00:00 2001 From: skotlex Date: Mon, 27 Mar 2006 01:24:34 +0000 Subject: - Changed status_point/skill_point to unsigned short. Adjusted the code as necessary to prevent overflows. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5762 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 2 ++ src/char/char.c | 49 ++++++++++++++++++++++++++-------------------- src/char_sql/char.c | 54 +++++++++++++++++++++++++-------------------------- src/common/mmo.h | 2 +- src/map/atcommand.c | 51 ++++++++++++++++++++++++++++++------------------ src/map/charcommand.c | 43 ++++++++++++++++++++++++++-------------- src/map/charsave.c | 4 ++-- src/map/chrif.c | 10 ++++++++-- src/map/clif.c | 14 ++++++------- src/map/pc.c | 54 +++++++++++++++++++++++++++++++++------------------ 10 files changed, 170 insertions(+), 113 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 4b1a1aa28..6d1ed241a 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -6,6 +6,8 @@ GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALAR 2006/03/26 + * Changed status_point/skill_point to unsigned short. Adjusted the code as + necessary to prevent overflows. [Skotlex] * itemdb_exists and itemdb_searchname should now ignore dummy_item matches. [Skotlex] * Fixed jstrescapecpy crashing when you pass a null string to parse. [Skotlex] 2006/03/25 diff --git a/src/char/char.c b/src/char/char.c index e803df3ce..c50dbe126 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -580,8 +580,8 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p, struct global_reg *reg p->int_ = tmp_int[16]; p->dex = tmp_int[17]; p->luk = tmp_int[18]; - p->status_point = tmp_int[19]; - p->skill_point = tmp_int[20]; + p->status_point = tmp_int[19] > USHRT_MAX ? USHRT_MAX : tmp_int[19]; + p->skill_point = tmp_int[20] > USHRT_MAX ? USHRT_MAX : tmp_int[20]; p->option = tmp_int[21]; p->karma = tmp_int[22]; p->manner = tmp_int[23]; @@ -1637,11 +1637,11 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) { WFIFOL(fd,j+32) = p->karma; WFIFOL(fd,j+36) = p->manner; - WFIFOW(fd,j+40) = p->status_point; - WFIFOW(fd,j+42) = (p->hp > 0x7fff) ? 0x7fff : p->hp; - WFIFOW(fd,j+44) = (p->max_hp > 0x7fff) ? 0x7fff : p->max_hp; - WFIFOW(fd,j+46) = (p->sp > 0x7fff) ? 0x7fff : p->sp; - WFIFOW(fd,j+48) = (p->max_sp > 0x7fff) ? 0x7fff : p->max_sp; + WFIFOW(fd,j+40) = (p->status_point>SHRT_MAX) ? SHRT_MAX : p->status_point; + WFIFOW(fd,j+42) = (p->hp > SHRT_MAX) ? SHRT_MAX : p->hp; + WFIFOW(fd,j+44) = (p->max_hp > SHRT_MAX) ? SHRT_MAX : p->max_hp; + WFIFOW(fd,j+46) = (p->sp > SHRT_MAX) ? SHRT_MAX : p->sp; + WFIFOW(fd,j+48) = (p->max_sp > SHRT_MAX) ? SHRT_MAX : p->max_sp; WFIFOW(fd,j+50) = DEFAULT_WALK_SPEED; // p->speed; WFIFOW(fd,j+52) = p->class_; WFIFOW(fd,j+54) = p->hair; @@ -1654,7 +1654,7 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) { else WFIFOW(fd,j+56) = p->weapon; WFIFOW(fd,j+58) = p->base_level; - WFIFOW(fd,j+60) = p->skill_point; + WFIFOW(fd,j+60) = (p->skill_point>SHRT_MAX)? SHRT_MAX : p->skill_point; WFIFOW(fd,j+62) = p->head_bottom; WFIFOW(fd,j+64) = p->shield; WFIFOW(fd,j+66) = p->head_top; @@ -1989,7 +1989,10 @@ int parse_tologin(int fd) { // remove specifical skills of classes 19, 4020 and 4042 for(j = 315; j <= 322; j++) { if (char_dat[i].status.skill[j].id > 0 && !char_dat[i].status.skill[j].flag) { - char_dat[i].status.skill_point += char_dat[i].status.skill[j].lv; + if (char_dat[i].status.skill_point > USHRT_MAX - char_dat[i].status.skill[j].lv) + char_dat[i].status.skill_point = USHRT_MAX; + else + char_dat[i].status.skill_point += char_dat[i].status.skill[j].lv; char_dat[i].status.skill[j].id = 0; char_dat[i].status.skill[j].lv = 0; } @@ -1997,7 +2000,11 @@ int parse_tologin(int fd) { // remove specifical skills of classes 20, 4021 and 4043 for(j = 323; j <= 330; j++) { if (char_dat[i].status.skill[j].id > 0 && !char_dat[i].status.skill[j].flag) { - char_dat[i].status.skill_point += char_dat[i].status.skill[j].lv; + if (char_dat[i].status.skill_point > USHRT_MAX - char_dat[i].status.skill[j].lv) + char_dat[i].status.skill_point = USHRT_MAX; + else + char_dat[i].status.skill_point += char_dat[i].status.skill[j].lv; + char_dat[i].status.skill[j].id = 0; char_dat[i].status.skill[j].lv = 0; } @@ -3390,16 +3397,16 @@ int parse_char(int fd) { WFIFOL(fd,2+32) = char_dat[i].status.manner; WFIFOW(fd,2+40) = 0x30; - WFIFOW(fd,2+42) = (char_dat[i].status.hp > 0x7fff) ? 0x7fff : char_dat[i].status.hp; - WFIFOW(fd,2+44) = (char_dat[i].status.max_hp > 0x7fff) ? 0x7fff : char_dat[i].status.max_hp; - WFIFOW(fd,2+46) = (char_dat[i].status.sp > 0x7fff) ? 0x7fff : char_dat[i].status.sp; - WFIFOW(fd,2+48) = (char_dat[i].status.max_sp > 0x7fff) ? 0x7fff : char_dat[i].status.max_sp; + WFIFOW(fd,2+42) = (char_dat[i].status.hp > SHRT_MAX) ? SHRT_MAX : char_dat[i].status.hp; + WFIFOW(fd,2+44) = (char_dat[i].status.max_hp > SHRT_MAX) ? SHRT_MAX : char_dat[i].status.max_hp; + WFIFOW(fd,2+46) = (char_dat[i].status.sp > SHRT_MAX) ? SHRT_MAX : char_dat[i].status.sp; + WFIFOW(fd,2+48) = (char_dat[i].status.max_sp > SHRT_MAX) ? SHRT_MAX : char_dat[i].status.max_sp; WFIFOW(fd,2+50) = DEFAULT_WALK_SPEED; // char_dat[i].status.speed; WFIFOW(fd,2+52) = char_dat[i].status.class_; WFIFOW(fd,2+54) = char_dat[i].status.hair; WFIFOW(fd,2+58) = char_dat[i].status.base_level; - WFIFOW(fd,2+60) = char_dat[i].status.skill_point; + WFIFOW(fd,2+60) = (char_dat[i].status.skill_point > SHRT_MAX) ? SHRT_MAX : char_dat[i].status.skill_point; WFIFOW(fd,2+64) = char_dat[i].status.shield; WFIFOW(fd,2+66) = char_dat[i].status.head_top; @@ -3408,12 +3415,12 @@ int parse_char(int fd) { memcpy(WFIFOP(fd,2+74), char_dat[i].status.name, NAME_LENGTH); - WFIFOB(fd,2+98) = (char_dat[i].status.str > 255) ? 255 : char_dat[i].status.str; - WFIFOB(fd,2+99) = (char_dat[i].status.agi > 255) ? 255 : char_dat[i].status.agi; - WFIFOB(fd,2+100) = (char_dat[i].status.vit > 255) ? 255 : char_dat[i].status.vit; - WFIFOB(fd,2+101) = (char_dat[i].status.int_ > 255) ? 255 : char_dat[i].status.int_; - WFIFOB(fd,2+102) = (char_dat[i].status.dex > 255) ? 255 : char_dat[i].status.dex; - WFIFOB(fd,2+103) = (char_dat[i].status.luk > 255) ? 255 : char_dat[i].status.luk; + WFIFOB(fd,2+98) = (char_dat[i].status.str > UCHAR_MAX) ? UCHAR_MAX : char_dat[i].status.str; + WFIFOB(fd,2+99) = (char_dat[i].status.agi > UCHAR_MAX) ? UCHAR_MAX : char_dat[i].status.agi; + WFIFOB(fd,2+100) = (char_dat[i].status.vit > UCHAR_MAX) ? UCHAR_MAX : char_dat[i].status.vit; + WFIFOB(fd,2+101) = (char_dat[i].status.int_ > UCHAR_MAX) ? UCHAR_MAX : char_dat[i].status.int_; + WFIFOB(fd,2+102) = (char_dat[i].status.dex > UCHAR_MAX) ? UCHAR_MAX : char_dat[i].status.dex; + WFIFOB(fd,2+103) = (char_dat[i].status.luk > UCHAR_MAX) ? UCHAR_MAX : char_dat[i].status.luk; WFIFOB(fd,2+104) = char_dat[i].status.char_num; WFIFOSET(fd,108); diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 330869524..dbd7e2dc9 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -930,8 +930,8 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p){ p->hp = atoi(sql_row[17]); p->max_sp = atoi(sql_row[18]); p->sp = atoi(sql_row[19]); - p->status_point = atoi(sql_row[20]); - p->skill_point = atoi(sql_row[21]); + p->status_point = atoi(sql_row[20]) > USHRT_MAX ? USHRT_MAX : atoi(sql_row[20]); + p->skill_point = atoi(sql_row[21]) > USHRT_MAX ? USHRT_MAX : atoi(sql_row[21]); //free mysql result. mysql_free_result(sql_res); strcat (t_msg, " status"); @@ -1179,8 +1179,8 @@ int mmo_char_fromsql_short(int char_id, struct mmo_charstatus *p){ p->hp = atoi(sql_row[17]); p->max_sp = atoi(sql_row[18]); p->sp = atoi(sql_row[19]); - p->status_point = atoi(sql_row[20]); - p->skill_point = atoi(sql_row[21]); + p->status_point = atoi(sql_row[20]) > USHRT_MAX ? USHRT_MAX : atoi(sql_row[20]); + p->skill_point = atoi(sql_row[21]) > USHRT_MAX ? USHRT_MAX : atoi(sql_row[21]); //free mysql result. mysql_free_result(sql_res); strcat (t_msg, " status"); @@ -1727,11 +1727,11 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) { WFIFOL(fd,j+32) = p->karma; WFIFOL(fd,j+36) = p->manner; - WFIFOW(fd,j+40) = p->status_point; - WFIFOW(fd,j+42) = (p->hp > 0x7fff) ? 0x7fff : p->hp; - WFIFOW(fd,j+44) = (p->max_hp > 0x7fff) ? 0x7fff : p->max_hp; - WFIFOW(fd,j+46) = (p->sp > 0x7fff) ? 0x7fff : p->sp; - WFIFOW(fd,j+48) = (p->max_sp > 0x7fff) ? 0x7fff : p->max_sp; + WFIFOW(fd,j+40) = (p->status_point > SHRT_MAX) ? SHRT_MAX : p->status_point; + WFIFOW(fd,j+42) = (p->hp > SHRT_MAX) ? SHRT_MAX : p->hp; + WFIFOW(fd,j+44) = (p->max_hp > SHRT_MAX) ? SHRT_MAX : p->max_hp; + WFIFOW(fd,j+46) = (p->sp > SHRT_MAX) ? SHRT_MAX : p->sp; + WFIFOW(fd,j+48) = (p->max_sp > SHRT_MAX) ? SHRT_MAX : p->max_sp; WFIFOW(fd,j+50) = DEFAULT_WALK_SPEED; // p->speed; WFIFOW(fd,j+52) = p->class_; WFIFOW(fd,j+54) = p->hair; @@ -1744,7 +1744,7 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) { else WFIFOW(fd,j+56) = p->weapon; WFIFOW(fd,j+58) = p->base_level; - WFIFOW(fd,j+60) = p->skill_point; + WFIFOW(fd,j+60) = (p->skill_point > SHRT_MAX) ? SHRT_MAX : p->skill_point; WFIFOW(fd,j+62) = p->head_bottom; WFIFOW(fd,j+64) = p->shield; WFIFOW(fd,j+66) = p->head_top; @@ -1754,12 +1754,12 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) { memcpy(WFIFOP(fd,j+74), p->name, NAME_LENGTH); - WFIFOB(fd,j+98) = (p->str > 255) ? 255 : p->str; - WFIFOB(fd,j+99) = (p->agi > 255) ? 255 : p->agi; - WFIFOB(fd,j+100) = (p->vit > 255) ? 255 : p->vit; - WFIFOB(fd,j+101) = (p->int_ > 255) ? 255 : p->int_; - WFIFOB(fd,j+102) = (p->dex > 255) ? 255 : p->dex; - WFIFOB(fd,j+103) = (p->luk > 255) ? 255 : p->luk; + WFIFOB(fd,j+98) = (p->str > UCHAR_MAX) ? UCHAR_MAX : p->str; + WFIFOB(fd,j+99) = (p->agi > UCHAR_MAX) ? UCHAR_MAX : p->agi; + WFIFOB(fd,j+100) = (p->vit > UCHAR_MAX) ? UCHAR_MAX : p->vit; + WFIFOB(fd,j+101) = (p->int_ > UCHAR_MAX) ? UCHAR_MAX : p->int_; + WFIFOB(fd,j+102) = (p->dex > UCHAR_MAX) ? UCHAR_MAX : p->dex; + WFIFOB(fd,j+103) = (p->luk > UCHAR_MAX) ? UCHAR_MAX : p->luk; WFIFOB(fd,j+104) = p->char_num; } @@ -3270,16 +3270,16 @@ int parse_char(int fd) { WFIFOL(fd,2+32) = char_dat[i].manner; WFIFOW(fd,2+40) = 0x30; - WFIFOW(fd,2+42) = (char_dat[i].hp > 0x7fff) ? 0x7fff : char_dat[i].hp; - WFIFOW(fd,2+44) = (char_dat[i].max_hp > 0x7fff) ? 0x7fff : char_dat[i].max_hp; - WFIFOW(fd,2+46) = (char_dat[i].sp > 0x7fff) ? 0x7fff : char_dat[i].sp; - WFIFOW(fd,2+48) = (char_dat[i].max_sp > 0x7fff) ? 0x7fff : char_dat[i].max_sp; + WFIFOW(fd,2+42) = (char_dat[i].hp > SHRT_MAX) ? SHRT_MAX : char_dat[i].hp; + WFIFOW(fd,2+44) = (char_dat[i].max_hp > SHRT_MAX) ? SHRT_MAX : char_dat[i].max_hp; + WFIFOW(fd,2+46) = (char_dat[i].sp > SHRT_MAX) ? SHRT_MAX : char_dat[i].sp; + WFIFOW(fd,2+48) = (char_dat[i].max_sp > SHRT_MAX) ? SHRT_MAX : char_dat[i].max_sp; WFIFOW(fd,2+50) = DEFAULT_WALK_SPEED; // char_dat[i].speed; WFIFOW(fd,2+52) = char_dat[i].class_; WFIFOW(fd,2+54) = char_dat[i].hair; WFIFOW(fd,2+58) = char_dat[i].base_level; - WFIFOW(fd,2+60) = char_dat[i].skill_point; + WFIFOW(fd,2+60) = (char_dat[i].skill_point > SHRT_MAX) ? SHRT_MAX : char_dat[i].skill_point; WFIFOW(fd,2+64) = char_dat[i].shield; WFIFOW(fd,2+66) = char_dat[i].head_top; @@ -3288,12 +3288,12 @@ int parse_char(int fd) { memcpy(WFIFOP(fd,2+74), char_dat[i].name, NAME_LENGTH); - WFIFOB(fd,2+98) = char_dat[i].str>255?255:char_dat[i].str; - WFIFOB(fd,2+99) = char_dat[i].agi>255?255:char_dat[i].agi; - WFIFOB(fd,2+100) = char_dat[i].vit>255?255:char_dat[i].vit; - WFIFOB(fd,2+101) = char_dat[i].int_>255?255:char_dat[i].int_; - WFIFOB(fd,2+102) = char_dat[i].dex>255?255:char_dat[i].dex; - WFIFOB(fd,2+103) = char_dat[i].luk>255?255:char_dat[i].luk; + WFIFOB(fd,2+98) = char_dat[i].str>UCHAR_MAX?UCHAR_MAX:char_dat[i].str; + WFIFOB(fd,2+99) = char_dat[i].agi>UCHAR_MAX?UCHAR_MAX:char_dat[i].agi; + WFIFOB(fd,2+100) = char_dat[i].vit>UCHAR_MAX?UCHAR_MAX:char_dat[i].vit; + WFIFOB(fd,2+101) = char_dat[i].int_>UCHAR_MAX?UCHAR_MAX:char_dat[i].int_; + WFIFOB(fd,2+102) = char_dat[i].dex>UCHAR_MAX?UCHAR_MAX:char_dat[i].dex; + WFIFOB(fd,2+103) = char_dat[i].luk>UCHAR_MAX?UCHAR_MAX:char_dat[i].luk; WFIFOB(fd,2+104) = char_dat[i].char_num; WFIFOSET(fd, 108); diff --git a/src/common/mmo.h b/src/common/mmo.h index ab9fd6dd7..99fb76c40 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -181,7 +181,7 @@ struct mmo_charstatus { int zeny; short class_; - short status_point,skill_point; + unsigned short status_point,skill_point; int hp,max_hp,sp,max_sp; short option,manner; unsigned char karma; diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 92ec003e5..9d4bbe155 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -2686,7 +2686,7 @@ int atcommand_baselevelup( const int fd, struct map_session_data* sd, const char* command, const char* message) { - int level=0, i=0; + int level=0, i=0, status_point=0; nullpo_retr(-1, sd); level = atoi(message); @@ -2703,7 +2703,12 @@ int atcommand_baselevelup( if ((unsigned int)level > pc_maxbaselv(sd) || (unsigned int)level > pc_maxbaselv(sd) - sd->status.base_level) // fix positiv overflow level = pc_maxbaselv(sd) - sd->status.base_level; for (i = 1; i <= level; i++) - sd->status.status_point += (sd->status.base_level + i + 14) / 5; + status_point += (sd->status.base_level + i + 14) / 5; + + if (sd->status.status_point > USHRT_MAX - status_point) + sd->status.status_point = USHRT_MAX; + else + sd->status.status_point += status_point; sd->status.base_level += (unsigned int)level; clif_updatestatus(sd, SP_BASELEVEL); clif_updatestatus(sd, SP_NEXTBASEEXP); @@ -2722,9 +2727,11 @@ int atcommand_baselevelup( level = sd->status.base_level-1; if (sd->status.status_point > 0) { for (i = 0; i > -level; i--) - sd->status.status_point -= (sd->status.base_level + i + 14) / 5; - if (sd->status.status_point < 0) + status_point -= (sd->status.base_level + i + 14) / 5; + if (sd->status.status_point < status_point) sd->status.status_point = 0; + else + sd->status.status_point -= status_point; clif_updatestatus(sd, SP_STATUSPOINT); } /* to add: remove status points from stats */ sd->status.base_level -= (unsigned int)level; @@ -2764,7 +2771,10 @@ int atcommand_joblevelup( sd->status.job_level += (unsigned int)level; clif_updatestatus(sd, SP_JOBLEVEL); clif_updatestatus(sd, SP_NEXTJOBEXP); - sd->status.skill_point += level; + if (sd->status.skill_point > USHRT_MAX - level) + sd->status.skill_point = USHRT_MAX; + else + sd->status.skill_point += level; clif_updatestatus(sd, SP_SKILLPOINT); status_calc_pc(sd, 0); clif_misceffect(&sd->bl, 1); @@ -2782,9 +2792,10 @@ int atcommand_joblevelup( clif_updatestatus(sd, SP_NEXTJOBEXP); if (sd->status.skill_point < level) pc_resetskill(sd,0); //Reset skills since we need to substract more points. - sd->status.skill_point -= level; - if (sd->status.skill_point < 0) + if (sd->status.skill_point < level) sd->status.skill_point = 0; + else + sd->status.skill_point -= level; clif_updatestatus(sd, SP_SKILLPOINT); status_calc_pc(sd, 0); clif_displaymessage(fd, msg_table[25]); // Job level lowered. @@ -4020,14 +4031,15 @@ int atcommand_statuspoint( return -1; } - new_status_point = (int)sd->status.status_point + point; - if (point > 0 && (point > 0x7FFF || new_status_point > 0x7FFF)) // fix positiv overflow - new_status_point = 0x7FFF; - else if (point < 0 && (point < -0x7FFF || new_status_point < 0)) // fix negativ overflow + if (point > 0 && sd->status.status_point > USHRT_MAX - point) + new_status_point = USHRT_MAX; + else + if (point < 0 && sd->status.status_point < -point) new_status_point = 0; - + else + new_status_point = sd->status.status_point + point; if (new_status_point != (int)sd->status.status_point) { - sd->status.status_point = (short)new_status_point; + sd->status.status_point = (unsigned short)new_status_point; clif_updatestatus(sd, SP_STATUSPOINT); clif_displaymessage(fd, msg_table[174]); // Number of status points changed! } else { @@ -4057,14 +4069,15 @@ int atcommand_skillpoint( return -1; } - new_skill_point = (int)sd->status.skill_point + point; - if (point > 0 && (point > 0x7FFF || new_skill_point > 0x7FFF)) // fix positiv overflow - new_skill_point = 0x7FFF; - else if (point < 0 && (point < -0x7FFF || new_skill_point < 0)) // fix negativ overflow + if (point > 0 && sd->status.skill_point > USHRT_MAX - point) + new_skill_point = USHRT_MAX; + else if (point < 0 && sd->status.skill_point < -point) new_skill_point = 0; - + else + new_skill_point = sd->status.skill_point + point; + if (new_skill_point != (int)sd->status.skill_point) { - sd->status.skill_point = (short)new_skill_point; + sd->status.skill_point = (unsigned short)new_skill_point; clif_updatestatus(sd, SP_SKILLPOINT); clif_displaymessage(fd, msg_table[175]); // Number of skill points changed! } else { diff --git a/src/map/charcommand.c b/src/map/charcommand.c index 39478d58f..27e92029a 100644 --- a/src/map/charcommand.c +++ b/src/map/charcommand.c @@ -1276,7 +1276,7 @@ int charcommand_baselevel( { struct map_session_data *pl_sd; char player[NAME_LENGTH]; - int level = 0, i; + int level = 0, i, status_point=0; nullpo_retr(-1, sd); if (!message || !*message || sscanf(message, "%d %23[^\n]", &level, player) < 2 || level == 0) { @@ -1296,7 +1296,11 @@ int charcommand_baselevel( pl_sd->status.base_level > pc_maxbaselv(pl_sd) -level) level = pc_maxbaselv(pl_sd) - pl_sd->status.base_level; for (i = 1; i <= level; i++) - pl_sd->status.status_point += (pl_sd->status.base_level + i + 14) / 5; + status_point += (pl_sd->status.base_level + i + 14) / 5; + if (pl_sd->status.status_point > USHRT_MAX - status_point) + pl_sd->status.status_point = USHRT_MAX; + else + pl_sd->status.status_point += status_point; pl_sd->status.base_level += (unsigned int)level; clif_updatestatus(pl_sd, SP_BASELEVEL); clif_updatestatus(pl_sd, SP_NEXTBASEEXP); @@ -1315,9 +1319,11 @@ int charcommand_baselevel( level = pl_sd->status.base_level -1; if (pl_sd->status.status_point > 0) { for (i = 0; i > -level; i--) - pl_sd->status.status_point -= (pl_sd->status.base_level +i + 14) / 5; - if (pl_sd->status.status_point < 0) + status_point -= (pl_sd->status.base_level +i + 14) / 5; + if (pl_sd->status.status_point < status_point) pl_sd->status.status_point = 0; + else + pl_sd->status.status_point -= status_point; clif_updatestatus(pl_sd, SP_STATUSPOINT); } // to add: remove status points from stats pl_sd->status.base_level -= (unsigned int)level; @@ -1371,7 +1377,11 @@ int charcommand_joblevel( pl_sd->status.job_level += (unsigned int)level; clif_updatestatus(pl_sd, SP_JOBLEVEL); clif_updatestatus(pl_sd, SP_NEXTJOBEXP); - pl_sd->status.skill_point += level; + + if (pl_sd->status.skill_point > USHRT_MAX - level) + pl_sd->status.skill_point = USHRT_MAX; + else + pl_sd->status.skill_point += level; clif_updatestatus(pl_sd, SP_SKILLPOINT); status_calc_pc(pl_sd, 0); clif_misceffect(&pl_sd->bl, 1); @@ -1389,9 +1399,10 @@ int charcommand_joblevel( clif_updatestatus(pl_sd, SP_NEXTJOBEXP); if (pl_sd->status.skill_point < level) pc_resetskill(pl_sd, 0); //Need more skill points to substract - pl_sd->status.skill_point -= level; - if (pl_sd->status.skill_point < 0) + if (pl_sd->status.skill_point < level) pl_sd->status.skill_point = 0; + else + pl_sd->status.skill_point -= level; clif_updatestatus(pl_sd, SP_SKILLPOINT); status_calc_pc(pl_sd, 0); clif_displaymessage(fd, msg_table[69]); // Character's job level lowered. @@ -1642,11 +1653,12 @@ int charcommand_skpoint( } if ((pl_sd = map_nick2sd(player)) != NULL) { - new_skill_point = (int)pl_sd->status.skill_point + point; - if (point > 0 && (point > 0x7FFF || new_skill_point > 0x7FFF)) // fix positiv overflow - new_skill_point = 0x7FFF; - else if (point < 0 && (point < -0x7FFF || new_skill_point < 0)) // fix negativ overflow + if (point > 0 && pl_sd->status.skill_point > USHRT_MAX - point) + new_skill_point = USHRT_MAX; + else if (point < 0 && pl_sd->status.skill_point < -point) new_skill_point = 0; + else + new_skill_point = pl_sd->status.skill_point + point; if (new_skill_point != (int)pl_sd->status.skill_point) { pl_sd->status.skill_point = new_skill_point; clif_updatestatus(pl_sd, SP_SKILLPOINT); @@ -1686,11 +1698,12 @@ int charcommand_stpoint( } if ((pl_sd = map_nick2sd(player)) != NULL) { - new_status_point = (int)pl_sd->status.status_point + point; - if (point > 0 && (point > 0x7FFF || new_status_point > 0x7FFF)) // fix positiv overflow - new_status_point = 0x7FFF; - else if (point < 0 && (point < -0x7FFF || new_status_point < 0)) // fix negativ overflow + if (point > 0 && pl_sd->status.status_point > USHRT_MAX - point) + new_status_point = USHRT_MAX; + else if (point < 0 && pl_sd->status.status_point < -point) new_status_point = 0; + else + new_status_point = pl_sd->status.status_point + point; if (new_status_point != (int)pl_sd->status.status_point) { pl_sd->status.status_point = new_status_point; clif_updatestatus(pl_sd, SP_STATUSPOINT); diff --git a/src/map/charsave.c b/src/map/charsave.c index aa066d1e6..4551b2787 100644 --- a/src/map/charsave.c +++ b/src/map/charsave.c @@ -74,8 +74,8 @@ struct mmo_charstatus *charsave_loadchar(int charid){ c->hp = atoi(charsql_row[17]); c->max_sp = atoi(charsql_row[18]); c->sp = atoi(charsql_row[19]); - c->status_point = atoi(charsql_row[20]); - c->skill_point = atoi(charsql_row[21]); + c->status_point = atoi(charsql_row[20]) > USHRT_MAX? USHRT_MAX : atoi(charsql_row[20]); + c->skill_point = atoi(charsql_row[21]) > USHRT_MAX? USHRT_MAX : atoi(charsql_row[21]); c->option = atoi(charsql_row[22]); c->karma = atoi(charsql_row[23]); c->manner = atoi(charsql_row[24]); diff --git a/src/map/chrif.c b/src/map/chrif.c index 06b1946cc..3a11222fb 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -861,7 +861,10 @@ int chrif_changedsex(int fd) // remove specifical skills of Bard classes for(i = 315; i <= 322; i++) { if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) { - sd->status.skill_point += sd->status.skill[i].lv; + if (sd->status.skill_point > USHRT_MAX - sd->status.skill[i].lv) + sd->status.skill_point = USHRT_MAX; + else + sd->status.skill_point += sd->status.skill[i].lv; sd->status.skill[i].id = 0; sd->status.skill[i].lv = 0; } @@ -869,7 +872,10 @@ int chrif_changedsex(int fd) // remove specifical skills of Dancer classes for(i = 323; i <= 330; i++) { if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) { - sd->status.skill_point += sd->status.skill[i].lv; + if (sd->status.skill_point > USHRT_MAX - sd->status.skill[i].lv) + sd->status.skill_point = USHRT_MAX; + else + sd->status.skill_point += sd->status.skill[i].lv; sd->status.skill[i].id = 0; sd->status.skill[i].lv = 0; } diff --git a/src/map/clif.c b/src/map/clif.c index 3a85618d6..1e7f6baa9 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -3351,18 +3351,18 @@ int clif_initialstatus(struct map_session_data *sd) buf=WFIFOP(fd,0); WBUFW(buf,0)=0xbd; - WBUFW(buf,2)=sd->status.status_point; - WBUFB(buf,4)=(sd->status.str > 255)? 255:sd->status.str; + WBUFW(buf,2)=(sd->status.status_point > SHRT_MAX)? SHRT_MAX:sd->status.status_point; + WBUFB(buf,4)=(sd->status.str > UCHAR_MAX)? UCHAR_MAX:sd->status.str; WBUFB(buf,5)=pc_need_status_point(sd,SP_STR); - WBUFB(buf,6)=(sd->status.agi > 255)? 255:sd->status.agi; + WBUFB(buf,6)=(sd->status.agi > UCHAR_MAX)? UCHAR_MAX:sd->status.agi; WBUFB(buf,7)=pc_need_status_point(sd,SP_AGI); - WBUFB(buf,8)=(sd->status.vit > 255)? 255:sd->status.vit; + WBUFB(buf,8)=(sd->status.vit > UCHAR_MAX)? UCHAR_MAX:sd->status.vit; WBUFB(buf,9)=pc_need_status_point(sd,SP_VIT); - WBUFB(buf,10)=(sd->status.int_ > 255)? 255:sd->status.int_; + WBUFB(buf,10)=(sd->status.int_ > UCHAR_MAX)? UCHAR_MAX:sd->status.int_; WBUFB(buf,11)=pc_need_status_point(sd,SP_INT); - WBUFB(buf,12)=(sd->status.dex > 255)? 255:sd->status.dex; + WBUFB(buf,12)=(sd->status.dex > UCHAR_MAX)? UCHAR_MAX:sd->status.dex; WBUFB(buf,13)=pc_need_status_point(sd,SP_DEX); - WBUFB(buf,14)=(sd->status.luk > 255)? 255:sd->status.luk; + WBUFB(buf,14)=(sd->status.luk > UCHAR_MAX)? UCHAR_MAX:sd->status.luk; WBUFB(buf,15)=pc_need_status_point(sd,SP_LUK); WBUFW(buf,16) = sd->base_atk + sd->right_weapon.watk + sd->left_weapon.watk; diff --git a/src/map/pc.c b/src/map/pc.c index a812fc8b2..95aab502f 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -3871,13 +3871,13 @@ int pc_checkbaselevelup(struct map_session_data *sd) if (battle_config.pet_lv_rate && sd->pd) // update pet's level status_calc_pet(sd,0); if (battle_config.use_statpoint_table) - { // Taken from pc_resetstate. [Skotlex] - int lv = sd->status.base_level; - if (lv >= MAX_LEVEL) lv = MAX_LEVEL - 1; - else if (lv < 1) lv = 1; - sd->status.status_point += statp[lv] - statp[lv-1]; - } else //Estimated way. - sd->status.status_point += (sd->status.base_level+14) / 5 ; + next = statp[sd->status.base_level] - statp[sd->status.base_level-1]; + else //Estimated way. + next = (sd->status.base_level+14) / 5 ; + if (sd->status.status_point > USHRT_MAX - next) + sd->status.status_point = USHRT_MAX; + else + sd->status.status_point += next; clif_updatestatus(sd,SP_STATUSPOINT); clif_updatestatus(sd,SP_BASELEVEL); clif_updatestatus(sd,SP_NEXTBASEEXP); @@ -4422,13 +4422,14 @@ int pc_resetstate(struct map_session_data* sd) if (battle_config.use_statpoint_table) { // New statpoint table used here - Dexity - int lv; - // allow it to just read the last entry [celest] - lv = sd->status.base_level < MAX_LEVEL ? sd->status.base_level : MAX_LEVEL - 1; - - sd->status.status_point = statp[lv]; + int stat; + stat = statp[sd->status.base_level]; if (sd->class_&JOBL_UPPER) sd->status.status_point+=52; // extra 52+48=100 stat points + if (stat > USHRT_MAX) + sd->status.status_point = USHRT_MAX; + else + sd->status.status_point = stat; } else { //Use new stat-calculating equation [Skotlex] #define sumsp(a) (((a-1)/10 +2)*(5*((a-1)/10 +1) + (a-1)%10) -10) int add=0; @@ -4438,8 +4439,8 @@ int pc_resetstate(struct map_session_data* sd) add += sumsp(sd->status.int_); add += sumsp(sd->status.dex); add += sumsp(sd->status.luk); - if (add > SHRT_MAX - sd->status.status_point) - sd->status.status_point = SHRT_MAX; + if (add > USHRT_MAX - sd->status.status_point) + sd->status.status_point = USHRT_MAX; else sd->status.status_point+=add; } @@ -4478,7 +4479,7 @@ int pc_resetstate(struct map_session_data* sd) */ int pc_resetskill(struct map_session_data* sd, int flag) { - int i, skill, inf2; + int i, skill, inf2, skill_point=0; nullpo_retr(0, sd); if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd)) @@ -4491,9 +4492,9 @@ int pc_resetskill(struct map_session_data* sd, int flag) !(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL))) //Avoid reseting wedding/linker skills. { if (!sd->status.skill[i].flag) - sd->status.skill_point += skill; + skill_point += skill; else if (sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13) - sd->status.skill_point += (sd->status.skill[i].flag - 2); + skill_point += (sd->status.skill[i].flag - 2); sd->status.skill[i].lv = 0; sd->status.skill[i].flag = 0; } @@ -4506,6 +4507,12 @@ int pc_resetskill(struct map_session_data* sd, int flag) sd->status.skill[i].lv = 0; } } + + if (sd->status.skill_point > USHRT_MAX - skill_point) + sd->status.skill_point = USHRT_MAX; + else + sd->status.skill_point += skill_point; + if (flag) { clif_updatestatus(sd,SP_SKILLPOINT); clif_skillinfoblock(sd); @@ -5085,8 +5092,14 @@ int pc_setparam(struct map_session_data *sd,int type,int val) if ((unsigned int)val > pc_maxbaselv(sd)) //Capping to max val = pc_maxbaselv(sd); if ((unsigned int)val > sd->status.base_level) { + int stat=0; for (i = 1; i <= (int)((unsigned int)val - sd->status.base_level); i++) - sd->status.status_point += (sd->status.base_level + i + 14) / 5 ; + stat += (sd->status.base_level + i + 14) / 5 ; + if (sd->status.status_point > USHRT_MAX - stat) + + sd->status.status_point = USHRT_MAX; + else + sd->status.status_point += stat; } sd->status.base_level = (unsigned int)val; sd->status.base_exp = 0; @@ -5100,7 +5113,10 @@ int pc_setparam(struct map_session_data *sd,int type,int val) case SP_JOBLEVEL: if ((unsigned int)val >= sd->status.job_level) { if ((unsigned int)val > pc_maxjoblv(sd)) val = pc_maxjoblv(sd); - sd->status.skill_point += ((unsigned int)val-sd->status.job_level); + if (sd->status.skill_point > USHRT_MAX - val + sd->status.job_level) + sd->status.skill_point = USHRT_MAX; + else + sd->status.skill_point += val-sd->status.job_level; clif_updatestatus(sd, SP_SKILLPOINT); clif_misceffect(&sd->bl, 1); } -- cgit v1.2.3-70-g09d2