#2135: Segfault in map.h line 208 caused by invalid map size 0x0
------------------------------------------------+---------------------------
        Reporter:  corvusco...@…                |         Type:  bug            
          
          Status:  new                          |     Priority:  major          
          
       Milestone:  unspecified                  |    Component:  Engine: other  
          
         Version:  2.3.4                        |     Keywords:  segfault map 
size invalid
Operating System:  All/Non-Specific             |   Blocked By:                 
          
        Blocking:                               |  
------------------------------------------------+---------------------------
 map.h line 208:


 {{{
 ...
 206 static inline unsigned char terrainType(const MAPTILE * tile)
 207 {
 208    return terrainTypes[TileNumber_tile(tile->texture)];
 209 }
 ...
 }}}

 According to backtrace it was called from

 map_Height(), map.c, line 1190
 {{{
 ...
 if (terrainType(mapTile(tileX,tileY)) == TER_WATER)
 ...
 }}}
 which in turn was called from
 moveUpdateDroid(), move.c, line 3000,

 the invalid tile pointer came from:
 {{{
 static inline WZ_DECL_PURE MAPTILE *mapTile(SDWORD x, SDWORD y)
 /* Return a pointer to the tile structure at x,y */
 static inline WZ_DECL_PURE MAPTILE *mapTile(SDWORD x, SDWORD y)
 {
         // Clamp x and y values to actual ones
         // Give one tile worth of leeway before asserting, for
 units/transporters coming in from off-map.
         ASSERT(x >= -1, "mapTile: x value is too small (%d,%d) in
 %dx%d",x,y,mapWidth,mapHeight);
         ASSERT(y >= -1, "mapTile: y value is too small (%d,%d) in
 %dx%d",x,y,mapWidth,mapHeight);
         x = (x < 0 ? 0 : x);
         y = (y < 0 ? 0 : y);
         ASSERT(x < mapWidth + 1, "mapTile: x value is too big (%d,%d) in
 %dx%d",x,y,mapWidth,mapHeight);
         ASSERT(y < mapHeight + 1, "mapTile: y value is too big (%d,%d) in
 %dx%d",x,y,mapWidth,mapHeight);
         x = (x >= mapWidth ? mapWidth - 1 : x);
         y = (y >= mapHeight ? mapHeight - 1 : y);

         return &psMapTiles[x + (y * mapWidth)];
 }
 }}}

 The way these checks are written, a invalid map with size mapwidth=0 and
 mapheight=0 as encountered in this network game lead to the check:

 {{{
         x = (x >= mapWidth ? mapWidth - 1 : x);
         y = (y >= mapHeight ? mapHeight - 1 : y);
 }}}

 calculating the pointer as
 {{{
         return &psMapTiles[-1];
 }}}

 SEGFAULT!

 Though apart from the assertions handling this fatal case incorrectly, a
 map with 0x0 size shouldn't have been loaded in the first place!

 Please someone add a check after map download and parsing.

-- 
Ticket URL: <http://developer.wz2100.net/ticket/2135>
Warzone 2100 Trac <http://developer.wz2100.net/>
The Warzone 2100 Project
_______________________________________________
Warzone-dev mailing list
Warzone-dev@gna.org
https://mail.gna.org/listinfo/warzone-dev

Reply via email to