Skip to content

Commit 9ad93c1

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 dcrt0.cc (dll_crt0_1): Is input from outside of Cygwin environ.cc (getwinenveq): Is input from outside of Cygwin 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 miscfuncs.cc (strlwr): TODO miscfuncs.cc (strupr): TODO 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 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: environ.cc (environ_init): Is input from outside of Cygwin environ.cc (build_env): Refers to the environment from outside Cygwin 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 315aa0f commit 9ad93c1

File tree

14 files changed

+64
-60
lines changed

14 files changed

+64
-60
lines changed

winsup/cygwin/dcrt0.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -948,9 +948,9 @@ dll_crt0_1 (void *)
948948
if (!__argc)
949949
{
950950
PWCHAR wline = GetCommandLineW ();
951-
size_t size = sys_wcstombs_no_path (NULL, 0, wline) + 1;
951+
size_t size = sys_wcstombs (NULL, 0, wline) + 1;
952952
char *line = (char *) alloca (size);
953-
sys_wcstombs_no_path (line, size, wline);
953+
sys_wcstombs (line, size, wline);
954954

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

winsup/cygwin/dtable.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,7 @@ handle_to_fn (HANDLE h, char *posix_fn)
10031003
if (wcsncasecmp (w32, DEVICE_PREFIX, DEVICE_PREFIX_LEN) != 0
10041004
|| !QueryDosDeviceW (NULL, fnbuf, sizeof (fnbuf) / sizeof (WCHAR)))
10051005
{
1006-
sys_wcstombs (posix_fn, NT_MAX_PATH, w32, w32len);
1006+
sys_wcstombs_path (posix_fn, NT_MAX_PATH, w32, w32len);
10071007
return false;
10081008
}
10091009

winsup/cygwin/environ.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,7 @@ environ_init (char **envp, int envc)
846846
eventually want to use them). */
847847
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
848848
{
849-
sys_wcstombs_alloc_no_path (&newp, HEAP_NOTHEAP, w);
849+
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
850850
if (i >= envc)
851851
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
852852
envp[i] = newp;
@@ -925,15 +925,15 @@ getwinenveq (const char *name, size_t namelen, int x)
925925
int totlen = GetEnvironmentVariableW (name0, valbuf, 32768);
926926
if (totlen > 0)
927927
{
928-
totlen = sys_wcstombs_no_path (NULL, 0, valbuf) + 1;
928+
totlen = sys_wcstombs (NULL, 0, valbuf) + 1;
929929
if (x == HEAP_1_STR)
930930
totlen += namelen;
931931
else
932932
namelen = 0;
933933
char *p = (char *) cmalloc_abort ((cygheap_types) x, totlen);
934934
if (namelen)
935935
strcpy (p, name);
936-
sys_wcstombs_no_path (p + namelen, totlen, valbuf);
936+
sys_wcstombs (p + namelen, totlen, valbuf);
937937
debug_printf ("using value from GetEnvironmentVariable for '%W'", name0);
938938
return p;
939939
}
@@ -1086,7 +1086,7 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
10861086
for (winnum = 0, var = cwinenv;
10871087
*var;
10881088
++winnum, var = wcschr (var, L'\0') + 1)
1089-
sys_wcstombs_alloc_no_path (&winenv[winnum], HEAP_NOTHEAP, var);
1089+
sys_wcstombs_alloc (&winenv[winnum], HEAP_NOTHEAP, var);
10901090
}
10911091
DestroyEnvironmentBlock (cwinenv);
10921092
/* 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
@@ -91,7 +91,7 @@ fillout_pinfo (pid_t pid, int winpid)
9191
ep.rusage_self = p->rusage_self;
9292
ep.rusage_children = p->rusage_children;
9393
ep.progname[0] = '\0';
94-
sys_wcstombs(ep.progname, MAX_PATH, p->progname);
94+
sys_wcstombs_path (ep.progname, MAX_PATH, p->progname);
9595
ep.strace_mask = 0;
9696
ep.version = EXTERNAL_PINFO_VERSION;
9797

winsup/cygwin/fhandler_disk_file.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class __DIR_mounts
5353
char *c = stpcpy (fname, parent_dir);
5454
if (c[- 1] != '/')
5555
*c++ = '/';
56-
sys_wcstombs (c, mounts[idx].Length + 1,
56+
sys_wcstombs_path (c, mounts[idx].Length + 1,
5757
mounts[idx].Buffer, mounts[idx].Length / sizeof (WCHAR));
5858
path_conv pc (fname, PC_SYM_NOFOLLOW | PC_POSIX | PC_KEEP_HANDLE);
5959
if (!stat_worker (pc, &st))
@@ -2076,7 +2076,7 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
20762076
char *p = stpcpy (file, pc.get_posix ());
20772077
if (p[-1] != '/')
20782078
*p++ = '/';
2079-
sys_wcstombs (p, NT_MAX_PATH - (p - file),
2079+
sys_wcstombs_path (p, NT_MAX_PATH - (p - file),
20802080
fname->Buffer, fname->Length / sizeof (WCHAR));
20812081
path_conv fpath (file, PC_SYM_NOFOLLOW);
20822082
if (fpath.issymlink ())
@@ -2097,7 +2097,7 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
20972097
}
20982098
}
20992099

2100-
sys_wcstombs (de->d_name, NAME_MAX + 1, fname->Buffer,
2100+
sys_wcstombs_path (de->d_name, NAME_MAX + 1, fname->Buffer,
21012101
fname->Length / sizeof (WCHAR));
21022102

21032103
/* 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
@@ -255,15 +255,15 @@ fhandler_netdrive::readdir (DIR *dir, dirent *de)
255255
tp.u_get (&ds);
256256
RtlInitUnicodeString (&ss, bs);
257257
RtlDowncaseUnicodeString (&ds, &ss, FALSE);
258-
sys_wcstombs (de->d_name, sizeof de->d_name,
258+
sys_wcstombs_path (de->d_name, sizeof de->d_name,
259259
ds.Buffer, ds.Length / sizeof (WCHAR));
260260
de->d_ino = hash_path_name (get_ino (), de->d_name);
261261
}
262262
else
263263
{
264-
sys_wcstombs (de->d_name, sizeof de->d_name, bs);
264+
sys_wcstombs_path (de->d_name, sizeof de->d_name, bs);
265265
char *rpath = tp.c_get ();
266-
sys_wcstombs (rpath, NT_MAX_PATH, nro->lpRemoteName);
266+
sys_wcstombs_path (rpath, NT_MAX_PATH, nro->lpRemoteName);
267267
de->d_ino = readdir_get_ino (rpath, false);
268268
/* We can't trust remote inode numbers of only 32 bit. That means,
269269
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
@@ -566,10 +566,10 @@ static off_t
566566
format_process_winexename (void *data, char *&destbuf)
567567
{
568568
_pinfo *p = (_pinfo *) data;
569-
size_t len = sys_wcstombs (NULL, 0, p->progname);
569+
size_t len = sys_wcstombs_path (NULL, 0, p->progname);
570570
destbuf = (char *) crealloc_abort (destbuf, len + 1);
571571
/* With trailing \0 for backward compat reasons. */
572-
sys_wcstombs (destbuf, len + 1, p->progname);
572+
sys_wcstombs_path (destbuf, len + 1, p->progname);
573573
return len;
574574
}
575575

@@ -1008,7 +1008,7 @@ format_process_maps (void *data, char *&destbuf)
10081008
drive_maps.fixup_if_match (msi->SectionFileName.Buffer);
10091009
if (mount_table->conv_to_posix_path (dosname,
10101010
posix_modname, 0))
1011-
sys_wcstombs (posix_modname, NT_MAX_PATH, dosname);
1011+
sys_wcstombs_path (posix_modname, NT_MAX_PATH, dosname);
10121012
stat64 (posix_modname, &st);
10131013
}
10141014
else if (!threads.fill_if_match (cur.abase, mb.Type,
@@ -1054,7 +1054,7 @@ format_process_stat (void *data, char *&destbuf)
10541054
else
10551055
{
10561056
PWCHAR last_slash = wcsrchr (p->progname, L'\\');
1057-
sys_wcstombs (cmd, NAME_MAX + 1,
1057+
sys_wcstombs_path (cmd, NAME_MAX + 1,
10581058
last_slash ? last_slash + 1 : p->progname);
10591059
int len = strlen (cmd);
10601060
if (len > 4)
@@ -1172,7 +1172,8 @@ format_process_status (void *data, char *&destbuf)
11721172
vmtext = 0UL, vmshare = 0UL;
11731173

11741174
PWCHAR last_slash = wcsrchr (p->progname, L'\\');
1175-
sys_wcstombs (cmd, NAME_MAX + 1, last_slash ? last_slash + 1 : p->progname);
1175+
sys_wcstombs_path (cmd, NAME_MAX + 1,
1176+
last_slash ? last_slash + 1 : p->progname);
11761177
int len = strlen (cmd);
11771178
if (len > 4)
11781179
{

winsup/cygwin/fhandler_procsys.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,11 @@ fhandler_procsys::fill_filebuf ()
243243
NtClose (h);
244244
if (!NT_SUCCESS (status))
245245
goto unreadable;
246-
len = sys_wcstombs (NULL, 0, target.Buffer, target.Length / sizeof (WCHAR));
246+
len = sys_wcstombs_path (NULL, 0,
247+
target.Buffer, target.Length / sizeof (WCHAR));
247248
filebuf = (char *) crealloc_abort (filebuf, procsys_len + len + 1);
248-
sys_wcstombs (fnamep = stpcpy (filebuf, procsys), len + 1, target.Buffer,
249-
target.Length / sizeof (WCHAR));
249+
sys_wcstombs_path (fnamep = stpcpy (filebuf, procsys), len + 1,
250+
target.Buffer, target.Length / sizeof (WCHAR));
250251
while ((fnamep = strchr (fnamep, '\\')))
251252
*fnamep = '/';
252253
return true;
@@ -355,7 +356,7 @@ fhandler_procsys::readdir (DIR *dir, dirent *de)
355356
res = ENMFILE;
356357
else
357358
{
358-
sys_wcstombs (de->d_name, NAME_MAX + 1, f.dbi.ObjectName.Buffer,
359+
sys_wcstombs_path (de->d_name, NAME_MAX + 1, f.dbi.ObjectName.Buffer,
359360
f.dbi.ObjectName.Length / sizeof (WCHAR));
360361
de->d_ino = hash_path_name (get_ino (), de->d_name);
361362
if (RtlEqualUnicodeString (&f.dbi.ObjectTypeName, &ro_u_natdir,

winsup/cygwin/mount.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
442442
{
443443
/* The filesystem name is only used in fillout_mntent and only if
444444
the filesystem isn't one of the well-known filesystems anyway. */
445-
sys_wcstombs (fsn, sizeof fsn, ffai_buf.ffai.FileSystemName,
445+
sys_wcstombs_path (fsn, sizeof fsn, ffai_buf.ffai.FileSystemName,
446446
ffai_buf.ffai.FileSystemNameLength / sizeof (WCHAR));
447447
strlwr (fsn);
448448
}
@@ -478,7 +478,7 @@ mount_info::create_root_entry (const PWCHAR root)
478478
/* Create a default root dir derived from the location of the Cygwin DLL.
479479
The entry is immutable, unless the "override" option is given in /etc/fstab. */
480480
char native_root[PATH_MAX];
481-
sys_wcstombs (native_root, PATH_MAX, root);
481+
sys_wcstombs_path (native_root, PATH_MAX, root);
482482
assert (*native_root != '\0');
483483
if (add_item (native_root, "/",
484484
MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC | MOUNT_NOACL)
@@ -874,7 +874,7 @@ mount_info::conv_to_posix_path (PWCHAR src_path, char *posix_path,
874874
}
875875
tmp_pathbuf tp;
876876
char *buf = tp.c_get ();
877-
sys_wcstombs (buf, NT_MAX_PATH, src_path);
877+
sys_wcstombs_path (buf, NT_MAX_PATH, src_path);
878878
int ret = conv_to_posix_path (buf, posix_path, ccp_flags);
879879
if (changed)
880880
src_path[0] = L'C';
@@ -1220,7 +1220,7 @@ mount_info::from_fstab_line (char *line, bool user)
12201220
{
12211221
tmp_pathbuf tp;
12221222
char *mb_tmp = tp.c_get ();
1223-
sys_wcstombs (mb_tmp, PATH_MAX, tmp);
1223+
sys_wcstombs_path (mb_tmp, PATH_MAX, tmp);
12241224

12251225
mount_flags |= MOUNT_USER_TEMP;
12261226
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
@@ -1626,7 +1626,7 @@ internal_setlocale ()
16261626
if (w_path)
16271627
{
16281628
char *c_path = tp.c_get ();
1629-
sys_wcstombs (c_path, 32768, w_path);
1629+
sys_wcstombs_path (c_path, 32768, w_path);
16301630
setenv ("PATH", c_path, 1);
16311631
}
16321632
}

0 commit comments

Comments
 (0)