diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | src/game.cpp | 6 | ||||
-rw-r--r-- | src/gui/npc.cpp | 16 | ||||
-rw-r--r-- | src/gui/npc.h | 2 |
4 files changed, 16 insertions, 15 deletions
@@ -1,5 +1,10 @@ 2005-08-27 Björn Steinbrink <B.Steinbrink@gmx.de> - + * src/game.cpp, src/gui/npc.cpp, src/gui/npc.h: Fix the bug when + sometimes the last entry in npc list windows is missing. The network + buffer isn't reset to all zeros, thus we can't rely on the received + string to be nul-terminated, instead we have to use the length + parameter we receive from eAthena (and this way we're also safe + against buffer overflows, because we can use strncpy()). * src/gui/window.cpp: Bail out early if there's no window container. * src/engine.cpp, src/game.cpp, src/gui/stats.cpp, src/gui/stats.h, src/gui/status.cpp, src/gui/status.h: Update the stats and status diff --git a/src/game.cpp b/src/game.cpp index c40a052c..8f7f3aa5 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1697,10 +1697,8 @@ void do_parse() // List in NPC dialog case 0x00b7: current_npc = RFIFOL(4); - // Hammerbear: Second argument here shouldn't be neccesary, - // instead make sure the string is \0 terminated. - //parse_items(RFIFOP(8), RFIFOW(2)); - npcListDialog->parseItems(RFIFOP(8)); + // RFIFOW(2) seems to be the full packet length, thus -8 + npcListDialog->parseItems(RFIFOP(8), RFIFOW(2)-8); npcListDialog->setVisible(true); break; diff --git a/src/gui/npc.cpp b/src/gui/npc.cpp index 084f2f6a..99d3b3a5 100644 --- a/src/gui/npc.cpp +++ b/src/gui/npc.cpp @@ -80,23 +80,21 @@ std::string NpcListDialog::getElementAt(int i) return items[i]; } -void NpcListDialog::parseItems(const char *string) { - char *copy = new char[strlen(string) + 1]; - strcpy(copy, string); +void NpcListDialog::parseItems(const char *string, unsigned short len) { + char *copy = new char[len + 1]; + strncpy(copy, string, len); + copy[len] = 0; char *token = strtok(copy, ":"); - while (token != NULL) { + while (token) { char *temp = (char*)malloc(strlen(token) + 1); strcpy(temp, token); items.push_back(std::string(temp)); token = strtok(NULL, ":"); } - - // TEMP: remove the last item insrted (fixes an athena bug probably) - items.pop_back(); - + delete[] copy; -} +} void NpcListDialog::reset() { items.clear(); diff --git a/src/gui/npc.h b/src/gui/npc.h index 8b694341..336bad62 100644 --- a/src/gui/npc.h +++ b/src/gui/npc.h @@ -75,7 +75,7 @@ class NpcListDialog : public Window, public gcn::ActionListener, * * @param string A string with the options separated with colons. */ - void parseItems(const char *string); + void parseItems(const char *string, unsigned short len); /** * Resets the list by removing all items. |