From 48a4ecf0b4a277fc2aef90b8ec66fa27fe1c3375 Mon Sep 17 00:00:00 2001 From: Edoardo Lolletti Date: Thu, 21 Dec 2023 21:58:07 +0100 Subject: [PATCH] Fix possible crash in IsPlayerCanDiscardDeckAsCost with count of 0 If 0 was passed as count, and the checked player had no cards in his deck, and a EFFECT_TO_GRAVE_REDIRECT was applied, the core would've crashed --- field.cpp | 10 ++++++---- field.h | 4 ++-- libduel.cpp | 7 ++----- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/field.cpp b/field.cpp index 0f8584a4..9765557c 100644 --- a/field.cpp +++ b/field.cpp @@ -2618,16 +2618,18 @@ int32_t field::check_with_sum_greater_limit_m(const card_vector& mats, int32_t a int32_t field::is_player_can_draw(uint8_t playerid) { return !is_player_affected_by_effect(playerid, EFFECT_CANNOT_DRAW); } -int32_t field::is_player_can_discard_deck(uint8_t playerid, int32_t count) { - if(player[playerid].list_main.size() < (uint32_t)count) +int32_t field::is_player_can_discard_deck(uint8_t playerid, uint32_t count) { + if(player[playerid].list_main.size() < count) return FALSE; return !is_player_affected_by_effect(playerid, EFFECT_CANNOT_DISCARD_DECK); } -int32_t field::is_player_can_discard_deck_as_cost(uint8_t playerid, int32_t count) { - if(player[playerid].list_main.size() < (uint32_t)count) +int32_t field::is_player_can_discard_deck_as_cost(uint8_t playerid, uint32_t count) { + if(player[playerid].list_main.size() < count) return FALSE; if(is_player_affected_by_effect(playerid, EFFECT_CANNOT_DISCARD_DECK)) return FALSE; + if(player[playerid].list_main.empty()) + return TRUE; card* topcard = player[playerid].list_main.back(); if((count == 1) && topcard->is_position(POS_FACEUP)) return topcard->is_capable_cost_to_grave(playerid); diff --git a/field.h b/field.h index 6f9748b5..c9371ce2 100644 --- a/field.h +++ b/field.h @@ -529,8 +529,8 @@ class field { static int32_t check_with_sum_greater_limit_m(const card_vector& mats, int32_t acc, int32_t index, int32_t opmin, int32_t must_count, int32_t* should_continue); int32_t is_player_can_draw(uint8_t playerid); - int32_t is_player_can_discard_deck(uint8_t playerid, int32_t count); - int32_t is_player_can_discard_deck_as_cost(uint8_t playerid, int32_t count); + int32_t is_player_can_discard_deck(uint8_t playerid, uint32_t count); + int32_t is_player_can_discard_deck_as_cost(uint8_t playerid, uint32_t count); int32_t is_player_can_discard_hand(uint8_t playerid, card* pcard, effect* peffect, uint32_t reason); int32_t is_player_can_action(uint8_t playerid, uint32_t actionlimit); int32_t is_player_can_summon(uint32_t sumtype, uint8_t playerid, card* pcard, uint8_t toplayer); diff --git a/libduel.cpp b/libduel.cpp index ab34a3ca..90f4358b 100644 --- a/libduel.cpp +++ b/libduel.cpp @@ -3596,11 +3596,8 @@ LUA_STATIC_FUNCTION(IsPlayerCanDraw) { return 1; } auto count = lua_get(L, 2); - if(count == 0) - lua_pushboolean(L, pduel->game_field->is_player_can_draw(playerid)); - else - lua_pushboolean(L, pduel->game_field->is_player_can_draw(playerid) - && (pduel->game_field->player[playerid].list_main.size() >= count)); + lua_pushboolean(L, pduel->game_field->is_player_can_draw(playerid) + && (pduel->game_field->player[playerid].list_main.size() >= count)); return 1; } LUA_STATIC_FUNCTION(IsPlayerCanDiscardDeck) {