summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-03-27 01:24:34 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-03-27 01:24:34 +0000
commit3633262bf2d8db0dd3bd51370826120371aac4a0 (patch)
treec5ae0b332226049181786cbbd3d13515d2cd2491 /src/map
parentad74cd5605eb1d0d4e774216dd62b471a9721cbe (diff)
downloadhercules-3633262bf2d8db0dd3bd51370826120371aac4a0.tar.gz
hercules-3633262bf2d8db0dd3bd51370826120371aac4a0.tar.bz2
hercules-3633262bf2d8db0dd3bd51370826120371aac4a0.tar.xz
hercules-3633262bf2d8db0dd3bd51370826120371aac4a0.zip
- 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
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c51
-rw-r--r--src/map/charcommand.c43
-rw-r--r--src/map/charsave.c4
-rw-r--r--src/map/chrif.c10
-rw-r--r--src/map/clif.c14
-rw-r--r--src/map/pc.c54
6 files changed, 112 insertions, 64 deletions
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) //<Skotlex> 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);
}