[comp.sources.bugs] perl 3.0 patch #41

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (11/14/90)

System: perl version 3.0
Patch #: 41
Subject: fixed a couple of malloc/free problems
Subject: added advice for dnix
Subject: added hp malloc union overhead strut (that sounds very blue collar)

Description:
	Here's the requisite dinky patch to fix the problems of the
	preceding large set of patches.  In this case, a couple of
	malloc/free problems--one of which involved overrunning the end
	of an allocated string, and the other of which involved freeing
	with invalid pointers.  (There was also a bug in there involving
	variable magicalness propagating incorrectly, which resulting in
	a dbm anomoly.)

	I updated README to mention that dnix needs to avoid -O.

	I added the hp malloc union overhead strut that Jan Dr{rv posted.
	(Eventually this should be determined by Configure, but laziness
	has its advantages.)

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:
		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@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 3.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.1.143).

Index: patchlevel.h
Prereq: 40
1c1
< #define PATCHLEVEL 40
---
> #define PATCHLEVEL 41

Index: README
*** README.old	Tue Nov 13 15:27:58 1990
--- README	Tue Nov 13 15:28:03 1990
***************
*** 113,118 ****
--- 113,119 ----
      A/UX may need -ZP -DPOSIX, and -g if big cc is used.
      FPS machines may need -J and -DBADSWITCH.
      UTS may need one or more of -DCRIPPLED_CC, -K or -g, and undef LSTAT.
+     Dnix (not dynix) may need to remove -O.
      If you get syntax errors on '(', try -DCRIPPLED_CC or -DBADSWITCH or both.
      Machines with half-implemented dbm routines will need to #undef ODBM & NDBM.
      C's that don't try to restore registers on longjmp() may need -DJMPCLOBBER.

