[net.bugs.usg] SysV.2 make bugs

glenn@nsc.UUCP (Glenn Skinner) (06/21/84)

There are two bugs in the System V Release 2 version of make(1) that prevent
its archive dependency features from working properly.

The first concerns dependencies of the form:
	ofile:	lib(member)
If lib contains a member that appears before the desired one and its name is
a superstring of the name of the desired one, make will incorrectly use the
first member.

The second concerns dependencies of the form:
	ofile:	lib((symbol))
For archives generated under either System V release, this form of dependency
doesn't work at all.

In both cases, the bug is in files.c.  Two diff -c outputs follow, giving
fixes for the two bugs.  As I've made other changes to this file as well,
line numbers don't correspond to those of the original System V versions,
so you'll have to install the fixes by hand.  The fix for the superstring
bug also includes provisions for handling 4.1 and 4.2 bsd format archives.
If you don't want this behavior, omit clauses of the if as described in its
associated comment.

		-- Glenn Skinner
		National Semiconductor, Microprocessor Systems Division
		(408) 733-2600 x 335

*** files.c.1.3	Sun Jun 17 13:47:02 1984
--- files.c.1.4	Sun Jun 17 13:47:11 1984
***************
*** 495,505
  			{
  				if (feof(arfd))
  					return (0L);
  				break;
  			}
! 			if (equaln(ar_port.ar_name, name, len))
  			{
  				long date;
  
  				if (sscanf(ar_port.ar_date, "%ld", &date) != 1)
  				{

--- 495,517 -----
  			{
  				if (feof(arfd))
  					return (0L);
  				break;
  			}
! 			/*
! 			* The second clause of the comparison below guards
! 			* against matching superstrings of the desired name.
! 			* Its third and fourth clauses allow compatibility
! 			* with 4.x bsd archives.
! 			*/
! 			if (  equaln(ar_port.ar_name, name, len)
! 			   && (  len == sizeof ar_port.ar_name
! 			      || ar_port.ar_name[len] == '/'
! 			      || ar_port.ar_name[len] == ' '
! 			      || ar_port.ar_name[len] == '\0'
! 			      )
! 			   )
  			{
  				long date;
  
  				if (sscanf(ar_port.ar_date, "%ld", &date) != 1)
  				{

*** files.c.1.6	Sun Jun 17 13:57:07 1984
--- files.c.1.7	Sun Jun 17 13:57:20 1984
***************
*** 611,620
  				if (fread((char *)&arf_5,
  					sizeof(arf_5), 1, arfd) != 1)
  				{
  					goto read_error;
  				}
  				return (sgetl(arf_5.arf_date));
  			}
  		}
  	}
  	else if (ar_type == ARport) /* This line modified from original */

--- 611,628 -----
  				if (fread((char *)&arf_5,
  					sizeof(arf_5), 1, arfd) != 1)
  				{
  					goto read_error;
  				}
+ 
+ 				/*
+ 				* Bug fix follows: must replace symbol name
+ 				* with member name.
+ 				*/
+ 				strncpy(archmem, arf_5.arf_name,
+ 					sizeof arf_5.arf_name);
+ 
  				return (sgetl(arf_5.arf_date));
  			}
  		}
  	}
  	else if (ar_type == ARport) /* This line modified from original */
***************
*** 655,664
  		while (syms < strend)
  		{
  			if (equal(syms, name))
  			{
  				long ptr, date;
  
  				ptr = sgetl(offs);
  				if (fseek(arfd, ptr, 0) != 0)
  					goto seek_error;
  				if (fread((char *)&ar_port, sizeof(ar_port), 1,

--- 663,673 -----
  		while (syms < strend)
  		{
  			if (equal(syms, name))
  			{
  				long ptr, date;
+ 				register char *ap, *hp;
  
  				ptr = sgetl(offs);
  				if (fseek(arfd, ptr, 0) != 0)
  					goto seek_error;
  				if (fread((char *)&ar_port, sizeof(ar_port), 1,
***************
*** 671,680
  				{
  				date_error:
  					fatal1("Bad date for %.14s, archive %s",
  						ar_port.ar_name, archname);
  				}
  				free(strbeg);
  				return (date);
  			}
  			syms += strlen(syms) + 1;
  			offs += sizeof(long);

--- 680,701 -----
  				{
  				date_error:
  					fatal1("Bad date for %.14s, archive %s",
  						ar_port.ar_name, archname);
  				}
+ 
+ 				/*
+ 				* Bug fix follows: must replace symbol name
+ 				* with member name.
+ 				*/
+ 				ap = archmem;
+ 				hp = ar_port.ar_name;
+ 				while (  *hp && *hp != '/'
+ 				      && ap < archmem + sizeof archmem
+ 				      )
+ 					*ap++ = *hp++;
+ 
  				free(strbeg);
  				return (date);
  			}
  			syms += strlen(syms) + 1;
  			offs += sizeof(long);