summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglighta <glighta@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-11-14 02:26:00 +0000
committerglighta <glighta@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-11-14 02:26:00 +0000
commit4e406f3ed6e6f8b2b8434a366a5e54c8f7186f45 (patch)
treeae5f4769d161f5693f94e95b1623909a3d75eaf9
parentdc88ae10c96b5d5d9d40fccbb102f1ec80058063 (diff)
downloadhercules-4e406f3ed6e6f8b2b8434a366a5e54c8f7186f45.tar.gz
hercules-4e406f3ed6e6f8b2b8434a366a5e54c8f7186f45.tar.bz2
hercules-4e406f3ed6e6f8b2b8434a366a5e54c8f7186f45.tar.xz
hercules-4e406f3ed6e6f8b2b8434a366a5e54c8f7186f45.zip
Following r16914
-fix @zeny for negative amout bugreport:6886, bugreport:6895 bugreport:6888 -fix @cash,@points command display result -enforce bound chk for both git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16924 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r--src/map/atcommand.c47
-rw-r--r--src/map/intif.c2
-rw-r--r--src/map/mail.c1
-rw-r--r--src/map/party.c2
-rw-r--r--src/map/pc.c21
-rw-r--r--src/map/pc.h4
-rw-r--r--src/map/trade.c49
7 files changed, 76 insertions, 50 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 27329ae4a..891fb1a79 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -2522,7 +2522,7 @@ ACMD_FUNC(skillpoint)
}
/*==========================================
- * @zeny (Rewritten by [Yor])
+ * @zeny
*------------------------------------------*/
ACMD_FUNC(zeny)
{
@@ -2533,10 +2533,14 @@ ACMD_FUNC(zeny)
clif_displaymessage(fd, msg_txt(1012)); // Please enter an amount (usage: @zeny <amount>).
return -1;
}
- if(zeny > 0)
- pc_getzeny(sd,zeny,LOG_TYPE_COMMAND,NULL);
- else
- pc_payzeny(sd,zeny,LOG_TYPE_COMMAND,NULL);
+
+ if(zeny > 0){
+ if(pc_getzeny(sd,zeny,LOG_TYPE_COMMAND,NULL) == 1)
+ clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
+ }
+ else if(pc_payzeny(sd,-zeny,LOG_TYPE_COMMAND,NULL) == 1){
+ clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
+ }
return 0;
}
@@ -7858,6 +7862,7 @@ ACMD_FUNC(cash)
{
char output[128];
int value;
+ int ret=0;
nullpo_retr(-1, sd);
if( !message || !*message || (value = atoi(message)) == 0 ) {
@@ -7868,25 +7873,33 @@ ACMD_FUNC(cash)
if( !strcmpi(command+1,"cash") )
{
if( value > 0 ) {
- pc_getcash(sd, value, 0);
- sprintf(output, msg_txt(505), value, sd->cashPoints);
- clif_disp_onlyself(sd, output, strlen(output));
+ if( (ret=pc_getcash(sd, value, 0)) >= 0){
+ sprintf(output, msg_txt(505), ret, sd->cashPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ else clif_displaymessage(fd, msg_txt(149)); // Unable to decrease the number/value.
} else {
- pc_paycash(sd, -value, 0);
- sprintf(output, msg_txt(410), value, sd->cashPoints);
- clif_disp_onlyself(sd, output, strlen(output));
+ if( (ret=pc_paycash(sd, -value, 0)) >= 0){
+ sprintf(output, msg_txt(410), ret, sd->cashPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ else clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
}
}
else
{ // @points
if( value > 0 ) {
- pc_getcash(sd, 0, value);
- sprintf(output, msg_txt(506), value, sd->kafraPoints);
- clif_disp_onlyself(sd, output, strlen(output));
+ if( (ret=pc_getcash(sd, 0, value)) >= 0){
+ sprintf(output, msg_txt(506), ret, sd->kafraPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ else clif_displaymessage(fd, msg_txt(149)); // Unable to decrease the number/value.
} else {
- pc_paycash(sd, -value, -value);
- sprintf(output, msg_txt(411), -value, sd->kafraPoints);
- clif_disp_onlyself(sd, output, strlen(output));
+ if( (ret=pc_paycash(sd, -value, -value)) >= 0){
+ sprintf(output, msg_txt(411), ret, sd->kafraPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ else clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
}
}
diff --git a/src/map/intif.c b/src/map/intif.c
index a06334e77..3bbb92216 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -1827,7 +1827,7 @@ static void intif_parse_Auction_register(int fd)
clif_Auction_message(sd->fd, 4);
pc_additem(sd, &auction.item, auction.item.amount, LOG_TYPE_AUCTION);
- pc_getzeny(sd, zeny, LOG_TYPE_AUCTION,NULL);
+ pc_getzeny(sd, zeny, LOG_TYPE_AUCTION, NULL);
}
}
diff --git a/src/map/mail.c b/src/map/mail.c
index 62d046ea4..03b8227b5 100644
--- a/src/map/mail.c
+++ b/src/map/mail.c
@@ -51,7 +51,6 @@ int mail_removezeny(struct map_session_data *sd, short flag)
pc_payzeny(sd,sd->mail.zeny,LOG_TYPE_MAIL, NULL);
}
sd->mail.zeny = 0;
- clif_updatestatus(sd, SP_ZENY);
return 1;
}
diff --git a/src/map/party.c b/src/map/party.c
index dfcae5421..f7a2ebc6a 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -949,7 +949,7 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b
pc_gainexp(sd[i], src, base_exp, job_exp, false);
if (zeny) // zeny from mobs [Valaris]
- pc_getzeny(sd[i],zeny,LOG_TYPE_OTHER,NULL);
+ pc_getzeny(sd[i],zeny,LOG_TYPE_PICKDROP_MONSTER,NULL);
}
return 0;
}
diff --git a/src/map/pc.c b/src/map/pc.c
index 986087484..b54b88ae2 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -3590,6 +3590,7 @@ int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
{
nullpo_ret(sd);
+ zeny = cap_value(zeny,-MAX_ZENY,MAX_ZENY); //prevent command UB
if( zeny < 0 )
{
ShowError("pc_payzeny: Paying negative Zeny (zeny=%d, account_id=%d, char_id=%d).\n", zeny, sd->status.account_id, sd->status.char_id);
@@ -3616,16 +3617,17 @@ int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
* Cash Shop
*------------------------------------------*/
-void pc_paycash(struct map_session_data *sd, int price, int points)
+int pc_paycash(struct map_session_data *sd, int price, int points)
{
char output[128];
int cash;
nullpo_retv(sd);
+ points = cap_value(points,-MAX_ZENY,MAX_ZENY); //prevent command UB
if( price < 0 || points < 0 )
{
ShowError("pc_paycash: Paying negative points (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id);
- return;
+ return -2;
}
if( points > price )
@@ -3639,7 +3641,7 @@ void pc_paycash(struct map_session_data *sd, int price, int points)
if( sd->cashPoints < cash || sd->kafraPoints < points )
{
ShowError("pc_paycash: Not enough points (cash=%d, kafra=%d) to cover the price (cash=%d, kafra=%d) (account_id=%d, char_id=%d).\n", sd->cashPoints, sd->kafraPoints, cash, points, sd->status.account_id, sd->status.char_id);
- return;
+ return -1;
}
pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints-cash);
@@ -3650,13 +3652,16 @@ void pc_paycash(struct map_session_data *sd, int price, int points)
sprintf(output, msg_txt(504), points, cash, sd->kafraPoints, sd->cashPoints);
clif_disp_onlyself(sd, output, strlen(output));
}
+ return cash+points;
}
-void pc_getcash(struct map_session_data *sd, int cash, int points)
+int pc_getcash(struct map_session_data *sd, int cash, int points)
{
char output[128];
nullpo_retv(sd);
+ cash = cap_value(cash,-MAX_ZENY,MAX_ZENY); //prevent command UB
+ points = cap_value(points,-MAX_ZENY,MAX_ZENY); //prevent command UB
if( cash > 0 )
{
if( cash > MAX_ZENY-sd->cashPoints )
@@ -3672,10 +3677,12 @@ void pc_getcash(struct map_session_data *sd, int cash, int points)
sprintf(output, msg_txt(505), cash, sd->cashPoints);
clif_disp_onlyself(sd, output, strlen(output));
}
+ return cash;
}
else if( cash < 0 )
{
ShowError("pc_getcash: Obtaining negative cash points (cash=%d, account_id=%d, char_id=%d).\n", cash, sd->status.account_id, sd->status.char_id);
+ return -1;
}
if( points > 0 )
@@ -3693,11 +3700,14 @@ void pc_getcash(struct map_session_data *sd, int cash, int points)
sprintf(output, msg_txt(506), points, sd->kafraPoints);
clif_disp_onlyself(sd, output, strlen(output));
}
+ return points;
}
else if( points < 0 )
{
ShowError("pc_getcash: Obtaining negative kafra points (points=%d, account_id=%d, char_id=%d).\n", points, sd->status.account_id, sd->status.char_id);
+ return -1;
}
+ return -2; //shouldn't happen but jsut in case
}
/*==========================================
@@ -3708,6 +3718,7 @@ int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
{
nullpo_ret(sd);
+ zeny = cap_value(zeny,-MAX_ZENY,MAX_ZENY); //prevent command UB
if( zeny < 0 )
{
ShowError("pc_getzeny: Obtaining negative Zeny (zeny=%d, account_id=%d, char_id=%d).\n", zeny, sd->status.account_id, sd->status.char_id);
@@ -3720,7 +3731,7 @@ int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
sd->status.zeny += zeny;
clif_updatestatus(sd,SP_ZENY);
- if(!sd) tsd = sd;
+ if(!tsd) tsd = sd;
log_zeny(sd, type, tsd, zeny);
if( zeny > 0 && sd->state.showzeny ) {
char output[255];
diff --git a/src/map/pc.h b/src/map/pc.h
index 1cc81eb9c..bc8a76f2a 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -701,8 +701,8 @@ int pc_getzeny(struct map_session_data*,int, enum e_log_pick_type, struct map_se
int pc_delitem(struct map_session_data*,int,int,int,short,e_log_pick_type);
// Special Shop System
-void pc_paycash(struct map_session_data *sd, int price, int points);
-void pc_getcash(struct map_session_data *sd, int cash, int points);
+int pc_paycash(struct map_session_data *sd, int price, int points);
+int pc_getcash(struct map_session_data *sd, int cash, int points);
int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type);
int pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type,e_log_pick_type log_type);
diff --git a/src/map/trade.c b/src/map/trade.c
index ac23b047e..0d01b54a6 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -74,15 +74,15 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta
clif_displaymessage(sd->fd, msg_txt(246));
clif_tradestart(sd, 2); // GM is not allowed to trade
return;
- }
-
+ }
+
// Players can not request trade from far away, unless they are allowed to use @trade.
if (!pc_can_use_command(sd, "trade", COMMAND_ATCOMMAND) &&
(sd->bl.m != target_sd->bl.m || !check_distance_bl(&sd->bl, &target_sd->bl, TRADE_DISTANCE))) {
clif_tradestart(sd, 0); // too far
return ;
}
-
+
target_sd->trade_partner = sd->status.account_id;
sd->trade_partner = target_sd->status.account_id;
clif_traderequest(target_sd, sd->status.name);
@@ -106,7 +106,7 @@ void trade_tradeack(struct map_session_data *sd, int type)
if (sd->state.trading || !sd->trade_partner)
return; //Already trading or no partner set.
-
+
if ((tsd = map_id2sd(sd->trade_partner)) == NULL) {
clif_tradestart(sd, 1); // character does not exist
sd->trade_partner=0;
@@ -177,7 +177,7 @@ int impossible_trade_check(struct map_session_data *sd)
int i, index;
nullpo_retr(1, sd);
-
+
if(sd->deal.zeny > sd->status.zeny)
{
pc_setglobalreg(sd,"ZENY_HACKER",1);
@@ -220,7 +220,7 @@ int impossible_trade_check(struct map_session_data *sd)
} else
// message about the ban
strcpy(message_to_gm, msg_txt(508)); // This player hasn't been banned (Ban option is disabled).
-
+
intif_wis_message_to_gm(wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
return 1;
}
@@ -257,7 +257,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
n = sd->deal.item[trade_i].index;
if (amount > inventory[n].amount)
return 0; //qty Exploit?
-
+
data = itemdb_search(inventory[n].nameid);
i = MAX_INVENTORY;
if (itemdb_isstackable2(data)) { //Stackable item.
@@ -272,7 +272,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
break;
}
}
-
+
if (i == MAX_INVENTORY) {// look for an empty slot.
for(i = 0; i < MAX_INVENTORY && inventory2[i].nameid; i++);
if (i == MAX_INVENTORY)
@@ -439,7 +439,7 @@ void trade_tradeok(struct map_session_data *sd)
if(sd->state.deal_locked || !sd->state.trading)
return;
-
+
if ((target_sd = map_id2sd(sd->trade_partner)) == NULL) {
trade_tradecancel(sd);
return;
@@ -470,7 +470,7 @@ void trade_tradecancel(struct map_session_data *sd)
clif_tradecancelled(sd);
return;
}
-
+
for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual)
if (!sd->deal.item[trade_i].amount)
continue;
@@ -498,7 +498,7 @@ void trade_tradecancel(struct map_session_data *sd)
target_sd->deal.item[trade_i].index = 0;
target_sd->deal.item[trade_i].amount = 0;
}
-
+
if (target_sd->deal.zeny) {
clif_updatestatus(target_sd, SP_ZENY);
target_sd->deal.zeny = 0;
@@ -525,9 +525,9 @@ void trade_tradecommit(struct map_session_data *sd)
trade_tradecancel(sd);
return;
}
-
+
sd->state.deal_locked = 2;
-
+
if (tsd->state.deal_locked < 2)
return; //Not yet time for trading.
@@ -547,7 +547,7 @@ void trade_tradecommit(struct map_session_data *sd)
trade_tradecancel(sd);
return;
}
-
+
// trade is accepted and correct.
for( trade_i = 0; trade_i < 10; trade_i++ )
{
@@ -578,30 +578,33 @@ void trade_tradecommit(struct map_session_data *sd)
}
}
- if( sd->deal.zeny || tsd->deal.zeny )
- {
- pc_getzeny(sd,tsd->deal.zeny - sd->deal.zeny,LOG_TYPE_TRADE, tsd);
- pc_getzeny(tsd,sd->deal.zeny - tsd->deal.zeny,LOG_TYPE_TRADE, sd);
-
+ if( sd->deal.zeny ) {
+ pc_payzeny(sd ,sd->deal.zeny, LOG_TYPE_TRADE, tsd);
+ pc_getzeny(tsd,sd->deal.zeny,LOG_TYPE_TRADE, sd);
sd->deal.zeny = 0;
+
+ }
+ if ( tsd->deal.zeny) {
+ pc_payzeny(tsd,tsd->deal.zeny,LOG_TYPE_TRADE, sd);
+ pc_getzeny(sd ,tsd->deal.zeny,LOG_TYPE_TRADE, tsd);
tsd->deal.zeny = 0;
}
-
+
sd->state.deal_locked = 0;
sd->trade_partner = 0;
sd->state.trading = 0;
-
+
tsd->state.deal_locked = 0;
tsd->trade_partner = 0;
tsd->state.trading = 0;
-
+
clif_tradecompleted(sd, 0);
clif_tradecompleted(tsd, 0);
// save both player to avoid crash: they always have no advantage/disadvantage between the 2 players
if (save_settings&1)
{
- chrif_save(sd,0);
+ chrif_save(sd,0);
chrif_save(tsd,0);
}
}