fixed a somewhat dangerous bug to shops

From: Kras Kresh (kras_kresh@hotmail.com)
Date: 04/22/02


This is a OLC bug, and I have no idea if anyone has submitted a fix already.

If you read the comments in genshp.c, around line 390, you'll see:
      /* Make a "nofree" variant and remove these later. */
      shop_index[rshop].in_room = NULL;
      shop_index[rshop].producing = NULL;
      shop_index[rshop].type = NULL;

There are two of those.
That is done during creation of a new shop.
However, they aren't even used!!! They are completely pointless unless used.
I believe the writer was going to do something with it to prevent the mud
from screwing over, but forgot to.

Heres how you check if you have the bug.

find 2 adjacent unused shop numbers -- non-existent ones

sedit the lower one and save it and quit
sedit the second one and save it and quit
and we crash

i suggest trying this on a test port.
I didn't bother with those three.
I just added in the following before copy_shop() is called:

      S_NOITEM1(&shop_index[rshop]) = NULL;
      S_NOITEM2(&shop_index[rshop]) = NULL;
      S_NOCASH1(&shop_index[rshop]) = NULL;
      S_NOCASH2(&shop_index[rshop]) = NULL;
      S_NOBUY(&shop_index[rshop]) = NULL;
      S_BUY(&shop_index[rshop]) = NULL;
      S_SELL(&shop_index[rshop]) = NULL;

so I have:

..............................
  for (rshop = top_shop - top_shop_offset; rshop > 0; rshop--) {
    if (nshp->vnum > SHOP_NUM(rshop - 1)) {
      found = rshop;

      /* Make a "nofree" variant and remove these later. */
      shop_index[rshop].in_room = NULL;
      shop_index[rshop].producing = NULL;
      shop_index[rshop].type = NULL;

      S_NOITEM1(&shop_index[rshop]) = NULL;
      S_NOITEM2(&shop_index[rshop]) = NULL;
      S_NOCASH1(&shop_index[rshop]) = NULL;
      S_NOCASH2(&shop_index[rshop]) = NULL;
      S_NOBUY(&shop_index[rshop]) = NULL;
      S_BUY(&shop_index[rshop]) = NULL;
      S_SELL(&shop_index[rshop]) = NULL;

      copy_shop(&shop_index[rshop], nshp);
      break;
      break;
    }
    shop_index[rshop] = shop_index[rshop - 1];
  }

  if (!found) {
    /* Make a "nofree" variant and remove these later. */
    shop_index[rshop].in_room = NULL;
    shop_index[rshop].producing = NULL;
    shop_index[rshop].type = NULL;

    S_NOITEM1(&shop_index[rshop]) = NULL;
    S_NOITEM2(&shop_index[rshop]) = NULL;
    S_NOCASH1(&shop_index[rshop]) = NULL;
    S_NOCASH2(&shop_index[rshop]) = NULL;
    S_NOBUY(&shop_index[rshop]) = NULL;
    S_BUY(&shop_index[rshop]) = NULL;
    S_SELL(&shop_index[rshop]) = NULL;

    copy_shop(&shop_index[0], nshp);
  }
...........

I'm pretty sure that I didn't screw it up here. If the slot was used, it
shouldn't be anymore after going through the for loop. copy_shop() would try
to free the slots that were transferred to another slot -- very buggy. That
is what I believe the comment in there was for. Anyway, free'ing an already
free'd pointer would crash the program. That is why it requires two sedit
new saves to crash, but still possible with just one. I think all you have
to do is reboot the mud. It would call on save_all() and it would try to
read from a free'd pointer and crash. This thing took me two hours to do!!
Takes a while if you don't mini the mud while using efence. Someone please
verify that my fix works, someone that knows what I'm talking about.

_________________________________________________________________
Send and receive Hotmail on your mobile device: http://mobile.msn.com

--
   +---------------------------------------------------------------+
   | FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
   | Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
   | Newbie List:  http://groups.yahoo.com/group/circle-newbies/   |
   +---------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 06/25/03 PDT