perl 2.0 patch #18

Larry Wall lwall at jpl-devvax.JPL.NASA.GOV
Tue Nov 22 20:07:33 AEST 1988


System: perl version 2.0
Patch #: 18
Priority: MEDIUM-HOT
Subject: declaration of origargv needed to be outside #ifdef DOSUID
Subject: string variables referenced numerically can later lose string value
Subject: manual page now contains current Release and Patchlevel
Subject: "make realclean" removes more files
Subject: removed extraneous EXT from struct definition in cmd.h
Subject: added $: to specify breakable characters in formats
Subject: continuation did not work with right justified or centered fields
Subject: makedepend shouldn't search subdirectories for *.[ch] files
Subject: documented non-initialization of SIG array
Subject: initialization of ENV must be forced if TAINT defined
Subject: $) wouldn't interpolate in "eff gid = $)"
Subject: dependencies in the wrong order in Makefile

Description:
	Sorry, I'm only one person.  I didn't test the changes in patch17
	when DOSUID is undefined, and so missed the undefined origargv thing.
	The fix is simply to move the declaration of origargv outside
	the #ifdef DOSUID.

	When you reference a string variable in a numeric context, the
	variable retains both a numeric value and a string value.  It doesn't
	matter if the string variable isn't a legal number--if it's looked
	at in a string context, you still get the string value.  Unfortunately
	there was a class of operation in perl that could inadvertently
	destroy the string value.  Among these were array copies and
	postincrement/decrement.  This has been fixed.

	The manual page now contains current Release and Patchlevel.

	"make realclean" now removes more files, as several people suggested.

	There was an extraneous EXT on a struct definition in cmd.h that
	declared no objects.  Now there isn't.

	Continuation fields in formats break a variable in multiple fields
	so you can do "filled" text.  It used to be you could only break
	these lines on spaces.  Now by default they are broken on spaces
	and hyphens, and you can change that by assigning the list of break
	characters to $:.

	Continuation fields used to work only for left-justified text.
	Now it works for centered and right justified text.  (It's still
	not perfect but at least it doesn't blow up.)

	The makedepend script had patterns like */*.c and */*.h that were
	holdovers from when it was used for rn.  These patterns have been
	removed.

	The SIG array does not initialize itself to the all possible signals,
	but only holds the signals that have explicitly been set.  This has
	now been documented.

	Setuid scripts that didn't explicitly reference ENV blew up because
	of the implicit reference when checking for an untainted PATH.
	The ENV array is now always initialized when TAINT is defined.

	$) wouldn't interpolate in "eff gid = $)".  This was because it
	was mistakenly seen as a terminating $ in a subpattern.  It now
	works correctly in "" and ``.

	There were some dependencies in the wrong order in the make file.

Fix:	From rn, say "| patch -p -N -d DIR", where DIR is your perl source
	directory.  Outside of rn, say "cd DIR; patch -p -N <thisarticle".
	If you don't have the patch program, apply the following by hand,
	or get patch (version 2.0, latest patchlevel).

	After patching:
		sh Makefile.SH
		sh makedepend.SH
		make depend
		touch perl.y		# Makefile isn't perfect yet...
		make
		make test
		make install

	If patch indicates that patchlevel is the wrong version, you may need
	to apply one or more previous patches, or the patch may already
	have been applied.  See the patchlevel.h file to find out what has or
	has not been applied.  In any event, don't continue with the patch.

	If you are missing previous patches they can be obtained from me:

	Larry Wall
	lwall at jpl-devvax.jpl.nasa.gov

	If you send a mail message of the following form it will greatly speed
	processing:

	Subject: Command
	@SH mailpatch PATH perl 2.0 LIST
		   ^ note the c

	where PATH is a return path FROM ME TO YOU either in Internet notation,
	or in bang notation from some well-known host, and LIST is the number
	of one or more patches you need, separated by spaces, commas, and/or
	hyphens.  Saying 35- says everything from 35 to the end.


	You can also get the patches via anonymous FTP from
	jpl-devvax.jpl.nasa.gov (128.149.8.43).

Index: patchlevel.h
Prereq: 17
1c1
< #define PATCHLEVEL 17
---
> #define PATCHLEVEL 18

Index: Makefile.SH
Prereq: 2.0.1.6
*** Makefile.SH.old	Tue Nov 22 01:20:29 1988
--- Makefile.SH	Tue Nov 22 01:20:31 1988
***************
*** 25,33 ****
  
  echo "Extracting Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
