OSDN Git Service

[Fix] prf経由で長すぎる銘を刻むとメモリが破壊される
authordis- <dis.rogue@gmail.com>
Sun, 19 Dec 2021 13:23:51 +0000 (22:23 +0900)
committerdis- <dis.rogue@gmail.com>
Mon, 20 Dec 2021 13:21:26 +0000 (22:21 +0900)
Issue #1923の件。
prfファイルから設定できる自動銘刻みとゲーム中{コマンドから刻む銘の文字数上限に違いがあり、確保している領域の差からバッファオーバーフローが発生する問題。
{コマンドで書き込める文字数を上限とし、prf経由の長すぎる銘は後半を無視する。
日本語版76バイト、英語版69バイトを上限とする。

src/autopick/autopick-describer.cpp
src/cmd-item/cmd-item.cpp
src/flavor/flavor-util.cpp
src/system/h-type.h
src/window/display-sub-window-items.cpp

index 3bf5147..f0beae8 100644 (file)
@@ -210,7 +210,7 @@ static void describe_autpick_jp(char *buff, autopick_type *entry, autopick_descr
         }
 
         strcat(buff, "で、名前が「");
-        strncat(buff, describer->str, 80);
+        angband_strcat(buff, describer->str, (MAX_NLEN - MAX_INSCRIPTION));
         if (describer->top)
             strcat(buff, "」で始まるもの");
         else
@@ -218,7 +218,9 @@ static void describe_autpick_jp(char *buff, autopick_type *entry, autopick_descr
     }
 
     if (describer->insc) {
-        strncat(buff, format("に「%s」", describer->insc), 80);
+        char tmp[MAX_INSCRIPTION + 1] = "";
+        angband_strcat(tmp, describer->insc, MAX_INSCRIPTION);
+        angband_strcat(buff, format("に「%s」", tmp), MAX_INSCRIPTION + 6);
 
         if (angband_strstr(describer->insc, "%%all"))
             strcat(buff, "(%%allは全能力を表す英字の記号で置換)");
index 6e2d42b..5953b32 100644 (file)
@@ -66,6 +66,7 @@
 #include "util/bit-flags-calculator.h"
 #include "util/int-char-converter.h"
 #include "util/quarks.h"
+#include "util/string-processor.h"
 #include "view/display-inventory.h"
 #include "view/display-messages.h"
 
@@ -201,7 +202,7 @@ void do_cmd_inscribe(PlayerType *player_ptr)
     OBJECT_IDX item;
     object_type *o_ptr;
     GAME_TEXT o_name[MAX_NLEN];
-    char out_val[80];
+    char out_val[MAX_INSCRIPTION + 1] = "";
     concptr q = _("どのアイテムに銘を刻みますか? ", "Inscribe which item? ");
     concptr s = _("銘を刻めるアイテムがない。", "You have nothing to inscribe.");
     o_ptr = choose_object(player_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT));
@@ -213,9 +214,9 @@ void do_cmd_inscribe(PlayerType *player_ptr)
     msg_print(nullptr);
     strcpy(out_val, "");
     if (o_ptr->inscription)
-        strcpy(out_val, quark_str(o_ptr->inscription));
+        angband_strcpy(out_val, quark_str(o_ptr->inscription), MAX_INSCRIPTION);
 
-    if (get_string(_("銘: ", "Inscription: "), out_val, 80)) {
+    if (get_string(_("銘: ", "Inscription: "), out_val, MAX_INSCRIPTION)) {
         o_ptr->inscription = quark_add(out_val);
         set_bits(player_ptr->update, PU_COMBINE);
         set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_FLOOR_ITEM_LIST);
index bd069fe..d4a7b27 100644 (file)
@@ -320,6 +320,8 @@ void get_inscription(char *buff, object_type *o_ptr)
         while (*insc) {
             if (*insc == '#')
                 break;
+            if (buff > ptr + MAX_INSCRIPTION - 1)
+                break;
 #ifdef JP
             if (iskanji(*insc))
                 *buff++ = *insc++;
index 235c4bd..b733a90 100644 (file)
@@ -57,6 +57,7 @@ typedef int errr;
 #define MAX_SHORT 32767 /*!< Maximum value storable in a "int16_t" (hard-coded) */
 
 #define MAX_NLEN 160 /*!< Maximum length of object's name */
+#define MAX_INSCRIPTION _(76, 69) /*!< Maximum length of object's inscription */
 #define MAX_MONSTER_NAME 160 /*!< モンスター名称の最大バイト数 / Max characters of monster's name */
 
 /*!
index 09ca467..88f9551 100644 (file)
@@ -21,7 +21,7 @@ void display_short_flavors(flavor_type *flavor_ptr)
     if (flavor_ptr->o_ptr->inscription == 0)
         return;
 
-    char buff[1024];
+    char buff[1024] = "";
     if (flavor_ptr->tmp_val2[0])
         strcat(flavor_ptr->tmp_val2, ", ");