* fhandler_registry.cc (must_encode): New function.
(encode_regname): Ditto. (decode_regname): Ditto. (fhandler_registry::exists): Encode name before path compare. (fhandler_registry::fstat): Pass decoded name to win32 registry call. (fhandler_registry::readdir): Return encoded name to user. (fhandler_registry::open): Store decoded name into value_name. (open_key): Pass decoded name to win32 registry call.
This commit is contained in:
		| @@ -1,3 +1,14 @@ | ||||
| 2008-12-01  Christian Franke  <franke@computer.org> | ||||
|  | ||||
| 	* fhandler_registry.cc (must_encode): New function. | ||||
| 	(encode_regname): Ditto. | ||||
| 	(decode_regname): Ditto. | ||||
| 	(fhandler_registry::exists): Encode name before path compare. | ||||
| 	(fhandler_registry::fstat): Pass decoded name to win32 registry call. | ||||
| 	(fhandler_registry::readdir): Return encoded name to user. | ||||
| 	(fhandler_registry::open): Store decoded name into value_name. | ||||
| 	(open_key): Pass decoded name to win32 registry call | ||||
|  | ||||
| 2008-11-28  Christopher Faylor  <me+cygwin@cgf.cx> | ||||
|  | ||||
| 	* exceptions.c (sigpacket::process): Set tls on return since it is | ||||
|   | ||||
| @@ -11,6 +11,7 @@ details. */ | ||||
| /* FIXME: Access permissions are ignored at the moment.  */ | ||||
|  | ||||
| #include "winsup.h" | ||||
| #include <stdlib.h> | ||||
| #include "cygerrno.h" | ||||
| #include "security.h" | ||||
| #include "path.h" | ||||
| @@ -79,6 +80,69 @@ static const char *DEFAULT_VALUE_NAME = "@"; | ||||
|  | ||||
| static HKEY open_key (const char *name, REGSAM access, DWORD wow64, bool isValue); | ||||
|  | ||||
| /* Return true if char must be encoded. | ||||
|  */ | ||||
| static inline bool | ||||
| must_encode (char c) | ||||
| { | ||||
|   return (isdirsep (c) || c == '%'); | ||||
| } | ||||
|  | ||||
| /* Encode special chars in registry key or value name. | ||||
|  */ | ||||
| static int | ||||
| encode_regname (char * dst, const char * src) | ||||
| { | ||||
|   int di = 0; | ||||
|   for (int si = 0; src[si]; si++) | ||||
|     { | ||||
|       char c = src[si]; | ||||
|       if (must_encode (c) || | ||||
| 	  (c == '.' && si == 0 && (!src[1] || (src[1] == '.' && !src[2])))) | ||||
| 	{ | ||||
| 	  if (di + 3 >= NAME_MAX + 1) | ||||
| 	    return ENAMETOOLONG; | ||||
| 	  __small_sprintf (dst + di, "%%%02x", c); | ||||
| 	  di += 3; | ||||
| 	} | ||||
|       else | ||||
| 	dst[di++] = c; | ||||
|     } | ||||
|   dst[di] = 0; | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| /* Decode special chars in registry key or value name. | ||||
|  */ | ||||
| static int | ||||
| decode_regname (char * dst, const char * src, int len = -1) | ||||
| { | ||||
|   if (len < 0) | ||||
|     len = strlen (src); | ||||
|   int di = 0; | ||||
|   for (int si = 0; si < len; si++) | ||||
|     { | ||||
|       char c = src[si]; | ||||
|       if (c == '%') | ||||
| 	{ | ||||
| 	  if (si + 2 >= len) | ||||
| 	    return EINVAL; | ||||
| 	  char s[] = {src[si+1], src[si+2], '\0'}; | ||||
| 	  char *p; | ||||
| 	  c = strtoul (s, &p, 16); | ||||
| 	  if (!(must_encode (c) || | ||||
| 	        (c == '.' && si == 0 && (len == 3 || (src[3] == '.' && len == 4))))) | ||||
| 	    return EINVAL; | ||||
| 	  dst[di++] = c; | ||||
| 	  si += 2; | ||||
| 	} | ||||
|       else | ||||
| 	dst[di++] = c; | ||||
|     } | ||||
|   dst[di] = 0; | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| /* Returns 0 if path doesn't exist, >0 if path is a directory, | ||||
|  * <0 if path is a file. | ||||
|  * | ||||
| @@ -159,8 +223,9 @@ fhandler_registry::exists () | ||||
| 				    NULL, NULL)) | ||||
| 	     || (error == ERROR_MORE_DATA)) | ||||
| 	{ | ||||
| 	  if (strcasematch (buf, file) | ||||
| 	      || (buf[0] == '\0' && strcasematch (file, DEFAULT_VALUE_NAME))) | ||||
| 	  char enc_buf[NAME_MAX + 1]; | ||||
| 	  if (   (buf[0] == '\0' && strcasematch (file, DEFAULT_VALUE_NAME)) | ||||
| 	      || (!encode_regname (enc_buf, buf) && strcasematch (enc_buf, file))) | ||||
| 	    { | ||||
| 	      file_type = -1; | ||||
| 	      goto out; | ||||
| @@ -257,9 +322,11 @@ fhandler_registry::fstat (struct __stat64 *buf) | ||||
| 		  while (!isdirsep (*value_name)) | ||||
| 		    value_name--; | ||||
| 		  value_name++; | ||||
| 		  char dec_value_name[NAME_MAX + 1]; | ||||
| 		  DWORD dwSize; | ||||
| 		  if (ERROR_SUCCESS == | ||||
| 		      RegQueryValueEx (hKey, value_name, NULL, NULL, NULL, | ||||
| 		  if (!decode_regname (dec_value_name, value_name) && | ||||
| 		      ERROR_SUCCESS == | ||||
| 		      RegQueryValueEx (hKey, dec_value_name, NULL, NULL, NULL, | ||||
| 				       &dwSize)) | ||||
| 		    buf->st_size = dwSize; | ||||
| 		} | ||||
| @@ -360,8 +427,8 @@ retry: | ||||
|   /* We get here if `buf' contains valid data.  */ | ||||
|   if (*buf == 0) | ||||
|     strcpy (de->d_name, DEFAULT_VALUE_NAME); | ||||
|   else | ||||
|     strcpy (de->d_name, buf); | ||||
|   else if (encode_regname (de->d_name, buf)) | ||||
|     goto retry; | ||||
|  | ||||
|   dir->__d_position++; | ||||
|   if (dir->__d_position & REG_ENUM_VALUES_MASK) | ||||
| @@ -505,6 +572,14 @@ fhandler_registry::open (int flags, mode_t mode) | ||||
|       goto out; | ||||
|     } | ||||
|  | ||||
|   char dec_file[NAME_MAX + 1]; | ||||
|   if (decode_regname (dec_file, file)) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       res = 0; | ||||
|       goto out; | ||||
|     } | ||||
|  | ||||
|   handle = open_key (path, KEY_READ, wow64, false); | ||||
|   if (handle == (HKEY) INVALID_HANDLE_VALUE) | ||||
|     { | ||||
| @@ -520,10 +595,10 @@ fhandler_registry::open (int flags, mode_t mode) | ||||
|  | ||||
|   set_io_handle (handle); | ||||
|  | ||||
|   if (strcasematch (file, DEFAULT_VALUE_NAME)) | ||||
|   if (strcasematch (dec_file, DEFAULT_VALUE_NAME)) | ||||
|     value_name = cstrdup (""); | ||||
|   else | ||||
|     value_name = cstrdup (file); | ||||
|     value_name = cstrdup (dec_file); | ||||
|  | ||||
|   if (!(flags & O_DIROPEN) && !fill_filebuf ()) | ||||
|     { | ||||
| @@ -661,8 +736,14 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue) | ||||
|       const char *anchor = name; | ||||
|       while (*name && !isdirsep (*name)) | ||||
| 	name++; | ||||
|       strncpy (component, anchor, name - anchor); | ||||
|       component[name - anchor] = '\0'; | ||||
|       if (decode_regname (component, anchor, name - anchor)) | ||||
|         { | ||||
| 	  set_errno (EINVAL); | ||||
| 	  if (parentOpened) | ||||
| 	    RegCloseKey (hParentKey); | ||||
| 	  hKey = (HKEY) INVALID_HANDLE_VALUE; | ||||
| 	  break; | ||||
| 	} | ||||
|       if (*name) | ||||
| 	name++; | ||||
|       if (*name == 0 && isValue == true) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user