* 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:
parent
c4f3555ecb
commit
651d8393c8
@ -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>
|
2008-11-28 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* exceptions.c (sigpacket::process): Set tls on return since it is
|
* exceptions.c (sigpacket::process): Set tls on return since it is
|
||||||
|
@ -11,6 +11,7 @@ details. */
|
|||||||
/* FIXME: Access permissions are ignored at the moment. */
|
/* FIXME: Access permissions are ignored at the moment. */
|
||||||
|
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
|
#include <stdlib.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include "path.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);
|
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,
|
/* Returns 0 if path doesn't exist, >0 if path is a directory,
|
||||||
* <0 if path is a file.
|
* <0 if path is a file.
|
||||||
*
|
*
|
||||||
@ -159,8 +223,9 @@ fhandler_registry::exists ()
|
|||||||
NULL, NULL))
|
NULL, NULL))
|
||||||
|| (error == ERROR_MORE_DATA))
|
|| (error == ERROR_MORE_DATA))
|
||||||
{
|
{
|
||||||
if (strcasematch (buf, file)
|
char enc_buf[NAME_MAX + 1];
|
||||||
|| (buf[0] == '\0' && strcasematch (file, DEFAULT_VALUE_NAME)))
|
if ( (buf[0] == '\0' && strcasematch (file, DEFAULT_VALUE_NAME))
|
||||||
|
|| (!encode_regname (enc_buf, buf) && strcasematch (enc_buf, file)))
|
||||||
{
|
{
|
||||||
file_type = -1;
|
file_type = -1;
|
||||||
goto out;
|
goto out;
|
||||||
@ -257,9 +322,11 @@ fhandler_registry::fstat (struct __stat64 *buf)
|
|||||||
while (!isdirsep (*value_name))
|
while (!isdirsep (*value_name))
|
||||||
value_name--;
|
value_name--;
|
||||||
value_name++;
|
value_name++;
|
||||||
|
char dec_value_name[NAME_MAX + 1];
|
||||||
DWORD dwSize;
|
DWORD dwSize;
|
||||||
if (ERROR_SUCCESS ==
|
if (!decode_regname (dec_value_name, value_name) &&
|
||||||
RegQueryValueEx (hKey, value_name, NULL, NULL, NULL,
|
ERROR_SUCCESS ==
|
||||||
|
RegQueryValueEx (hKey, dec_value_name, NULL, NULL, NULL,
|
||||||
&dwSize))
|
&dwSize))
|
||||||
buf->st_size = dwSize;
|
buf->st_size = dwSize;
|
||||||
}
|
}
|
||||||
@ -360,8 +427,8 @@ retry:
|
|||||||
/* We get here if `buf' contains valid data. */
|
/* We get here if `buf' contains valid data. */
|
||||||
if (*buf == 0)
|
if (*buf == 0)
|
||||||
strcpy (de->d_name, DEFAULT_VALUE_NAME);
|
strcpy (de->d_name, DEFAULT_VALUE_NAME);
|
||||||
else
|
else if (encode_regname (de->d_name, buf))
|
||||||
strcpy (de->d_name, buf);
|
goto retry;
|
||||||
|
|
||||||
dir->__d_position++;
|
dir->__d_position++;
|
||||||
if (dir->__d_position & REG_ENUM_VALUES_MASK)
|
if (dir->__d_position & REG_ENUM_VALUES_MASK)
|
||||||
@ -505,6 +572,14 @@ fhandler_registry::open (int flags, mode_t mode)
|
|||||||
goto out;
|
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);
|
handle = open_key (path, KEY_READ, wow64, false);
|
||||||
if (handle == (HKEY) INVALID_HANDLE_VALUE)
|
if (handle == (HKEY) INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
@ -520,10 +595,10 @@ fhandler_registry::open (int flags, mode_t mode)
|
|||||||
|
|
||||||
set_io_handle (handle);
|
set_io_handle (handle);
|
||||||
|
|
||||||
if (strcasematch (file, DEFAULT_VALUE_NAME))
|
if (strcasematch (dec_file, DEFAULT_VALUE_NAME))
|
||||||
value_name = cstrdup ("");
|
value_name = cstrdup ("");
|
||||||
else
|
else
|
||||||
value_name = cstrdup (file);
|
value_name = cstrdup (dec_file);
|
||||||
|
|
||||||
if (!(flags & O_DIROPEN) && !fill_filebuf ())
|
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;
|
const char *anchor = name;
|
||||||
while (*name && !isdirsep (*name))
|
while (*name && !isdirsep (*name))
|
||||||
name++;
|
name++;
|
||||||
strncpy (component, anchor, name - anchor);
|
if (decode_regname (component, anchor, name - anchor))
|
||||||
component[name - anchor] = '\0';
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
if (parentOpened)
|
||||||
|
RegCloseKey (hParentKey);
|
||||||
|
hKey = (HKEY) INVALID_HANDLE_VALUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (*name)
|
if (*name)
|
||||||
name++;
|
name++;
|
||||||
if (*name == 0 && isValue == true)
|
if (*name == 0 && isValue == true)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user