! # $Header: Makefile.SH,v 2.0.1.6 88/11/18 23:41:43 lwall Locked $
  #
  # $Log:	Makefile.SH,v $
  # Revision 2.0.1.6  88/11/18  23:41:43  lwall
  # patch16: now creates taintperl for taint checks without setuid emulation
  # 
--- 25,38 ----
  
  echo "Extracting Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
! # $Header: Makefile.SH,v 2.0.1.7 88/11/22 01:04:00 lwall Locked $
  #
  # $Log:	Makefile.SH,v $
+ # Revision 2.0.1.7  88/11/22  01:04:00  lwall
+ # patch18: dependencies in the wrong order in Makefile
+ # patch18: manual page now contains current Release and Patchlevel
+ # patch18: "make realclean" removes more files
+ # 
  # Revision 2.0.1.6  88/11/18  23:41:43  lwall
  # patch16: now creates taintperl for taint checks without setuid emulation
  # 
***************
*** 118,124 ****
  # This is the standard version that contains no "taint" checks and is
  # used for all scripts that aren't set-id or running under something set-id.
  
! perl: $(obj) perl.o
  	$(CC) $(LDFLAGS) $(LARGE) $(obj) perl.o $(libs) -o perl
  
  # This version, if specified in Configure, does ONLY those scripts which need
--- 123,129 ----
  # This is the standard version that contains no "taint" checks and is
  # used for all scripts that aren't set-id or running under something set-id.
  
! perl: perl.o $(obj)
  	$(CC) $(LDFLAGS) $(LARGE) $(obj) perl.o $(libs) -o perl
  
  # This version, if specified in Configure, does ONLY those scripts which need
***************
*** 126,132 ****
  # checks as well as the special code to validate that the script in question
  # has been invoked correctly.
  
! suidperl: sperly.o $(tobj) tperl.o
  	$(CC) $(LDFLAGS) $(LARGE) sperly.o $(tobj) tperl.o $(libs) -o suidperl
  
  # This version interprets scripts that are already set-id either via a wrapper
--- 131,137 ----
  # checks as well as the special code to validate that the script in question
  # has been invoked correctly.
  
! suidperl: tperl.o sperly.o $(tobj)
  	$(CC) $(LDFLAGS) $(LARGE) sperly.o $(tobj) tperl.o $(libs) -o suidperl
  
  # This version interprets scripts that are already set-id either via a wrapper
***************
*** 134,140 ****
  # NOT be setuid to root or anything else.  The only difference between it
  # and normal perl is the presence of the "taint" checks.
  
! taintperl: tperly.o $(tobj) tperl.o
  	$(CC) $(LDFLAGS) $(LARGE) tperly.o $(tobj) tperl.o $(libs) -o taintperl
  
  # Replicating all this junk is yucky, but I don't see a portable way to fix it.
--- 139,145 ----
  # NOT be setuid to root or anything else.  The only difference between it
  # and normal perl is the presence of the "taint" checks.
  
! taintperl: tperl.o tperly.o $(tobj)
  	$(CC) $(LDFLAGS) $(LARGE) tperly.o $(tobj) tperl.o $(libs) -o taintperl
  
  # Replicating all this junk is yucky, but I don't see a portable way to fix it.
***************
*** 243,249 ****
  	touch $@
  
  perl.man: perl.man.1 perl.man.2
! 	cat perl.man.1 perl.man.2 >perl.man
  
  install: all
  # won't work with csh
--- 248,256 ----
  	touch $@
  
  perl.man: perl.man.1 perl.man.2
! 	./perl -e '($$r,$$p)=$$]=~/(\d+\.\d+).*\n\D*(\d+)/; \
! print ".ds RP Release $$r Patchlevel $$p\n";' >perl.man
! 	cat perl.man.1 perl.man.2 >>perl.man
  
  install: all
  # won't work with csh
***************
*** 289,294 ****
--- 296,303 ----
  
  realclean:
  	rm -f perl *.orig */*.orig *~ */*~ *.o core $(addedbyconf) perl.man
+ 	rm -f perl.c perly.h t/perl Makefile config.h makedepend makedir
+ 	rm -f x2p/Makefile
  
  # The following lint has practically everything turned on.  Unfortunately,
  # you have to wade through a lot of mumbo jumbo that can't be suppressed.

