[comp.bugs.4bsd] expr trashes memory

sjoerd@cwi.nl (Sjoerd Mullender) (02/04/89)

Subject: expr trashes memory
Index: bin tahoe

Description:
	Expr overwrites its memory when a very long strings matches
	the \( \) pair in the second argument to the : operator.
Repeat-By:
	Try the following command:

		expr very-long-argument : '\(.*\)'

	If expr doesn't dump core, the very-long-argument wasn't long
	enough.
	Another possibility is to just look at the source.
Fix:
	A look at the source gives the impression that the match algorithm
	was adapted from another program, since the matched strings are
	put into a two dimensional array Mstring, of which the first
	dimension has length 1.
	The context diff below changes Mstring into a character pointer
	and allocates the memory needed for the matched string at run time.
	Further improvements might include checking the results of the
	malloc calls.

*** expr.y.orig	Mon May 21 17:20:06 1984
--- expr.y	Fri Feb  3 17:12:49 1989
***************
*** 56,62 ****
  int	Ac;
  int	Argi;
  
! char Mstring[1][128];
  char *malloc();
  extern int nbra;
  
--- 56,62 ----
  int	Ac;
  int	Argi;
  
! char *Mstring;
  char *malloc();
  extern int nbra;
  
***************
*** 205,212 ****
  
  	sprintf(rv = malloc(8), "%d", ematch(s, p));
  	if(nbra) {
! 		rv = malloc(strlen(Mstring[0])+1);
! 		strcpy(rv, Mstring[0]);
  	}
  	return rv;
  }
--- 205,212 ----
  
  	sprintf(rv = malloc(8), "%d", ematch(s, p));
  	if(nbra) {
! 		rv = malloc(strlen(Mstring)+1);
! 		strcpy(rv, Mstring);
  	}
  	return rv;
  }
***************
*** 235,242 ****
  		if(nbra == 1) {
  			p = braslist[0];
  			num = braelist[0] - p;
! 			strncpy(Mstring[0], p, num);
! 			Mstring[0][num] = '\0';
  		}
  		return(loc2-s);
  	}
--- 235,243 ----
  		if(nbra == 1) {
  			p = braslist[0];
  			num = braelist[0] - p;
! 			Mstring = malloc(num + 1);
! 			strncpy(Mstring, p, num);
! 			Mstring[num] = '\0';
  		}
  		return(loc2-s);
  	}
-- 
Sjoerd Mullender		e-mail: sjoerd@cwi.nl
Centre for Mathematics and Computer Science, Amsterdam