[comp.soft-sys.andrew] difference of strlen

kaz@kate.mita.keio.ac.jp (Kazuhiro Kitagawa) (10/16/89)

The   bush program  runs RT-PC correctly, but
it does not run on Sun 3 sometime in paticular case.
 On Sun 3, it dumps core  with Segment violation when
searching the files with unknown uid.

---------bush.c ---------------
static void
AllocNameSpace( target, source )
    char	    **target, *source;
{
    if(!target) return;
    if(*target) free(*target);
    if(*target = malloc(strlen(source)+1)) 
	strcpy(*target,source);
}
------------------------------------------

The follwoing code includes  bug.
On RT-PC, strlen()  dose not dumps core, if source is NULL,
On Sun 3, strlen dumps core. 
Sometime  AllocNameSpace   is called as second arguement being NULL.

Because of, on RT-PC users can read address 0 and it value is NULL,
but, on Sun 3 we can not read address 0.



This  program(bush) should include   the follwoing code at first line.
static void
AllocNameSpace( target, source )
    char	    **target, *source;
{
    if(!source)return
    if(!target) return;
    if(*target) free(*target);
    if(*target = malloc(strlen(source)+1)) 
	strcpy(*target,source);
}


    Kaz. Kitagawa Phd. Candidate
    KEIO Univ. Dept of math.

guy@auspex.auspex.com (Guy Harris) (10/21/89)

(Well, here's hoping the bi-directional gateway mentioned in the beta
README file really gateways bi-directionally....)

 >The   bush program  runs RT-PC correctly, but
 >it does not run on Sun 3 sometime in paticular case.
 > On Sun 3, it dumps core  with Segment violation when
 >searching the files with unknown uid.

 ...

 >The follwoing code includes  bug.
 >On RT-PC, strlen()  dose not dumps core, if source is NULL,
 >On Sun 3, strlen dumps core. 
 >Sometime  AllocNameSpace   is called as second arguement being NULL.

If a program drops core on a machine that disallows NULL-pointer
dereferencing, it's trying to tell you something, and often trying to
tell you something about some routine other than the one dropping core. 
It's quite likely trying to tell you that either

	1) somebody's not checking for a NULL pointer result from some
	   routine

or

	2) some routine is generating a NULL pointer result when it's
	   not supposed to.

In this case, 2) is the answer.  The problem is that the
UID/cell-to-name translation routine properly deals with UIDs that have
no name in the AFS case, but not in the boring ordinary UNIX case.  In
the AFS case, it constructs a name from the decimal value of the UID and
the cell; in the boring ordinary UNIX case, it should do as "ls" does
and construct a name from just the decimal value of the UID. 

It should also, while it's at it, search the UidUnameMap vector that it
is taking the trouble to construct; it does so in the AFS case, but not
the boring ordinary UNIX case.  It looks as if the boring ordinary UNIX
case is incomplete; these changes appear to correctly complete it (and
render the change to AllocNameSpace unnecessary - and, in fact,
undesirable, since such a change could conceivably mask other errors
like this):

*** bush.c.dist	Thu Oct 19 16:51:15 1989
--- bush.c	Fri Oct 20 15:25:25 1989
***************
*** 365,373 ****
      int				 uid;
      char			*cell;
  {
- #ifdef AFS_ENV
      register int		 i = 0;
- #endif /* AFS_ENV */
      register struct map_item	*item = NULL;
      char			*uname = NULL;
      register struct passwd	*pw = NULL;
--- 365,371 ----
***************
*** 404,413 ****
--- 402,429 ----
  	}
      }
  #else /* AFS_ENV */
+     for( i = 0 ; i < vector_Count(UidUnameMap) ; i++ ) {
+ 	item = (struct map_item*)vector_Item(UidUnameMap,i);
+ 	if(uid == item->uid) {
+ 	    uname = item->uname;
+ 	    break;
+ 	}
+     }
      if(pw = getpwuid(uid)) {
  	item = (struct map_item*)calloc(1,sizeof(struct map_item));
  	item->uid = uid;
  	AllocNameSpace(&item->uname,pw->pw_name);
+ 	AllocNameSpace(&item->ucell,"");
+ 	vector_AddItem(UidUnameMap,(long)item);
+ 	uname = item->uname;
+     }
+     else {
+ 	char	    uid_str[200];
+ 
+ 	item = (struct map_item*)calloc(1,sizeof(struct map_item));
+ 	item->uid = uid;
+ 	sprintf(uid_str,"%d",uid);
+ 	AllocNameSpace(&item->uname,uid_str);
  	AllocNameSpace(&item->ucell,"");
  	vector_AddItem(UidUnameMap,(long)item);
  	uname = item->uname;

(Actually, it should probably be "%u" in the boring ordinary UNIX case,
and possibly in the equivalent code in the AFS case; in most UNIX
systems, UIDs are unsigned, and I expect other systems, such as SunOS,
to follow suit - SunOS in 4.1, for instance.)