changeset 4786:6e6f7b79c1fc

xemacs: fix issue 634 -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2009-11-27 Adrian Aichner <adrian@xemacs.org> * nt.c (mswindows_getdcwd): Check first whether drive is valid with _getdrives() to avoid crash in _wgetdcwd(...) when linking against msvcrt8. This fix was taken from the Mozilla project which experienced the same problem.
author Adrian Aichner <adrian@xemacs.org>
date Fri, 27 Nov 2009 00:51:41 +0100
parents 217abcf015c4
children 56049bea9231
files src/ChangeLog src/nt.c
diffstat 2 files changed, 28 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Thu Nov 19 18:21:06 2009 -0500
+++ b/src/ChangeLog	Fri Nov 27 00:51:41 2009 +0100
@@ -1,3 +1,10 @@
+2009-11-27  Adrian Aichner  <adrian@xemacs.org>
+
+	* nt.c (mswindows_getdcwd): Check first whether drive is valid
+	with _getdrives() to avoid crash in _wgetdcwd(...) when linking
+	against msvcrt8.  This fix was taken from the Mozilla project
+	which experienced the same problem.
+
 2009-11-19  Vin Shelton  <acs@xemacs.org>
 
 	* sysdep.c (sys_subshell): Restore sys_subshell(); it's necessary
--- a/src/nt.c	Thu Nov 19 18:21:06 2009 -0500
+++ b/src/nt.c	Fri Nov 27 00:51:41 2009 +0100
@@ -1815,7 +1815,27 @@
 {
   Extbyte *cwdext;
   Ibyte *cwd;
-
+  /* Following comment and two-liner fix comes from
+     https://bugzilla.mozilla.org/show_bug.cgi?id=419326 which
+     apparently fell prey to this feature of msvcrt8 as well. */
+  /* We need to worry about IPH, for details read bug 419326.
+   * _getdrives - http://msdn2.microsoft.com/en-us/library/xdhk0xd2.aspx 
+   * uses a bitmask, bit 0 is 'a:'
+   * _chdrive - http://msdn2.microsoft.com/en-us/library/0d1409hb.aspx
+   * _getdcwd - http://msdn2.microsoft.com/en-us/library/7t2zk3s4.aspx
+   * take an int, 1 is 'a:'.
+   *
+   * Because of this, we need to do some math. Subtract 1 to convert from
+   * _chdrive/_getdcwd format to _getdrives drive numbering.
+   * Shift left x bits to convert from integer indexing to bitfield indexing.
+   * And of course, we need to find out if the drive is in the bitmask.
+   *
+   * If we're really unlucky, we can still lose, but only if the user
+   * manages to eject the drive between our call to _getdrives() and
+   * our *calls* to _wgetdcwd.
+   */
+  if (!((1 << (drivelet - 1)) & _getdrives()))
+    return NULL;
   if (XEUNICODE_P)
     cwdext = (Extbyte *) _wgetdcwd (drivelet, NULL, 0);
   else