Index: malloc.c
Prereq: 3.0.1.3
*** malloc.c.old	Tue Nov 13 15:28:14 1990
--- malloc.c	Tue Nov 13 15:28:19 1990
***************
*** 1,6 ****
! /* $Header: malloc.c,v 3.0.1.3 90/10/16 15:27:47 lwall Locked $
   *
   * $Log:	malloc.c,v $
   * Revision 3.0.1.3  90/10/16  15:27:47  lwall
   * patch29: various portability fixes
   * 
--- 1,9 ----
! /* $Header: malloc.c,v 3.0.1.4 90/11/13 15:23:45 lwall Locked $
   *
   * $Log:	malloc.c,v $
+  * Revision 3.0.1.4  90/11/13  15:23:45  lwall
+  * patch41: added hp malloc union overhead strut (that sounds very blue collar)
+  * 
   * Revision 3.0.1.3  90/10/16  15:27:47  lwall
   * patch29: various portability fixes
   * 
***************
*** 56,62 ****
   */
  union	overhead {
  	union	overhead *ov_next;	/* when free */
! #if defined(mips) || defined(sparc) || defined(luna88k)
  	double  strut;			/* alignment problems */
  #endif
  	struct {
--- 59,65 ----
   */
  union	overhead {
  	union	overhead *ov_next;	/* when free */
! #if defined(mips) || defined(sparc) || defined(luna88k) || defined(hp9000s800)
  	double  strut;			/* alignment problems */
  #endif
  	struct {

Index: str.c
Prereq: 3.0.1.10
*** str.c.old	Tue Nov 13 15:28:47 1990
--- str.c	Tue Nov 13 15:28:59 1990
***************
*** 1,4 ****
! /* $Header: str.c,v 3.0.1.10 90/11/10 02:06:29 lwall Locked $
   *
   *    Copyright (c) 1989, Larry Wall
   *
--- 1,4 ----
! /* $Header: str.c,v 3.0.1.11 90/11/13 15:27:14 lwall Locked $
   *
   *    Copyright (c) 1989, Larry Wall
   *
***************
*** 6,11 ****
--- 6,14 ----
   *    as specified in the README file that comes with the perl 3.0 kit.
   *
   * $Log:	str.c,v $
+  * Revision 3.0.1.11  90/11/13  15:27:14  lwall
+  * patch41: fixed a couple of malloc/free problems
+  * 
   * Revision 3.0.1.10  90/11/10  02:06:29  lwall
   * patch38: temp string values are now copied less often
   * patch38: array slurps are now faster and take less memory
***************
*** 259,286 ****
  	/*
  	 * Check to see if we can just swipe the string.  If so, it's a
  	 * possible small lose on short strings, but a big win on long ones.
  	 */
  
  	if (sstr->str_pok & SP_TEMP) {		/* slated for free anyway? */
! 	    if (dstr->str_ptr)
  		Safefree(dstr->str_ptr);
! #ifdef STRUCTCOPY
! 	    *dstr = *sstr;
! #else
! 	    Copy(sstr, dstr, 1, STR);
  #endif
! 	    Zero(sstr, 1, STR);			/* (probably overkill) */
! 	    dstr->str_pok &= ~SP_TEMP;
  	}
! 	else {					/* have to copy piecemeal */
  	    str_nset(dstr,sstr->str_ptr,sstr->str_cur);
! 	    if (sstr->str_nok) {
! 		dstr->str_u.str_nval = sstr->str_u.str_nval;
! 		dstr->str_nok = 1;
! 		dstr->str_state = SS_NORM;
! 	    }
! 	    else if (sstr->str_cur == sizeof(STBP)) {
! 		char *tmps = sstr->str_ptr;
  
  		if (*tmps == 'S' && bcmp(tmps,"StB",4) == 0) {
  		    if (!dstr->str_magic) {
--- 262,302 ----
  	/*
  	 * Check to see if we can just swipe the string.  If so, it's a
  	 * possible small lose on short strings, but a big win on long ones.
+ 	 * It might even be a win on short strings if dstr->str_ptr
+ 	 * has to be allocated and sstr->str_ptr has to be freed.
  	 */
  
  	if (sstr->str_pok & SP_TEMP) {		/* slated for free anyway? */
! 	    if (dstr->str_ptr) {
! 		if (dstr->str_state == SS_INCR)
! 		    dstr->str_ptr -= dstr->str_u.str_useful;
  		Safefree(dstr->str_ptr);
! 	    }
! 	    dstr->str_ptr = sstr->str_ptr;
! 	    dstr->str_len = sstr->str_len;
! 	    dstr->str_cur = sstr->str_cur;
! 	    dstr->str_state = sstr->str_state;
! 	    dstr->str_pok = sstr->str_pok & ~SP_TEMP;
! #ifdef TAINT
! 	    dstr->str_tainted = sstr->str_tainted;
  #endif
! 	    sstr->str_ptr = Nullch;
! 	    sstr->str_len = 0;
! 	    sstr->str_pok = 0;			/* wipe out any weird flags */
! 	    sstr->str_state = 0;		/* so sstr frees uneventfully */
  	}
! 	else					/* have to copy actual string */
  	    str_nset(dstr,sstr->str_ptr,sstr->str_cur);
! 	if (dstr->str_nok = sstr->str_nok)
! 	    dstr->str_u.str_nval = sstr->str_u.str_nval;
! 	else {
! #ifdef STRUCTCOPY
! 	    dstr->str_u = sstr->str_u;
! #else
! 	    dstr->str_u.str_nval = sstr->str_u.str_nval;
! #endif
! 	    if (dstr->str_cur == sizeof(STBP)) {
! 		char *tmps = dstr->str_ptr;
  
  		if (*tmps == 'S' && bcmp(tmps,"StB",4) == 0) {
  		    if (!dstr->str_magic) {
***************
*** 763,770 ****
      str->str_pok = 1;			/* validate pointer */
      if (str->str_len <= cnt + 1) {	/* make sure we have the room */
  	if (cnt > 80 && str->str_len > 0) {
! 	    shortbuffered = cnt - str->str_len;
! 	    cnt = str->str_len;
  	}
  	else {
  	    shortbuffered = 0;
--- 779,786 ----
      str->str_pok = 1;			/* validate pointer */
      if (str->str_len <= cnt + 1) {	/* make sure we have the room */
  	if (cnt > 80 && str->str_len > 0) {
! 	    shortbuffered = cnt - str->str_len + 1;
! 	    cnt = str->str_len - 1;
  	}
  	else {
  	    shortbuffered = 0;

*** End of Patch 41 ***