Saw the following bug report on the XEmacs developer list. The code
in fileio.c in Emacs is very much identical, lines 446 and 472 would
seem to be relevant to the problem.
I don't have a Windows Emacs available, so I can't vouch for this
actually crashing Emacs too, but I consider it quite likely.
Somebody using Windows better check this.
------------------------------------------------------------------------
Subject:
[Bug: 21.5-b27] [CRASH] (file-name-directory "1:")
From:
address@hidden
Date:
Wed, 01 Nov 2006 23:41:46 +0900
CC:
XEmacs Beta <address@hidden>
Newsgroups:
gmane.emacs.xemacs.beta
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?