OSDN Git Service

[Fix] 呪術と歌の詠唱時の配列範囲外アクセス
authorHabu <habu1010+github@gmail.com>
Sun, 11 Jun 2023 05:41:37 +0000 (14:41 +0900)
committerHabu <habu1010+github@gmail.com>
Sun, 11 Jun 2023 10:48:08 +0000 (19:48 +0900)
呪術と歌を詠唱した時、誤ってmp_ptr->infoの要素にアクセスしているため配列
範囲外アクセスが発生する。
呪術と歌の時は正しいtechnic_infoの要素にアクセスするよう修正する。

src/player/player-skill.cpp

index 596614c..d8e30c5 100644 (file)
@@ -4,6 +4,7 @@
 #include "player-base/player-race.h"
 #include "player-info/class-info.h"
 #include "player/player-realm.h"
+#include "realm/realm-names-table.h"
 #include "sv-definition/sv-weapon-types.h"
 #include "system/floor-type-definition.h"
 #include "system/item-entity.h"
@@ -352,12 +353,12 @@ void PlayerSkill::gain_riding_skill_exp_on_fall_off_check(int dam)
 
 void PlayerSkill::gain_spell_skill_exp(int realm, int spell_idx)
 {
-    if ((realm < 1) || ((static_cast<int>(std::size(mp_ptr->info)) < realm) && (realm != REALM_MUSIC) && (realm != REALM_HEX))) {
-        return;
-    }
+    auto is_valid_realm = is_magic(realm) ||
+                          (realm == REALM_MUSIC) || (realm == REALM_HEX);
+    is_valid_realm &= (realm == this->player_ptr->realm1) || (realm == this->player_ptr->realm2);
+    const auto is_valid_spell_idx = (0 <= spell_idx) && (spell_idx < 32);
 
-    if (((spell_idx < 0) || (32 <= spell_idx)) ||
-        ((realm != this->player_ptr->realm1) && (realm != this->player_ptr->realm2))) {
+    if (!is_valid_realm || !is_valid_spell_idx) {
         return;
     }
 
@@ -365,7 +366,7 @@ void PlayerSkill::gain_spell_skill_exp(int realm, int spell_idx)
     constexpr GainAmountList gain_amount_list_second{ { 60, 8, 2, 0 } };
 
     const auto is_first_realm = (realm == this->player_ptr->realm1);
-    const auto *s_ptr = &mp_ptr->info[realm - 1][spell_idx];
+    const auto *s_ptr = is_magic(realm) ? &mp_ptr->info[realm - 1][spell_idx] : &technic_info[realm - MIN_TECHNIC][spell_idx];
 
     gain_spell_skill_exp_aux(this->player_ptr, this->player_ptr->spell_exp[spell_idx + (is_first_realm ? 0 : 32)],
         (is_first_realm ? gain_amount_list_first : gain_amount_list_second), s_ptr->slevel);