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