Index: cmd.h
Prereq: 2.0
*** cmd.h.old	Tue Nov 22 01:20:36 1988
--- cmd.h	Tue Nov 22 01:20:37 1988
***************
*** 1,6 ****
! /* $Header: cmd.h,v 2.0 88/06/05 00:08:28 root Exp $
   *
   * $Log:	cmd.h,v $
   * Revision 2.0  88/06/05  00:08:28  root
   * Baseline version 2.0.
   * 
--- 1,9 ----
! /* $Header: cmd.h,v 2.0.1.1 88/11/22 01:05:06 lwall Locked $
   *
   * $Log:	cmd.h,v $
+  * Revision 2.0.1.1  88/11/22  01:05:06  lwall
+  * patch18: removed extraneous EXT from struct definition in cmd.h
+  * 
   * Revision 2.0  88/06/05  00:08:28  root
   * Baseline version 2.0.
   * 
***************
*** 120,126 ****
  EXT CMD *main_root INIT(Nullcmd);
  EXT CMD *eval_root INIT(Nullcmd);
  
! EXT struct compcmd {
      CMD *comp_true;
      CMD *comp_alt;
  };
--- 123,129 ----
  EXT CMD *main_root INIT(Nullcmd);
  EXT CMD *eval_root INIT(Nullcmd);
  
! struct compcmd {
      CMD *comp_true;
      CMD *comp_alt;
  };

Index: form.c
Prereq: 2.0.1.2
*** form.c.old	Tue Nov 22 01:20:41 1988
--- form.c	Tue Nov 22 01:20:42 1988
***************
*** 1,6 ****
! /* $Header: form.c,v 2.0.1.2 88/08/05 01:26:20 root Exp $
   *
   * $Log:	form.c,v $
   * Revision 2.0.1.2  88/08/05  01:26:20  root
   * patch13: no form feeds first
   * 
--- 1,10 ----
! /* $Header: form.c,v 2.0.1.3 88/11/22 01:07:10 lwall Locked $
   *
   * $Log:	form.c,v $
+  * Revision 2.0.1.3  88/11/22  01:07:10  lwall
+  * patch18: added $: to specify breakable characters in formats
+  * patch18: continuation did not work with right justified or centered fields
+  * 
   * Revision 2.0.1.2  88/08/05  01:26:20  root
   * patch13: no form feeds first
   * 
***************
*** 67,73 ****
  	    chophere = Nullch;
  	    while (size && *s && *s != '\n') {
  		size--;
! 		if ((*d++ = *s++) == ' ')
  		    chophere = s;
  	    }
  	    if (size)
--- 71,77 ----
  	    chophere = Nullch;
  	    while (size && *s && *s != '\n') {
  		size--;
! 		if (index(chopset,(*d++ = *s++)))
  		    chophere = s;
  	    }
  	    if (size)
***************
*** 103,116 ****
  	    }
  	    break;
  	case F_RIGHT:
! 	    t = s = str_get(eval(fcmd->f_expr,Null(STR***),-1));
  	    size = fcmd->f_size;
  	    CHKLEN(size);
  	    chophere = Nullch;
  	    while (size && *s && *s != '\n') {
  		size--;
! 		if (*s++ == ' ')
! 			chophere = s;
  	    }
  	    if (size)
  		chophere = s;
--- 107,121 ----
  	    }
  	    break;
  	case F_RIGHT:
! 	    str = eval(fcmd->f_expr,Null(STR***),-1);
! 	    t = s = str_get(str);
  	    size = fcmd->f_size;
  	    CHKLEN(size);
  	    chophere = Nullch;
  	    while (size && *s && *s != '\n') {
  		size--;
! 		if (index(chopset,*s++))
! 		    chophere = s;
  	    }
  	    if (size)
  		chophere = s;
***************
*** 118,142 ****
  		if (!chophere)
  		    chophere = s;
  		size += (s - chophere);
- 		d -= (s - chophere);
- 		if (fcmd->f_flags & FC_MORE &&
- 		  *chophere && strNE(chophere,"\n")) {
- 		    while (size < 3) {
- 			d--;
- 			size++;
- 		    }
- 		    while (d[-1] == ' ' && size < fcmd->f_size) {
- 			d--;
- 			size++;
- 		    }
- 		    *d++ = '.';
- 		    *d++ = '.';
- 		    *d++ = '.';
- 		}
  		s = chophere;
  		while (*chophere == ' ' || *chophere == '\n')
  			chophere++;
- 		str_chop(str,chophere);
  	    }
  	    tmpchar = *s;
  	    *s = '\0';
--- 123,131 ----
***************
*** 148,165 ****
  	    bcopy(t,d,size);
  	    d += size;
  	    *s = tmpchar;
  	    break;
  	case F_CENTER: {
  	    int halfsize;
  
! 	    t = s = str_get(eval(fcmd->f_expr,Null(STR***),-1));
  	    size = fcmd->f_size;
  	    CHKLEN(size);
  	    chophere = Nullch;
  	    while (size && *s && *s != '\n') {
  		size--;
! 		if (*s++ == ' ')
! 			chophere = s;
  	    }
  	    if (size)
  		chophere = s;
--- 137,157 ----
  	    bcopy(t,d,size);
  	    d += size;
  	    *s = tmpchar;
+ 	    if (fcmd->f_flags & FC_CHOP)
+ 		str_chop(str,chophere);
  	    break;
  	case F_CENTER: {
  	    int halfsize;
  
! 	    str = eval(fcmd->f_expr,Null(STR***),-1);
! 	    t = s = str_get(str);
  	    size = fcmd->f_size;
  	    CHKLEN(size);
  	    chophere = Nullch;
  	    while (size && *s && *s != '\n') {
  		size--;
! 		if (index(chopset,*s++))
! 		    chophere = s;
  	    }
  	    if (size)
  		chophere = s;
***************
*** 167,191 ****
  		if (!chophere)
  		    chophere = s;
  		size += (s - chophere);
- 		d -= (s - chophere);
- 		if (fcmd->f_flags & FC_MORE &&
- 		  *chophere && strNE(chophere,"\n")) {
- 		    while (size < 3) {
- 			d--;
- 			size++;
- 		    }
- 		    while (d[-1] == ' ' && size < fcmd->f_size) {
- 			d--;
- 			size++;
- 		    }
- 		    *d++ = '.';
- 		    *d++ = '.';
- 		    *d++ = '.';
- 		}
  		s = chophere;
  		while (*chophere == ' ' || *chophere == '\n')
  			chophere++;
- 		str_chop(str,chophere);
  	    }
  	    tmpchar = *s;
  	    *s = '\0';
--- 159,167 ----
***************
*** 206,211 ****
--- 182,189 ----
  		size--;
  		*d++ = ' ';
  	    }
+ 	    if (fcmd->f_flags & FC_CHOP)
+ 		str_chop(str,chophere);
  	    break;
  	}
  	case F_LINES:

Index: form.h
Prereq: 2.0
*** form.h.old	Tue Nov 22 01:20:45 1988
--- form.h	Tue Nov 22 01:20:46 1988
***************
*** 1,6 ****
! /* $Header: form.h,v 2.0 88/06/05 00:09:01 root Exp $
   *
   * $Log:	form.h,v $
   * Revision 2.0  88/06/05  00:09:01  root
   * Baseline version 2.0.
   * 
--- 1,9 ----
! /* $Header: form.h,v 2.0.1.1 88/11/22 01:08:49 lwall Locked $
   *
   * $Log:	form.h,v $
+  * Revision 2.0.1.1  88/11/22  01:08:49  lwall
+  * patch18: added $: to specify breakable characters in formats
+  * 
   * Revision 2.0  88/06/05  00:09:01  root
   * Baseline version 2.0.
   * 
***************
*** 27,29 ****
--- 30,34 ----
  #define FC_MORE 4
  
  #define Nullfcmd Null(FCMD*)
+ 
+ EXT char *chopset INIT(" -");

Index: makedepend.SH
Prereq: 2.0
*** makedepend.SH.old	Tue Nov 22 01:20:50 1988
--- makedepend.SH	Tue Nov 22 01:20:50 1988
***************
*** 15,23 ****
  echo "Extracting makedepend (with variable substitutions)"
  $spitshell >makedepend <<!GROK!THIS!
  $startsh
! # $Header: makedepend.SH,v 2.0 88/06/05 00:09:11 root Exp $
  #
  # $Log:	makedepend.SH,v $
  # Revision 2.0  88/06/05  00:09:11  root
  # Baseline version 2.0.
  # 
--- 15,26 ----
  echo "Extracting makedepend (with variable substitutions)"
  $spitshell >makedepend <<!GROK!THIS!
  $startsh
! # $Header: makedepend.SH,v 2.0.1.1 88/11/22 01:09:44 lwall Locked $
  #
  # $Log:	makedepend.SH,v $
+ # Revision 2.0.1.1  88/11/22  01:09:44  lwall
+ # patch18: makedepend shouldn't search subdirectories for *.[ch] files
+ # 
  # Revision 2.0  88/06/05  00:09:11  root
  # Baseline version 2.0.
  # 
***************
*** 82,88 ****
  esac
  
  make clist || ($echo "Searching for .c files..."; \
! 	$echo *.c */*.c | $tr ' ' '\012' | $egrep -v '\*' >.clist)
  for file in `$cat .clist`; do
  # for file in `cat /dev/null`; do
      case "$file" in
