Stock Circle Bug

From: Edward Almasy (almasy@axisdata.com)
Date: 01/19/97


I believe there is a bug in stock CircleMUD 3.0bp11 in db.c, lines 2058-
2065, in the function free_char():

  if (!IS_NPC(ch) || (IS_NPC(ch) && GET_MOB_RNUM(ch) == -1)) {   
    /* if this is a player, or a non-prototyped non-player, free all */
    if (GET_NAME(ch))
      free(GET_NAME(ch));
    if (ch->player.title)
      free(ch->player.title);
    if (ch->player.short_descr)
      free(ch->player.short_descr);

The bug arises when ch points to an NPC with an rnum of -1.  The problem
is that for NPCs the GET_NAME() macro actually returns a pointer to
ch->player.short_descr, so you end up calling free() for that field twice.

This is most like to manifest itself when using one of the OLCs, since
they have to create new NPCs on the fly.  Under Linux it corrupts the heap
and causes a crash at some later indeterminate point that may be seemingly
unrelated to the above code.  Other OSes may handle multiple deallocations
of the same chunk differently, with more or less drastic results.

The fix that we're using is:

  if (!IS_NPC(ch) || (IS_NPC(ch) && GET_MOB_RNUM(ch) == -1)) {
    /* if this is a player, or a non-prototyped non-player, free all */
    if (ch->player.name)
      free(ch->player.name);
    if (ch->player.title)
      free(ch->player.title);
    if (ch->player.short_descr)
      free(ch->player.short_descr);

(The third and fourth lines are the only ones modified.)  This change
should avoid the double deallocation.

If a problem with the above fix becomes apparent to anyone or if the bug
is not present in stock Circle, please let me know.

Greymalk
The Ninth Circle
greymalk@axisdata.com


+-----------------------------------------------------------+
| Ensure that you have read the CircleMUD Mailing List FAQ: |
|   http://cspo.queensu.ca/~fletcher/Circle/list_faq.html   |
+-----------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/18/00 PST