[CF-Devel] Fix for diseases on tiled maps crashing the server

crossfire-devel at archives.real-time.com crossfire-devel at archives.real-time.com
Mon Aug 16 14:15:23 CDT 2004


The attached patches fixes a bug with diseases cast on tiled maps. (This
bug did crash the server on metalforge some days ago.)

Basically, the bug is that the loop variables (x and y) in
check_infection() are modified by get_map_flags(), resulting in an
infinite loop. My fix uses some temp variables for the result values,
leaving the loop variables unchanged.

I checked all other calls of get_map_flags() for similar problems. (I
did not actually tested these other fixes.)

But I have some concerns with the change to magic_wall() in
server/spell_effect.c: it does not feel right to me that the existing
code used the leftover value from the previous loop for "m". Therefore I
added "m=tmp->map" because "x" and "y" use the coordinates from "tmp" as
well.
-------------- next part --------------
Index: server/disease.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/server/disease.c,v
retrieving revision 1.27
diff -w -c -5 -r1.27 disease.c
*** server/disease.c	13 Sep 2003 05:02:09 -0000	1.27
--- server/disease.c	16 Aug 2004 19:00:45 -0000
***************
*** 230,242 ****
  }
    
  /*  searches around for more victims to infect */
  int check_infection(object *disease) {
      int x,y,range, mflags;
!     mapstruct *map;
      object *tmp;
!     sint16 i,j;
  
      range = abs(disease->magic);
      if(disease->env) { 
  	x = disease->env->x;
  	y = disease->env->y;
--- 230,242 ----
  }
  
  /*  searches around for more victims to infect */
  int check_infection(object *disease) {
      int x,y,range, mflags;
!     mapstruct *map, *map2;
      object *tmp;
!     sint16 i, j, i2, j2;
  
      range = abs(disease->magic);
      if(disease->env) {
  	x = disease->env->x;
  	y = disease->env->y;
***************
*** 249,261 ****
      }
  
      if(map == NULL) return 0;
      for(i=x-range;i<x+range;i++) {
  	for(j=y-range;j<y+range;j++) {
! 	    mflags = get_map_flags(map,&map, i,j, &i, &j);
  	    if (!(mflags & P_OUT_OF_MAP) && (mflags & P_IS_ALIVE)) {
! 		for(tmp=get_map_ob(map,i,j);tmp;tmp=tmp->above) {
  		    infect_object(tmp,disease,0);
  		}
  	    }
  	}
      }
--- 249,261 ----
      }
  
      if(map == NULL) return 0;
      for(i=x-range;i<x+range;i++) {
  	for(j=y-range;j<y+range;j++) {
! 	    mflags = get_map_flags(map,&map2, i,j, &i2, &j2);
  	    if (!(mflags & P_OUT_OF_MAP) && (mflags & P_IS_ALIVE)) {
! 		for(tmp=get_map_ob(map2,i2,j2);tmp;tmp=tmp->above) {
  		    infect_object(tmp,disease,0);
  		}
  	    }
  	}
      }
Index: server/move.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/server/move.c,v
retrieving revision 1.32
diff -w -c -5 -r1.32 move.c
*** server/move.c	16 Apr 2004 06:23:43 -0000	1.32
--- server/move.c	16 Aug 2004 19:00:45 -0000
***************
*** 289,312 ****
  int try_fit (object *op, mapstruct *m, int x, int y) 
  {
      object *tmp, *more;
      sint16 tx, ty;
      int mflags;
  
      if (op->head) 
  	op = op->head;
  
      for (more = op; more ; more = more->more) {
  	tx = x + more->x - op->x;
  	ty = y + more->y - op->y;
  
! 	mflags = get_map_flags(m, &m, tx, ty, &tx, &ty);
  
  	if (mflags & P_OUT_OF_MAP)
  	    return 1;
  
! 	for (tmp = get_map_ob (m, tx, ty); tmp; tmp=tmp->above) {
  	    if (tmp->head == op || tmp == op)
  		continue;
  
  	    if ((QUERY_FLAG(tmp,FLAG_ALIVE) && tmp->type!=DOOR))
  		return 1;
--- 289,313 ----
  int try_fit (object *op, mapstruct *m, int x, int y)
  {
      object *tmp, *more;
      sint16 tx, ty;
      int mflags;
+     mapstruct *m2;
  
      if (op->head)
  	op = op->head;
  
      for (more = op; more ; more = more->more) {
  	tx = x + more->x - op->x;
  	ty = y + more->y - op->y;
  
! 	mflags = get_map_flags(m, &m2, tx, ty, &tx, &ty);
  
  	if (mflags & P_OUT_OF_MAP)
  	    return 1;
  
! 	for (tmp = get_map_ob (m2, tx, ty); tmp; tmp=tmp->above) {
  	    if (tmp->head == op || tmp == op)
  		continue;
  
  	    if ((QUERY_FLAG(tmp,FLAG_ALIVE) && tmp->type!=DOOR))
  		return 1;
Index: server/spell_effect.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/server/spell_effect.c,v
retrieving revision 1.121
diff -w -c -5 -r1.121 spell_effect.c
*** server/spell_effect.c	16 Jun 2004 07:09:45 -0000	1.121
--- server/spell_effect.c	16 Aug 2004 19:00:45 -0000
***************
*** 1178,1187 ****
--- 1178,1188 ----
  	 
  	dir2 = (dir<4)?(dir+2):dir-2;
  	 
  	x = tmp->x+i*freearr_x[dir2]; 
  	y = tmp->y+i*freearr_y[dir2];
+ 	m = tmp->map;
  
  	if(!(get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP | P_BLOCKED)) && !posblocked) {
  	    tmp2 = get_object();
  	    copy_object(tmp,tmp2);
  	    tmp2->x = x;
-------------- next part --------------
_______________________________________________
crossfire-devel mailing list
     
     crossfire-devel at lists.real-time.com
     
     
     https://mailman.real-time.com/mailman/listinfo/crossfire-devel
     
     
    


More information about the crossfire mailing list