--- 85,91 ----
  esac
  
  make clist || ($echo "Searching for .c files..."; \
! 	$echo *.c | $tr ' ' '\012' | $egrep -v '\*' >.clist)
  for file in `$cat .clist`; do
  # for file in `cat /dev/null`; do
      case "$file" in
***************
*** 109,115 ****
  $sed <Makefile >Makefile.new -e '1,/^# AUTOMATICALLY/!d'
  
  make shlist || ($echo "Searching for .SH files..."; \
! 	$echo *.SH */*.SH | $tr ' ' '\012' | $egrep -v '\*' >.shlist)
  if $test -s .deptmp; then
      for file in `cat .shlist`; do
  	$echo `$expr X$file : 'X\(.*\).SH`: $file config.sh \; \
--- 112,118 ----
  $sed <Makefile >Makefile.new -e '1,/^# AUTOMATICALLY/!d'
  
  make shlist || ($echo "Searching for .SH files..."; \
! 	$echo *.SH | $tr ' ' '\012' | $egrep -v '\*' >.shlist)
  if $test -s .deptmp; then
      for file in `cat .shlist`; do
  	$echo `$expr X$file : 'X\(.*\).SH`: $file config.sh \; \
***************
*** 122,128 ****
         >>Makefile.new
  else
      make hlist || ($echo "Searching for .h files..."; \
! 	$echo *.h */*.h | $tr ' ' '\012' | $egrep -v '\*' >.hlist)
      $echo "You don't seem to have a proper C preprocessor.  Using grep instead."
      $egrep '^#include ' `cat .clist` `cat .hlist`  >.deptmp
      $echo "Updating Makefile..."
