Skip to content

Commit 99c3c01

Browse files
committed
Make paths' WCS->MBS conversion explicit
* dcrt0.cc (dll_crt0_1), dtable.cc (handle_to_fn), environ.cc (environ_init, getwinenveq, build_env), external.cc (fillout_pinfo), fhandler_disk_file.cc (__DIR_mounts::eval_ino, fhandler_disk_file::readdir_helper), fhandler_netdrive.cc (fhandler_netdrive::readdir), fhandler_process.cc (format_process_winexename, format_process_maps, format_process_stat, format_process_status), fhandler_procsys.cc (fill_filebuf, fhandler_procsys::readdir), mount.cc (fs_info::update, mount_info::create_root_entry, mount_info::conv_to_posix_path, mount_info::from_fstab_line), nlsfuncs.cc (internal_setlocale), path.cc (path_conv::check, sysmlink_info::check_shortcut, symlink_info::check_sysfile, symlink_info::check_reparse_point, symlink_info::check_nfs_symlink, cygwin_conv_path, cygwin_conv_path_list, cwdstuff::get_error_desc, cwdstuff::get), strfuncs.cc (sys_wcstombs_no_path, sys_wcstombs_alloc_no_path), uinfo.cc (ontherange, fetch_from_path, cygheap_pwdgrp::get_home, cygheap_pwdgrp::get_shell, cygheap_pwdgrp::get_gecos), wchar.h (sys_wcstombs_no_path, sys_wcstombs_alloc_no_path): Convert call sites of the sys_wcstombs*() family to specify explicitly when the parameter refers to a path or file name, to avoid future misconversions. Detailed explanation: The sys_wcstombs() function contains special handling for paths/file names, to work around file name restriction on Windows that are unexpected in the POSIX context of Cygwin. We actually do not want that special handling for WCS strings that do *not* refer to paths or file names. Neither do we want to convert those special file names unless they come from inside Cygwin: if the source of the string value is the Windows API, we *know* it cannot be such a special file name because Windows itself would not be able to handle it in the way Cygwin does. So let's switch the previous sys_wcstombs()/sys_wcstombs_no_path() (and the *_alloc* variant) around to sys_wcstombs_path()/sys_wcstombs(). We do this for several reasons: - whenever a call site wants to convert a WCS representation of a path or file name to an MBS one, it should be made very clear that we *want* the special file name conversion to happen. - it is shorter to read and write. - future calls to sys_wcstombs() will not incur unwanted conversion by accident (it is easy for unsuspecting programmers to assume that the function name "sys_wcstombs()" refers to a regular text conversion that has nothing to do with paths or filenames). By keeping the name sys_wcstombs() (and not switching to sys_wcstombs_path()), the following call sites are implicitly changed to *exclude* the special path/file name conversion: cygheap.h (get_drive): Cannot contain special characters external.cc (cygwin_internal): Refers to user/domain names, not paths fhandler_clipboard.cc (fhandler_dev_clipboard::read): Is not a path or file name but characters from the Windows clipboard fhandler_console.cc: (dev_console::con_to_str): Is not a path or file name but characters from the console fhandler_registry.cc (encode_regname): Is a registry key, not a path or filename fhandler_registry.cc (multi_wcstombs): All call sites pass registry values, not paths or filenames fhandler_registry.cc (fstat): Is a registry value, not a path or filename fhandler_registry.cc (fill_filebuf): Is a registry value, not a path or filename net.cc (get_ipv4fromreg): Is a registry value, not a path or filename net.cc (get_friendlyname): Is a device name, not a path or filename netdb.cc (open_system_file): Is from outside Cygwin smallprint.cc (__small_vsprintf): Is a free text, not a path or filename strfuncs.cc (strlwr): Should preserve the characters from the private page if there are any strfuncs.cc (strupr): Should preserve the characters from the private page if there are any uinfo.cc (cygheap_user::init): Refers to a user name, not a path or filename uinfo.cc (pwdgrp::fetch_account_from_windows): Refers to value from outside Cygwin By keeping the function name sys_wcstombs_alloc() (and not changing it to sys_wcstombs_alloc_path()), the following call sites are implicitly changed to *exclude* the special path/file name conversion: ldap.cc (cyg_ldap::remap_uid): Refers to a user name, not a path or filename ldap.cc (cyg_ldap::remap_gid): Refers to a group name, not a path or filename pinfo.cc (_pinfo::cmdline): Refers to a command line from Windows, outside Cygwin uinfo.cc (cygheap_user::env_logsrv): Is a server name, not a path or filename uinfo.cc (cygheap_user::env_domain): Refers to the user/domain name, not a path or filename uinfo.cc (cygheap_user::env_userprofile): Refers to Windows' idea of a path, outside Cygwin uinfo.cc (cygheap_user::env_systemroot): Refers to Windows' idea of a path, outside Cygwin uinfo.cc (fetch_from_description): Refers to values from outside of Cygwin uinfo.cc (cygheap_pwdgrp::get_gecos): Refers to user/domain name and email address, not path nor filename Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent 76cdfb2 commit 99c3c01

