[Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.215,2.216

Tim Peters tim_one@users.sourceforge.net
Wed, 19 Dec 2001 11:05:04 -0800


Update of /cvsroot/python/python/dist/src/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv13624/python/Modules

Modified Files:
	posixmodule.c 
Log Message:
SF bug #495021:  Crash calling os.stat with a trailing backslash
Patch from Mark Hammond, plus code rearrangement and comments from me.
posix_do_stat():  Windows-specific code could try to free() stack
memory in some cases when a path ending with a forward or backward slash
was passed to os.stat().


Index: posixmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v
retrieving revision 2.215
retrieving revision 2.216
diff -C2 -d -r2.215 -r2.216
*** posixmodule.c	2001/12/08 18:02:57	2.215
--- posixmodule.c	2001/12/19 19:05:01	2.216
***************
*** 680,689 ****
  {
  	STRUCT_STAT st;
! 	char *path = NULL;
  	int res;
  
  #ifdef MS_WIN32
!       int pathlen;
!       char pathcopy[MAX_PATH];
  #endif /* MS_WIN32 */
  
--- 680,690 ----
  {
  	STRUCT_STAT st;
! 	char *path = NULL;	/* pass this to stat; do not free() it */
! 	char *pathfree = NULL;  /* this memory must be free'd */
  	int res;
  
  #ifdef MS_WIN32
! 	int pathlen;
! 	char pathcopy[MAX_PATH];
  #endif /* MS_WIN32 */
  
***************
*** 691,694 ****
--- 692,696 ----
  	                      Py_FileSystemDefaultEncoding, &path))
  		return NULL;
+ 	pathfree = path;
  
  #ifdef MS_WIN32
***************
*** 696,713 ****
  	/* the library call can blow up if the file name is too long! */
  	if (pathlen > MAX_PATH) {
! 		PyMem_Free(path);
  		errno = ENAMETOOLONG;
  		return posix_error();
  	}
  
! 	if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
! 		/* exception for specific or current drive root */
! 		if (!((pathlen == 1) ||
! 		      ((pathlen == 3) &&
! 		      (path[1] == ':') &&
! 		      (path[2] == '\\' || path[2] == '/'))))
! 		{
  			strncpy(pathcopy, path, pathlen);
! 			pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
  			path = pathcopy;
  		}
--- 698,719 ----
  	/* the library call can blow up if the file name is too long! */
  	if (pathlen > MAX_PATH) {
! 		PyMem_Free(pathfree);
  		errno = ENAMETOOLONG;
  		return posix_error();
  	}
  
! 	/* Remove trailing slash or backslash, unless it's the current
! 	   drive root (/ or \) or a specific drive's root (like c:\ or c:/).
! 	*/
! 	if (pathlen > 0 &&
! 	    (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
! 	    	/* It does end with a slash -- exempt the root drive cases. */
! 	    	/* XXX UNC root drives should also be exempted? */
! 	    	if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
! 	    		/* leave it alone */;
! 	    	else {
! 			/* nuke the trailing backslash */
  			strncpy(pathcopy, path, pathlen);
! 			pathcopy[pathlen-1] = '\0';
  			path = pathcopy;
  		}
***************
*** 719,725 ****
  	Py_END_ALLOW_THREADS
  	if (res != 0)
! 		return posix_error_with_allocated_filename(path);
  
! 	PyMem_Free(path);
  	return _pystat_fromstructstat(st);
  }
--- 725,731 ----
  	Py_END_ALLOW_THREADS
  	if (res != 0)
! 		return posix_error_with_allocated_filename(pathfree);
  
! 	PyMem_Free(pathfree);
  	return _pystat_fromstructstat(st);
  }