Login
User Name:

Password:



Register
Forgot your password?
Vote for Us!
tintin++ ogg sound player script for linux
Author: Robert Smith
Submitted by: Vladaar
6Dragons ogg Soundpack
Author: Vladaar
Submitted by: Vladaar
6Dragons 4.4
Author: Vladaar
Submitted by: Vladaar
LoP 1.46
Author: Remcon
Submitted by: Remcon
LOP 1.45
Author: Remcon
Submitted by: Remcon
Users Online
CommonCrawl, Yandex

Members: 0
Guests: 8
Stats
Files
Topics
Posts
Members
Newest Member
481
3,735
19,370
618
Micheal64X
Today's Birthdays
There are no member birthdays today.
Related Links
» SmaugMuds.org » Bugfix Lists » AFKMud Bugfix List » AFKMud Bug Archive » [Bug] The fread_mobile functi...
Forum Rules | Mark all | Recent Posts

[Bug] The fread_mobile function is unsafe and also has leaks
< Newer Topic :: Older Topic > AFKMud 1.77

Pages:<< prev 1 next >>
Post is unread #1 Jul 3, 2006, 11:23 am
Go to the top of the page
Go to the bottom of the page

Samson
Black Hand
GroupAdministrators
Posts3,643
JoinedJan 1, 2002

Bug: The fread_mobile function is unsafe and also has leaks
Danger: High - Minor memory leaks + infinite loop potential in corrupt pfiles
Discovered in: AFKMud 1.77
Found by: Remcon
Fixed by: Remcon

---

save.c, fread_mobile

Replace the entire function with this:
/*
 * This will read one mobile structure pointer to by fp --Shaddai
 *   Edited by Tarl 5 May 2002 to allow pets to load equipment.
 */