13 files changed

+63
-60
lines changed

winsup/cygwin/dcrt0.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -957,9 +957,9 @@ dll_crt0_1 (void *)
957957
if (!__argc)
958958
{
959959
PWCHAR wline = GetCommandLineW ();
960-
size_t size = sys_wcstombs_no_path (NULL, 0, wline) + 1;
960+
size_t size = sys_wcstombs (NULL, 0, wline) + 1;
961961
char *line = (char *) alloca (size);
962-
sys_wcstombs_no_path (line, size, wline);
962+
sys_wcstombs (line, size, wline);
963963

964964
/* Scan the command line and build argv. Expand wildcards if not
965965
called from another cygwin process. */

winsup/cygwin/dtable.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1011,7 +1011,7 @@ handle_to_fn (HANDLE h, char *posix_fn)
10111011
if (wcsncasecmp (w32, DEVICE_PREFIX, DEVICE_PREFIX_LEN) != 0
10121012
|| !QueryDosDeviceW (NULL, fnbuf, sizeof (fnbuf) / sizeof (WCHAR)))
10131013
{
1014-
sys_wcstombs (posix_fn, NT_MAX_PATH, w32, w32len);
1014+
sys_wcstombs_path (posix_fn, NT_MAX_PATH, w32, w32len);
10151015
return false;
10161016
}
10171017

winsup/cygwin/environ.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ win32env_to_cygenv (PWCHAR rawenv, bool posify)
929929
eventually want to use them). */
930930
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
931931
{
932-
sys_wcstombs_alloc_no_path (&newp, HEAP_NOTHEAP, w);
932+
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
933933
if (i >= envc)
934934
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
935935
envp[i] = newp;
@@ -989,15 +989,15 @@ getwinenveq (const char *name, size_t namelen, int x)
989989
int totlen = GetEnvironmentVariableW (name0, valbuf, 32768);
990990
if (totlen > 0)
991991
{
992-
totlen = sys_wcstombs_no_path (NULL, 0, valbuf) + 1;
992+
totlen = sys_wcstombs (NULL, 0, valbuf) + 1;
993993
if (x == HEAP_1_STR)
994994
totlen += namelen;
995995
else
996996
namelen = 0;
997997
char *p = (char *) cmalloc_abort ((cygheap_types) x, totlen);
998998
if (namelen)
999999
strcpy (p, name);
1000-
sys_wcstombs_no_path (p + namelen, totlen, valbuf);
1000+
sys_wcstombs (p + namelen, totlen, valbuf);
10011001
debug_printf ("using value from GetEnvironmentVariable for '%W'", name0);
10021002
return p;
10031003
}
@@ -1155,7 +1155,7 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
11551155
for (winnum = 0, var = cwinenv;
11561156
*var;
11571157
++winnum, var = wcschr (var, L'\0') + 1)
1158-
sys_wcstombs_alloc_no_path (&winenv[winnum], HEAP_NOTHEAP, var);
1158+
sys_wcstombs_alloc (&winenv[winnum], HEAP_NOTHEAP, var);
11591159
}
11601160
DestroyEnvironmentBlock (cwinenv);
11611161
/* Eliminate variables which are already available in envp, as well as

winsup/cygwin/external.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ fillout_pinfo (pid_t pid, int winpid)
9292
ep.rusage_self = p->rusage_self;
9393
ep.rusage_children = p->rusage_children;
9494
ep.progname[0] = '\0';
95-
sys_wcstombs(ep.progname, MAX_PATH, p->progname);
95+
sys_wcstombs_path (ep.progname, MAX_PATH, p->progname);
9696
ep.strace_mask = 0;
9797
ep.version = EXTERNAL_PINFO_VERSION;
9898

winsup/cygwin/fhandler_disk_file.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,7 +2136,7 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
21362136
char *p = stpcpy (file, pc.get_posix ());
21372137
if (p[-1] != '/')
21382138
*p++ = '/';
2139-
sys_wcstombs (p, NT_MAX_PATH - (p - file),
2139+
sys_wcstombs_path (p, NT_MAX_PATH - (p - file),
21402140
fname->Buffer, fname->Length / sizeof (WCHAR));
21412141
path_conv fpath (file, PC_SYM_NOFOLLOW);
21422142
if (fpath.issymlink ())
@@ -2157,7 +2157,7 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
21572157
}
21582158
}
21592159

2160-
sys_wcstombs (de->d_name, NAME_MAX + 1, fname->Buffer,
2160+
sys_wcstombs_path (de->d_name, NAME_MAX + 1, fname->Buffer,
21612161
fname->Length / sizeof (WCHAR));
21622162

21632163
/* Don't try to optimize relative to dir->__d_position. On several

winsup/cygwin/fhandler_netdrive.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,15 @@ fhandler_netdrive::readdir (DIR *dir, dirent *de)
250250
tp.u_get (&ds);
251251
RtlInitUnicodeString (&ss, bs);
252252
RtlDowncaseUnicodeString (&ds, &ss, FALSE);
253-
sys_wcstombs (de->d_name, sizeof de->d_name,
253+
sys_wcstombs_path (de->d_name, sizeof de->d_name,
254254
ds.Buffer, ds.Length / sizeof (WCHAR));
255255
de->d_ino = hash_path_name (get_ino (), de->d_name);
256256
}
257257
else
258258
{
259-
sys_wcstombs (de->d_name, sizeof de->d_name, bs);
259+
sys_wcstombs_path (de->d_name, sizeof de->d_name, bs);
260260
char *rpath = tp.c_get ();
261-
sys_wcstombs (rpath, NT_MAX_PATH, nro->lpRemoteName);
261+
sys_wcstombs_path (rpath, NT_MAX_PATH, nro->lpRemoteName);
262262
de->d_ino = readdir_get_ino (rpath, false);
263263
/* We can't trust remote inode numbers of only 32 bit. That means,
264264
remote NT4 NTFS, as well as shares of Samba version < 3.0. */