--- 125,131 ----
         >>Makefile.new
  else
      make hlist || ($echo "Searching for .h files..."; \
! 	$echo *.h | $tr ' ' '\012' | $egrep -v '\*' >.hlist)
      $echo "You don't seem to have a proper C preprocessor.  Using grep instead."
      $egrep '^#include ' `cat .clist` `cat .hlist`  >.deptmp
      $echo "Updating Makefile..."

Index: perl.man.1
Prereq: 2.0.1.7
*** perl.man.1.old	Tue Nov 22 01:21:02 1988
--- perl.man.1	Tue Nov 22 01:21:08 1988
***************
*** 1,7 ****
  .rn '' }`
! ''' $Header: perl.man.1,v 2.0.1.7 88/11/18 23:59:52 lwall Locked $
  ''' 
  ''' $Log:	perl.man.1,v $
  ''' Revision 2.0.1.7  88/11/18  23:59:52  lwall
  ''' patch16: added getc function
  ''' 
--- 1,10 ----
  .rn '' }`
! ''' $Header: perl.man.1,v 2.0.1.8 88/11/22 01:10:59 lwall Locked $
  ''' 
  ''' $Log:	perl.man.1,v $
+ ''' Revision 2.0.1.8  88/11/22  01:10:59  lwall
+ ''' patch18: manual page now contains current Release and Patchlevel
+ ''' 
  ''' Revision 2.0.1.7  88/11/18  23:59:52  lwall
  ''' patch16: added getc function
  ''' 
***************
*** 70,76 ****
  .ds L' `
  .ds R' '
  'br\}
! .TH PERL 1 LOCAL
  .UC
  .SH NAME
  perl \- Practical Extraction and Report Language
--- 73,79 ----
  .ds L' `
  .ds R' '
  'br\}
! .TH PERL 1 "\*(RP"
  .UC
  .SH NAME
  perl \- Practical Extraction and Report Language

Index: perl.man.2
Prereq: 2.0.1.8
*** perl.man.2.old	Tue Nov 22 01:21:24 1988
--- perl.man.2	Tue Nov 22 01:21:31 1988
***************
*** 1,7 ****
  ''' Beginning of part 2
