[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: New versions of openbsd_{basename,dirname}.c



Svante Signell, le Tue 17 Jan 2012 09:04:45 +0100, a écrit :
> 	static char *bname = NULL;
> 	register const char *endp, *startp;
> 
> 	bname = strdup(path);

You need to free bname before assigning something else, otherwise
nothing will ever free it. There is also no need for strdup, use
malloc(strlen(path)+1), since in all cases something will be strcpy-ed to
it. Also, put it below this:

> 	/* Empty or NULL string gets treated as "." */
> 	if (path == NULL || *path == '\0') {
> 		(void)strcpy(bname, ".");
> 		return(bname);
> 	}

Since otherwise when path is NULL strdup or strlen will just segfault;
Of course you'll need to replace strcpy(bname,".") with free(bname);
bname = strdup(".").

> 	/* Strip trailing slashes */
> 	endp = path + strlen(path) - 1;
> 	while (endp > path && *endp == '/')
> 		endp--;
> 
> 	/* All slashes becomes "/" */
> 	if (endp == path && *endp == '/') {
> 		(void)strcpy(bname, "/");
> 		return(bname);
> 	}
> 
> 	/* Find the start of the base */
> 	startp = endp;
> 	while (startp > path && *(startp - 1) != '/')
> 		startp--;
> 
> 	if (endp - startp + 1 > sizeof(bname)) {

Drop this test, it has become completely bogus now that bname is a
pointer, sizeof(bname) will just be typically 4.

> 		errno = ENAMETOOLONG;
> 		return(NULL);
> 	}
> 	(void)strncpy(bname, startp, endp - startp + 1);
> 	bname[endp - startp + 1] = '\0';
> 	return(bname);
> }



> 	const char *path;
> {
> 	static char *bname = NULL;
> 	register const char *endp;
> 
> 	/* Empty or NULL string gets treated as "." */
> 	if (path == NULL || *path == '\0') {

Ditto: you need to free the previous value of bname first:

> 		bname = malloc(2);
> 		(void)strcpy(bname, ".");

and you could just use bname = strdup(".") instead.

> 		return(bname);
> 	}
> 
> 	bname = strdup(path);

Ditto, replace this with a malloc.

> 	/* Strip trailing slashes */
> 	endp = path + strlen(path) - 1;
> 	while (endp > path && *endp == '/')
> 		endp--;
> 
> 	/* Find the start of the dir */
> 	while (endp > path && *endp != '/')
> 		endp--;
> 
> 	/* Either the dir is "/" or there are no slashes */
> 	if (endp == path) {
> 		(void)strcpy(bname, *endp == '/' ? "/" : ".");
> 		return(bname);
> 	} else {
> 		do {
> 			endp--;
> 		} while (endp > path && *endp == '/');
> 	}
> 
> 	if (endp - path + 1 > strlen(bname)) {

Ditto. This test is now meaningless.

> 		errno = ENAMETOOLONG;
> 		return(NULL);
> 	}
> 	(void)strncpy(bname, path, endp - path + 1);
> 	bname[endp - path + 1] = '\0';
> 	return(bname);
> }


Reply to: