Bug in vi and ex 3.6

crl crl
Tue Jul 27 10:41:46 AEST 1982


I think that I have found a bug in version 3.6 of ex (and vi).  A user
here had a file that had many, many ;'s in it, and he wanted to do 
a substitute on the whole file to replace them with spaces.  I told
him to do a :%s/;/ /g.  Oddly, this command gave the error "Substitution
Loop", while :g/;/s// /g did not.  Looking into the code, I found that
the substitute command tries to avoid a substitution loop by keeping
a variable called 'hopcount', which is incremented after every substitute
with the 'g' flag.  If it gets larger than the size of the line buffer,
vi thinks it is in a loop.  However, hopcount was not being initialized
to zero at the beginning of every line.  Therefore, if you wanted to
make over 512 substitutions (the size of our linebuf), you were out of
luck.  The fix follows.

Charles LaBrec
Purdue University
pur-ee!physics:crl
---------------------------------------------------------------------
*** ex_re.c.old	Mon Jul  5 22:47:45 1982
--- ex_re.c	Mon Jul  5 22:40:47 1982
***************
*** 182,187
  			 * The loop can happen from s/\</&/g
  			 * but we don't want to break other, reasonable cases.
  			 */
  			while (*loc2) {
  				if (++hopcount > sizeof linebuf)
  					error("substitution loop");

--- 182,196 -----
  			 * The loop can happen from s/\</&/g
  			 * but we don't want to break other, reasonable cases.
  			 */
+ #ifdef PUR_PHY
+ 			hopcount=0;  	/* since it seems hopcount is 
+ 					 * never reset, ex thinks it is 
+ 					 * looping if there are more than
+ 					 * sizeof (linbuf) subs made.
+ 					 * This attempts to forstall this
+ 					 * by resetting hopcount every line
+ 					 */
+ #endif PUR_PHY
  			while (*loc2) {
  				if (++hopcount > sizeof linebuf)
  					error("substitution loop");



More information about the Net.bugs mailing list