[Bug: 21.5-b27] [CRASH] (file-name-directory "1:")

stephen at xemacs.org stephen
Wed Nov 1 10:00:44 EST 2006


Adrian Aichner writes:

 > Just evaluate
 > (file-name-directory "1:")
 > in the *scratch* buffer (without any unsaved autobiographies or other
 > work close to your heart).

This is only a problem on Windows.  Here's the problem, I think, in
fileio.c:find_end_of_directory_component:

------------------------------------------------------------------------
  while (p != path && !IS_DIRECTORY_SEP (p[-1])
#ifdef WIN32_FILENAMES
	 /* only recognise drive specifier at the beginning */
	 && !(p[-1] == ':'
	      /* handle the "/:d:foo" and "/:foo" cases correctly  */
	      && ((p == path + 2 && !IS_DIRECTORY_SEP (*path))
		  || (p == path + 4 && IS_DIRECTORY_SEP (*path))))
#endif
	 ) p--;
------------------------------------------------------------------------

This code doesn't check whether the X in "X:" is a valid drive letter
or not!  My guess would be that if X is a valid drive letter, you
won't have a problem.  Could you try `(file-name-directory "X:")' for
X = "C" and X = "S" (or some other letter that definitely isn't mapped
to a drive on your system)?  I'll bet that it crashes for X = ".", or
anything else that isn't a valid drive letter, too.

Even if it doesn't fix the crash, if the IS_VALID_DRIVE_LETTER macro
exists, then it seems to me the above fragment should be

------------------------------------------------------------------------
  while (p != path && !IS_DIRECTORY_SEP (p[-1])
#ifdef WIN32_FILENAMES
	 /* only recognise drive specifier at the beginning */
	 && !(p == path + 2 && path[1] == ':' && IS_VALID_DRIVE_LETTER (*path))
#endif
	 ) p--;
------------------------------------------------------------------------

It might be even more sane (not to mention faster) to

------------------------------------------------------------------------
#ifdef WIN32_FILENAMES
  const Ibyte *beg = (path[0] && path[1] && path[1] == ':'
                      && IS_VALID_DRIVE_LETTER (path[0])) ? path + 2 : path;
#else
  const Ibyte *beg = path;
#endif

  while (p != beg && !IS_DIRECTORY_SEP (p[-1])) p--;
------------------------------------------------------------------------

don't you think?



More information about the XEmacs-Beta mailing list