winsup/cygwin/fhandler_process.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -574,10 +574,10 @@ static off_t
574574
format_process_winexename (void *data, char *&destbuf)
575575
{
576576
_pinfo *p = (_pinfo *) data;
577-
size_t len = sys_wcstombs (NULL, 0, p->progname);
577+
size_t len = sys_wcstombs_path (NULL, 0, p->progname);
578578
destbuf = (char *) crealloc_abort (destbuf, len + 1);
579579
/* With trailing \0 for backward compat reasons. */
580-
sys_wcstombs (destbuf, len + 1, p->progname);
580+
sys_wcstombs_path (destbuf, len + 1, p->progname);
581581
return len;
582582
}
583583

@@ -1052,7 +1052,7 @@ format_process_maps (void *data, char *&destbuf)
10521052
drive_maps.fixup_if_match (msi->SectionFileName.Buffer);
10531053
if (mount_table->conv_to_posix_path (dosname,
10541054
posix_modname, 0))
1055-
sys_wcstombs (posix_modname, NT_MAX_PATH, dosname);
1055+
sys_wcstombs_path (posix_modname, NT_MAX_PATH, dosname);
10561056
stat64 (posix_modname, &st);
10571057
}
10581058
else if (!threads.fill_if_match (cur.abase, mb.Type,
@@ -1098,7 +1098,7 @@ format_process_stat (void *data, char *&destbuf)
10981098
else
10991099
{
11001100
PWCHAR last_slash = wcsrchr (p->progname, L'\\');
1101-
sys_wcstombs (cmd, NAME_MAX + 1,
1101+
sys_wcstombs_path (cmd, NAME_MAX + 1,
11021102
last_slash ? last_slash + 1 : p->progname);
11031103
int len = strlen (cmd);
11041104
if (len > 4)
@@ -1201,7 +1201,8 @@ format_process_status (void *data, char *&destbuf)
12011201
size_t vmsize = 0, vmrss = 0, vmdata = 0, vmlib = 0, vmtext = 0, vmshare = 0;
12021202

12031203
PWCHAR last_slash = wcsrchr (p->progname, L'\\');
1204-
sys_wcstombs (cmd, NAME_MAX + 1, last_slash ? last_slash + 1 : p->progname);
1204+
sys_wcstombs_path (cmd, NAME_MAX + 1,
1205+
last_slash ? last_slash + 1 : p->progname);
12051206
int len = strlen (cmd);
12061207
if (len > 4)
12071208
{

winsup/cygwin/fhandler_procsys.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,11 @@ fhandler_procsys::fill_filebuf ()
236236
NtClose (h);
237237
if (!NT_SUCCESS (status))
238238
goto unreadable;
239-
len = sys_wcstombs (NULL, 0, target.Buffer, target.Length / sizeof (WCHAR));
239+
len = sys_wcstombs_path (NULL, 0,
240+
target.Buffer, target.Length / sizeof (WCHAR));
240241
filebuf = (char *) crealloc_abort (filebuf, procsys_len + len + 1);
241-
sys_wcstombs (fnamep = stpcpy (filebuf, procsys), len + 1, target.Buffer,
242-
target.Length / sizeof (WCHAR));
242+
sys_wcstombs_path (fnamep = stpcpy (filebuf, procsys), len + 1,
243+
target.Buffer, target.Length / sizeof (WCHAR));
243244
while ((fnamep = strchr (fnamep, '\\')))
244245
*fnamep = '/';
245246
return true;
@@ -377,8 +378,8 @@ fhandler_procsys::readdir (DIR *dir, dirent *de)
377378
res = ENMFILE;
378379
else
379380
{
380-
sys_wcstombs (de->d_name, NAME_MAX + 1, dbi->ObjectName.Buffer,
381-
dbi->ObjectName.Length / sizeof (WCHAR));
381+
sys_wcstombs_path (de->d_name, NAME_MAX + 1, dbi->ObjectName.Buffer,
382+
dbi->ObjectName.Length / sizeof (WCHAR));
382383
de->d_ino = hash_path_name (get_ino (), de->d_name);
383384
if (RtlEqualUnicodeString (&dbi->ObjectTypeName, &ro_u_natdir, FALSE))
384385
de->d_type = DT_DIR;

winsup/cygwin/mount.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
441441
{
442442
/* The filesystem name is only used in fillout_mntent and only if
443443
the filesystem isn't one of the well-known filesystems anyway. */
444-
sys_wcstombs (fsn, sizeof fsn, ffai_buf.ffai.FileSystemName,
444+
sys_wcstombs_path (fsn, sizeof fsn, ffai_buf.ffai.FileSystemName,
445445
ffai_buf.ffai.FileSystemNameLength / sizeof (WCHAR));
446446
strlwr (fsn);
447447
}
@@ -468,7 +468,7 @@ mount_info::create_root_entry (const PWCHAR root)
468468
/* Create a default root dir derived from the location of the Cygwin DLL.
469469
The entry is immutable, unless the "override" option is given in /etc/fstab. */
470470
char native_root[PATH_MAX];
471-
sys_wcstombs (native_root, PATH_MAX, root);
471+
sys_wcstombs_path (native_root, PATH_MAX, root);
472472
assert (*native_root != '\0');
473473
if (add_item (native_root, "/",
474474
MOUNT_SYSTEM | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC | MOUNT_NOACL)
@@ -846,7 +846,7 @@ mount_info::conv_to_posix_path (PWCHAR src_path, char *posix_path,
846846
}
847847
tmp_pathbuf tp;
848848
char *buf = tp.c_get ();
849-
sys_wcstombs (buf, NT_MAX_PATH, src_path);
849+
sys_wcstombs_path (buf, NT_MAX_PATH, src_path);
850850
int ret = conv_to_posix_path (buf, posix_path, ccp_flags);
851851
if (changed)
852852
src_path[0] = L'C';
@@ -1177,7 +1177,7 @@ mount_info::from_fstab_line (char *line, bool user)
11771177
{
11781178
tmp_pathbuf tp;
11791179
char *mb_tmp = tp.c_get ();
1180-
sys_wcstombs (mb_tmp, PATH_MAX, tmp);
1180+
sys_wcstombs_path (mb_tmp, PATH_MAX, tmp);
11811181

11821182
mount_flags |= MOUNT_USER_TEMP;
11831183
int res = mount_table->add_item (mb_tmp, posix_path, mount_flags);

winsup/cygwin/nlsfuncs.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1606,7 +1606,7 @@ internal_setlocale ()
16061606
if (w_path)
16071607
{
16081608
char *c_path = tp.c_get ();
1609-
sys_wcstombs (c_path, 32768, w_path);
1609+
sys_wcstombs_path (c_path, 32768, w_path);
16101610
setenv ("PATH", c_path, 1);
16111611
}
16121612
}

0 commit comments

Comments
 (0)