summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--src/game.cpp6
-rw-r--r--src/gui/npc.cpp16
-rw-r--r--src/gui/npc.h2
4 files changed, 16 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index ca437178..af87bfa6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.