CHAR_DATA *fread_mobile( FILE * fp, bool shopmob )
{
   CHAR_DATA *mob = NULL;
   const char *word;
   bool fMatch;
   int inroom = 0, i, x;
   ROOM_INDEX_DATA *pRoomIndex = NULL;
   MOB_INDEX_DATA *pMobIndex = NULL;

   if( !shopmob )
      word = feof( fp ) ? "EndMobile" : fread_word( fp );
   else
      word = feof( fp ) ? "EndVendor" : fread_word( fp );

   if( word[0] == '\0' )
   {
      bug( "%s: EOF encountered reading file!", __FUNCTION__ );
      if( !shopmob )
         word = "EndMobile";
      else
         word = "EndVendor";
   }

   if( !str_cmp( word, "Vnum" ) )
   {
      int vnum;

      vnum = fread_number( fp );
      pMobIndex = get_mob_index( vnum );
      if( !pMobIndex )
      {
         for( ;; )
         {
            if( !shopmob )
               word = feof( fp ) ? "EndMobile" : fread_word( fp );
            else
               word = feof( fp ) ? "EndVendor" : fread_word( fp );

            if( word[0] == '\0' )
            {
               bug( "%s: EOF encountered reading file!", __FUNCTION__ );
               if( !shopmob )
                  word = "EndMobile";
               else
                  word = "EndVendor";
            }

            /*
             * So we don't get so many bug messages when something messes up
             * * --Shaddai
             */
            if( !str_cmp( word, "EndMobile" ) || !str_cmp( word, "EndVendor" ) )
               break;
         }
         bug( "%s: No index data for vnum %d", __FUNCTION__, vnum );
         return NULL;
      }
      mob = create_mobile( pMobIndex );
   }
   else
   {
      for( ;; )
      {
         if( !shopmob )
            word = feof( fp ) ? "EndMobile" : fread_word( fp );
         else
            word = feof( fp ) ? "EndVendor" : fread_word( fp );

         if( word[0] == '\0' )
         {
            bug( "%s: EOF encountered reading file!", __FUNCTION__ );
            if( !shopmob )
               word = "EndMobile";
            else
               word = "EndVendor";
         }

         /*
          * So we don't get so many bug messages when something messes up
          * * --Shaddai
          */
         if( !str_cmp( word, "EndMobile" ) || !str_cmp( word, "EndVendor" ) )
            break;
      }
      extract_char( mob, TRUE );
      bug( "%s: Vnum not found", __FUNCTION__ );
      return NULL;
   }

   for( ;; )
   {
      if( !shopmob )
         word = feof( fp ) ? "EndMobile" : fread_word( fp );
      else
         word = feof( fp ) ? "EndVendor" : fread_word( fp );

      if( word[0] == '\0' )
      {
         bug( "%s: EOF encountered reading file!", __FUNCTION__ );
         if( !shopmob )
            word = "EndMobile";
         else
            word = "EndVendor";
      }

      fMatch = FALSE;
      switch ( UPPER( word[0] ) )
      {
         case '*':
            fMatch = TRUE;
            fread_to_eol( fp );
            break;

         case '#':
            if( !str_cmp( word, "#OBJECT" ) )
            {
               fread_obj( mob, fp, OS_CARRY );
               fMatch = true;
               break;
            }
            break;

         case 'A':
            if( !str_cmp( word, "Affect" ) || !str_cmp( word, "AffectData" ) )
            {
               AFFECT_DATA *paf;

               CREATE( paf, AFFECT_DATA, 1 );
               if( !str_cmp( word, "Affect" ) )
                  paf->type = fread_number( fp );
               else
               {
                  int sn;
                  char *sname = fread_word( fp );

                  if( ( sn = skill_lookup( sname ) ) < 0 )
                  {
                     if( ( sn = herb_lookup( sname ) ) < 0 )
                        bug( "%s", "Fread_mobile: unknown skill." );
                     else
                        sn += TYPE_HERB;
                  }
                  paf->type = sn;
               }

               paf->duration = fread_number( fp );
               paf->modifier = fread_number( fp );
               paf->location = fread_number( fp );
               if( paf->location == APPLY_WEAPONSPELL
                   || paf->location == APPLY_WEARSPELL
                   || paf->location == APPLY_REMOVESPELL
                   || paf->location == APPLY_STRIPSN || paf->location == APPLY_RECURRINGSPELL )
                  paf->modifier = slot_lookup( paf->modifier );
               paf->bit = fread_number( fp );
               LINK( paf, mob->first_affect, mob->last_affect, next, prev );
               fMatch = true;
               break;
            }
            KEY( "AffectedBy", mob->affected_by, fread_bitvector( fp ) );
            break;

         case 'C':
            if( !str_cmp( word, "Coordinates" ) )
            {
               mob->x = fread_number( fp );
               mob->y = fread_number( fp );
               mob->map = fread_number( fp );

               fMatch = TRUE;
               break;
            }
            break;

         case 'D':
            if( !str_cmp( word, "Description" ) )
            {
               STRFREE( mob->chardesc );
               mob->chardesc = fread_string( fp );
               fMatch = TRUE;
               break;
            }
            break;

         case 'E':
            if( !str_cmp( word, "EndMobile" ) || !str_cmp( word, "EndVendor" ) )
            {
               if( inroom == 0 )
                  inroom = ROOM_VNUM_TEMPLE;
               pRoomIndex = get_room_index( inroom );
               if( !pRoomIndex )
                  pRoomIndex = get_room_index( ROOM_VNUM_LIMBO );
               if( !char_to_room( mob, pRoomIndex ) )
                  log_printf( "char_to_room: %s:%s, line %d.", __FILE__, __FUNCTION__, __LINE__ );

               for( i = 0; i < MAX_WEAR; i++ )
                  for( x = 0; x < MAX_LAYERS; x++ )
                     if( mob_save_equipment[i][x] )
                     {
                        equip_char( mob, mob_save_equipment[i][x], i );
                        mob_save_equipment[i][x] = NULL;
                     }
               return mob;
            }
            if( !str_cmp( word, "Exp" ) )
            {
               mob->exp = fread_number( fp );
               fMatch = TRUE;
               break;
            }
            break;

         case 'F':
            KEY( "Flags", mob->act, fread_bitvector( fp ) );
            break;

         case 'H':
            if( !str_cmp( word, "HpManaMove" ) )
            {
               mob->hit = fread_number( fp );
               mob->max_hit = fread_number( fp );
               mob->mana = fread_number( fp );
               mob->max_mana = fread_number( fp );
               mob->move = fread_number( fp );
               mob->max_move = fread_number( fp );
               fMatch = TRUE;
               break;
            }
            break;

         case 'L':
            KEY( "Level", mob->level, fread_number( fp ) );
            if( !str_cmp( word, "Long" ) )
            {
               STRFREE( mob->long_descr );
               mob->long_descr = fread_string( fp );
               fMatch = TRUE;
               break;
            }
            break;

         case 'N':
            if( !str_cmp( word, "Name" ) )
            {
               STRFREE( mob->name );
               mob->name = fread_string( fp );
               fMatch = TRUE;
               break;
            }
            break;

         case 'P':
            KEY( "Position", mob->position, fread_number( fp ) );
            break;

         case 'R':
            KEY( "Room", inroom, fread_number( fp ) );
            break;

         case 'S':
            if( !str_cmp( word, "Short" ) )
            {
               STRFREE( mob->short_descr );
               mob->short_descr = fread_string( fp );
               fMatch = TRUE;
               break;
            }
            break;
      }
      if( !fMatch )
      {
         bug( "%s: no match: %s", __FUNCTION__, word );
         fread_to_eol( fp );
      }
   }
}


This is a cumulative fix ported over from SmaugFUSS which fixes some minor memory leaks and also adds protection against infinite loops if the pfiles containing the mobile data are corrupted and end prematurely. Such corruption and looping is an on-going problem with many Merc derived muds.
       
Pages:<< prev 1 next >>