* path.cc: Include malloc.h for alloca.
(is_symlink): Rewrite. Just read the whole file in memory rather than by parts. Account for an ITEMIDLIST if present, as well as the new style of Cygwin shortcut supporting targets > MAX_PATH.
This commit is contained in:
		| @@ -1,3 +1,10 @@ | ||||
| 2008-03-16  Brian Dessent  <brian@dessent.net> | ||||
|  | ||||
| 	* path.cc: Include malloc.h for alloca. | ||||
| 	(is_symlink): Rewrite.  Just read the whole file in memory rather | ||||
| 	than by parts.  Account for an ITEMIDLIST if present, as well as | ||||
| 	the new style of Cygwin shortcut supporting targets > MAX_PATH. | ||||
|  | ||||
| 2008-03-12  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* cygpath.cc (do_sysfolders): Use cygwin_conv_path. | ||||
|   | ||||
| @@ -18,6 +18,7 @@ details. */ | ||||
| #include <windows.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <malloc.h> | ||||
| #include "path.h" | ||||
| #include "cygwin/include/cygwin/version.h" | ||||
| #include "cygwin/include/sys/mount.h" | ||||
| @@ -172,60 +173,57 @@ is_symlink (HANDLE fh) | ||||
| bool | ||||
| readlink (HANDLE fh, char *path, int maxlen) | ||||
| { | ||||
|   int got; | ||||
|   int magic = get_word (fh, 0x0); | ||||
|   DWORD rv; | ||||
|   char *buf, *cp; | ||||
|   unsigned short len; | ||||
|   win_shortcut_hdr *file_header; | ||||
|   BY_HANDLE_FILE_INFORMATION fi; | ||||
|  | ||||
|   if (magic == SHORTCUT_MAGIC) | ||||
|   if (!GetFileInformationByHandle (fh, &fi) | ||||
|       || fi.nFileSizeHigh != 0 | ||||
|       || fi.nFileSizeLow > 8192) | ||||
|     return false; | ||||
|  | ||||
|   buf = (char *) alloca (fi.nFileSizeLow + 1); | ||||
|   file_header = (win_shortcut_hdr *) buf; | ||||
|  | ||||
|   if (SetFilePointer (fh, 0L, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER | ||||
|       || !ReadFile (fh, buf, fi.nFileSizeLow, &rv, NULL) | ||||
|       || rv != fi.nFileSizeLow) | ||||
|     return false; | ||||
|    | ||||
|   if (fi.nFileSizeLow > sizeof (file_header) | ||||
|       && cmp_shortcut_header (file_header)) | ||||
|     { | ||||
|       int offset = get_word (fh, 0x4c); | ||||
|       int slen = get_word (fh, 0x4c + offset + 2); | ||||
|       if (slen >= maxlen) | ||||
| 	{ | ||||
| 	  SetLastError (ERROR_FILENAME_EXCED_RANGE); | ||||
| 	  return false; | ||||
| 	} | ||||
|       if (SetFilePointer (fh, 0x4c + offset + 4, 0, FILE_BEGIN) == | ||||
| 	  INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR) | ||||
| 	return false; | ||||
|  | ||||
|       if (!ReadFile (fh, path, slen, (DWORD *) &got, 0)) | ||||
| 	return false; | ||||
|       else if (got < slen) | ||||
| 	{ | ||||
| 	  SetLastError (ERROR_READ_FAULT); | ||||
| 	  return false; | ||||
| 	} | ||||
|       else | ||||
| 	path[got] = '\0'; | ||||
|       cp = buf + sizeof (win_shortcut_hdr); | ||||
|       if (file_header->flags & WSH_FLAG_IDLIST) /* Skip ITEMIDLIST */ | ||||
|         cp += *(unsigned short *) cp + 2; | ||||
|       if (!(len = *(unsigned short *) cp)) | ||||
|         return false; | ||||
|       cp += 2; | ||||
|       /* Has appended full path?  If so, use it instead of description. */ | ||||
|       unsigned short relpath_len = *(unsigned short *) (cp + len); | ||||
|       if (cp + len + 2 + relpath_len < buf + fi.nFileSizeLow) | ||||
|         { | ||||
|           cp += len + 2 + relpath_len; | ||||
|           len = *(unsigned short *) cp; | ||||
|           cp += 2; | ||||
|         } | ||||
|       if (len + 1 > maxlen) | ||||
|         return false; | ||||
|       memcpy (path, cp, len); | ||||
|       path[len] = '\0'; | ||||
|       return true; | ||||
|     } | ||||
|   else if (magic == SYMLINK_MAGIC) | ||||
|   else if (strncmp (buf, SYMLINK_COOKIE, strlen (SYMLINK_COOKIE)) == 0 | ||||
|            && fi.nFileSizeLow - strlen (SYMLINK_COOKIE) <= (unsigned) maxlen | ||||
|            && buf[fi.nFileSizeLow - 1] == '\0') | ||||
|     { | ||||
|       char cookie_buf[sizeof (SYMLINK_COOKIE) - 1]; | ||||
|  | ||||
|       if (SetFilePointer (fh, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER | ||||
| 	  && GetLastError () != NO_ERROR) | ||||
| 	return false; | ||||
|  | ||||
|       if (!ReadFile (fh, cookie_buf, sizeof (cookie_buf), (DWORD *) &got, 0)) | ||||
| 	return false; | ||||
|       else if (got == sizeof (cookie_buf) | ||||
| 	       && memcmp (cookie_buf, SYMLINK_COOKIE, sizeof (cookie_buf)) == 0) | ||||
| 	{ | ||||
| 	  if (!ReadFile (fh, path, maxlen, (DWORD *) &got, 0)) | ||||
| 	    return false; | ||||
| 	  else if (got >= maxlen) | ||||
| 	    { | ||||
| 	      SetLastError (ERROR_FILENAME_EXCED_RANGE); | ||||
| 	      path[0] = '\0'; | ||||
| 	      return false; | ||||
| 	    } | ||||
| 	  else | ||||
| 	    path[got] = '\0'; | ||||
| 	} | ||||
|       strcpy (path, &buf[strlen (SYMLINK_COOKIE)]); | ||||
|       return true; | ||||
|     }       | ||||
|   else | ||||
|     return false; | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| typedef struct mnt | ||||
|   | ||||
		Reference in New Issue
	
	Block a user