! ''' $Header: perl.man.2,v 2.0.1.8 88/11/19 00:03:12 lwall Locked $
  '''
  ''' $Log:	perl.man.2,v $
  ''' Revision 2.0.1.8  88/11/19  00:03:12  lwall
  ''' patch16: added $] to return rcsid and patchlevel
  ''' patch16: documented how to write secure setuid perl scripts
--- 1,11 ----
  ''' Beginning of part 2
! ''' $Header: perl.man.2,v 2.0.1.9 88/11/22 01:13:02 lwall Locked $
  '''
  ''' $Log:	perl.man.2,v $
+ ''' Revision 2.0.1.9  88/11/22  01:13:02  lwall
+ ''' patch18: added $: to specify breakable characters in formats
+ ''' patch18: documented non-initialization of SIG array
+ ''' 
  ''' Revision 2.0.1.8  88/11/19  00:03:12  lwall
  ''' patch16: added $] to return rcsid and patchlevel
  ''' patch16: documented how to write secure setuid perl scripts
***************
*** 1101,1106 ****
--- 1105,1112 ----
  out a block of text.
  If you like, you can end the final field with .\|.\|., which will appear in the
  output if the text was too long to appear in its entirety.
+ You can change which characters are legal to break on by changing the
+ variable $: to a list of the desired characters.
  .PP
  Since use of ^ fields can produce variable length records if the text to be
  formatted is short, you can suppress blank lines by putting the tilde (~)
***************
*** 1430,1435 ****
--- 1436,1446 ----
  .Sp
  Note: $<, $>, $( and $) can only be set on machines that support the
  corresponding set[re][ug]id() routine.
+ .Ip $: 8 2
+ The current set of characters after which a string may be broken to
+ fill continuation fields (starting with ^) in a format.
+ Default is "\ -", to break on spaces or hyphens.
+ (Mnemonic: a \*(L"colon\*(R" in poetry is a part of a line.)
  .Ip @ARGV 8 3
  The array ARGV contains the command line arguments intended for the script.
  Note that $#ARGV is the generally number of arguments minus one, since
***************
*** 1469,1474 ****
--- 1480,1487 ----
  	$SIG{\'QUIT\'} = \'IGNORE\';	# ignore SIGQUIT
  
  .fi
+ The SIG array only contains values for the signals actually set within
+ the perl script.
  .Sh "Setuid Scripts"
  .I Perl
  is designed to make it easy to write secure setuid and setgid scripts.

Index: perly.c
Prereq: 2.0.1.9
*** perly.c.old	Tue Nov 22 01:21:51 1988
--- perly.c	Tue Nov 22 01:21:59 1988
***************
*** 1,6 ****
! char rcsid[] = "$Header: perly.c,v 2.0.1.9 88/11/19 00:14:36 lwall Exp $\nPatch level: ###\n";
  /*
   * $Log:	perly.c,v $
   * Revision 2.0.1.9  88/11/19  00:14:36  lwall
   * patch16: added $] to return rcsid and patchlevel
   * patch16: added code to check for kernel setuid script bug
--- 1,11 ----
! char rcsid[] = "$Header: perly.c,v 2.0.1.10 88/11/22 01:14:58 lwall Locked $\nPatch level: ###\n";
  /*
   * $Log:	perly.c,v $
+  * Revision 2.0.1.10  88/11/22  01:14:58  lwall
+  * patch18: declaration of origargv needed to be outside #ifdef DOSUID
+  * patch18: initialization of ENV must be forced if TAINT defined
+  * patch18: added $: to specify breakable characters in formats
+  * 
   * Revision 2.0.1.9  88/11/19  00:14:36  lwall
   * patch16: added $] to return rcsid and patchlevel
   * patch16: added code to check for kernel setuid script bug
***************
*** 102,109 ****
      register char *s;
      char *index(), *strcpy(), *getenv();
      bool dosearch = FALSE;
- #ifdef DOSUID
      char **origargv = argv;
      char *validarg = "";
  #endif
      int gid = (int)getgid();
--- 107,114 ----
      register char *s;
      char *index(), *strcpy(), *getenv();
      bool dosearch = FALSE;
      char **origargv = argv;
+ #ifdef DOSUID
      char *validarg = "";
  #endif
      int gid = (int)getgid();
***************
*** 569,574 ****
--- 574,582 ----
  	    apush(argvstab->stab_array,str_make(argv[0]));
  	}
      }
+ #ifdef TAINT
+     (void) stabent("ENV",TRUE);		/* must test PATH and IFS */
+ #endif
      if (envstab = stabent("ENV",allstabs)) {
  	hadd(envstab);
  	for (; *env; env++) {
***************
*** 587,598 ****
      if (sigstab = stabent("SIG",allstabs))
  	hadd(sigstab);
  
!     magicalize("!#?^~=-%0123456789.+&*()<>,\\/[|`'");
  
      amperstab = stabent("&",allstabs);
      leftstab = stabent("`",allstabs);
      rightstab = stabent("'",allstabs);
      sawampersand = (amperstab || leftstab || rightstab);
  
      /* these aren't necessarily magical */
      if (tmpstab = stabent(";",allstabs))
--- 595,608 ----
      if (sigstab = stabent("SIG",allstabs))
  	hadd(sigstab);
  
!     magicalize("!#?^~=-%0123456789.+&*()<>,\\/[|`':");
  
      amperstab = stabent("&",allstabs);
      leftstab = stabent("`",allstabs);
      rightstab = stabent("'",allstabs);
      sawampersand = (amperstab || leftstab || rightstab);
+     if (tmpstab = stabent(":",allstabs))
+ 	str_set(STAB_STR(tmpstab),chopset);
  
      /* these aren't necessarily magical */
      if (tmpstab = stabent(";",allstabs))

Index: stab.c
Prereq: 2.0.1.6
*** stab.c.old	Tue Nov 22 01:22:11 1988
--- stab.c	Tue Nov 22 01:22:14 1988
***************
*** 1,6 ****
! /* $Header: stab.c,v 2.0.1.6 88/11/19 00:19:26 lwall Exp $
   *
   * $Log:	stab.c,v $
   * Revision 2.0.1.6  88/11/19  00:19:26  lwall
   * patch16: $@ now reports correct error line after do EXPR
   * patch16: now makes use of setre[ug]id() if available
--- 1,9 ----
! /* $Header: stab.c,v 2.0.1.7 88/11/22 01:15:37 lwall Locked $
   *
   * $Log:	stab.c,v $
+  * Revision 2.0.1.7  88/11/22  01:15:37  lwall
+  * patch18: added $: to specify breakable characters in formats
+  * 
   * Revision 2.0.1.6  88/11/19  00:19:26  lwall
   * patch16: $@ now reports correct error line after do EXPR
   * patch16: now makes use of setre[ug]id() if available
***************
*** 372,377 ****
--- 375,383 ----
  	    fatal("setegid() not implemented");
  #endif
  #endif
+ 	    break;
+ 	case ':':
+ 	    chopset = str_get(str);
  	    break;
  	case '.':
  	case '+':

Index: str.c
Prereq: 2.0.1.4
*** str.c.old	Tue Nov 22 01:22:20 1988
--- str.c	Tue Nov 22 01:22:22 1988
***************
*** 1,6 ****
! /* $Header: str.c,v 2.0.1.4 88/11/19 00:21:57 lwall Exp $
   *
   * $Log:	str.c,v $
   * Revision 2.0.1.4  88/11/19  00:21:57  lwall
   * patch16: "taint" checks for setuid scripts
   * 
--- 1,9 ----
! /* $Header: str.c,v 2.0.1.5 88/11/22 01:18:37 lwall Locked $
   *
   * $Log:	str.c,v $
+  * Revision 2.0.1.5  88/11/22  01:18:37  lwall
+  * patch18: string variables referenced numerically can later lose string value
+  * 
   * Revision 2.0.1.4  88/11/19  00:21:57  lwall
   * patch16: "taint" checks for setuid scripts
   * 
***************
*** 165,174 ****
  #endif
      if (!sstr)
  	str_nset(dstr,No,0);
      else if (sstr->str_nok)
  	str_numset(dstr,sstr->str_nval);
-     else if (sstr->str_pok)
- 	str_nset(dstr,sstr->str_ptr,sstr->str_cur);
      else
  	str_nset(dstr,"",0);
  }
--- 168,182 ----
  #endif
      if (!sstr)
  	str_nset(dstr,No,0);
+     else if (sstr->str_pok) {
+ 	str_nset(dstr,sstr->str_ptr,sstr->str_cur);
+ 	if (sstr->str_nok) {
+ 	    dstr->str_nval = sstr->str_nval;
+ 	    dstr->str_nok = 1;
+ 	}
+     }
      else if (sstr->str_nok)
  	str_numset(dstr,sstr->str_nval);
      else
  	str_nset(dstr,"",0);
  }

Index: toke.c
Prereq: 2.0.1.6
*** toke.c.old	Tue Nov 22 01:22:31 1988
--- toke.c	Tue Nov 22 01:22:35 1988
***************
*** 1,6 ****
! /* $Header: toke.c,v 2.0.1.6 88/11/19 00:25:21 lwall Exp $
   *
   * $Log:	toke.c,v $
   * Revision 2.0.1.6  88/11/19  00:25:21  lwall
   * patch16: added getc function
   * patch16: variables in patterns are no longer hidden from -w typo detection
--- 1,9 ----
! /* $Header: toke.c,v 2.0.1.7 88/11/22 01:20:15 lwall Locked $
   *
   * $Log:	toke.c,v $
+  * Revision 2.0.1.7  88/11/22  01:20:15  lwall
+  * patch18: $) wouldn't interpolate in "eff gid = $)"
+  * 
   * Revision 2.0.1.6  88/11/19  00:25:21  lwall
   * patch16: added getc function
   * patch16: variables in patterns are no longer hidden from -w typo detection
***************
*** 1075,1080 ****
--- 1078,1084 ----
      register ARG *arg;
      register bool makesingle = FALSE;
      register STAB *stab;
+     bool alwaysdollar = FALSE;
      char *leave = "\\$nrtfb0123456789";	/* which backslash sequences to keep */
  
      arg = op_new(1);
***************
*** 1207,1216 ****
--- 1211,1222 ----
      case '"': 
  	arg[1].arg_type = A_DOUBLE;
  	makesingle = TRUE;	/* maybe disable runtime scanning */
+ 	alwaysdollar = TRUE;	/* treat $) and $| as variables */
  	term = *s;
  	goto snarf_it;
      case '`':
  	arg[1].arg_type = A_BACKTICK;
+ 	alwaysdollar = TRUE;	/* treat $) and $| as variables */
  	term = *s;
        snarf_it:
  	{
***************
*** 1241,1250 ****
  	    s = tmpstr->str_ptr;
  	    while (*s) {		/* see if we can make SINGLE */
  		if (*s == '\\' && s[1] && isdigit(s[1]) && !isdigit(s[2]) &&
! 		  !index("`\"",term) )
  		    *s = '$';		/* grandfather \digit in subst */
  		if (*s == '$' && s[1] &&
! 		  (index("`\"",term) || (s[1] != ')' && s[1] != '|'))) {
  		    makesingle = FALSE;	/* force interpretation */
  		}
  		else if (*s == '\\' && s[1]) {
--- 1247,1256 ----
  	    s = tmpstr->str_ptr;
  	    while (*s) {		/* see if we can make SINGLE */
  		if (*s == '\\' && s[1] && isdigit(s[1]) && !isdigit(s[2]) &&
! 		  !alwaysdollar )
  		    *s = '$';		/* grandfather \digit in subst */
  		if (*s == '$' && s[1] &&
! 		  (alwaysdollar || (s[1] != ')' && s[1] != '|'))) {
  		    makesingle = FALSE;	/* force interpretation */
  		}
  		else if (*s == '\\' && s[1]) {
***************
*** 1254,1260 ****
  	    }
  	    s = d = tmpstr->str_ptr;	/* assuming shrinkage only */
  	    while (*s) {
! 		if (*s == '$' && s[1] && s[1] != ')' && s[1] != '|') {
  		    int len;
  
  		    len = scanreg(s,tokenbuf) - s;
--- 1260,1267 ----
  	    }
  	    s = d = tmpstr->str_ptr;	/* assuming shrinkage only */
  	    while (*s) {
! 		if (*s == '$' && s[1] &&
! 		    (alwaysdollar || (s[1] != ')' && s[1] != '|')) ) {
  		    int len;
  
  		    len = scanreg(s,tokenbuf) - s;



More information about the Comp.sources.bugs mailing list