浏览代码

Fixed potential race-condition possibility in cart item transaction (#4139)


Co-authored-by: Cydh Ramdh <cydh@users.noreply.github.com>
Co-Authored-By: Aleos <aleos89@users.noreply.github.com>
Jittapan Pluemsumran 6 年之前
父节点
当前提交
7f772c32d3
共有 1 个文件被更改,包括 13 次插入9 次删除
  1. 13 9
      src/map/pc.cpp

+ 13 - 9
src/map/pc.cpp

@@ -5447,7 +5447,7 @@ void pc_putitemtocart(struct map_session_data *sd,int idx,int amount)
 
 	item_data = &sd->inventory.u.items_inventory[idx];
 
-	if( item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->state.vending )
+	if( item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->state.vending || sd->state.prevend )
 		return;
 
 	if( item_data->equipSwitch ){
@@ -5487,21 +5487,25 @@ int pc_cartitem_amount(struct map_session_data* sd, int idx, int amount)
  *------------------------------------------*/
 void pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
 {
-	struct item *item_data;
-	unsigned char flag = 0;
-
 	nullpo_retv(sd);
 
 	if (idx < 0 || idx >= MAX_CART) //Invalid index check [Skotlex]
 		return;
 
-	item_data=&sd->cart.u.items_cart[idx];
+	item* item_data=&sd->cart.u.items_cart[idx];
 
-	if(item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->state.vending )
+	if (item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->state.vending || sd->state.prevend)
 		return;
-	if((flag = pc_additem(sd,item_data,amount,LOG_TYPE_NONE)) == 0)
-		pc_cart_delitem(sd,idx,amount,0,LOG_TYPE_NONE);
-	else {
+
+	if (pc_checkadditem(sd, item_data->nameid, amount) == CHKADDITEM_OVERAMOUNT) {
+		return;
+	}
+
+	item item_copy = *item_data;
+
+	pc_cart_delitem(sd, idx, amount, 0, LOG_TYPE_NONE);
+	char flag = pc_additem(sd, &item_copy, amount, LOG_TYPE_NONE);
+	if(flag != ADDITEM_SUCCESS) {
 		clif_dropitem(sd,idx,0);
 		clif_additem(sd,0,0,flag);
 	}