Skip to content

Commit 6f2afa8

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 <[email protected]>
1 parent efae895 commit 6f2afa8

File tree

13 files changed

+62
-59
lines changed

13 files changed

+62
-59
lines changed

winsup/cygwin/dcrt0.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -912,9 +912,9 @@ dll_crt0_1 (void *)
912912
if (!__argc)
913913
{
914914
PWCHAR wline = GetCommandLineW ();
915-
size_t size = sys_wcstombs_no_path (NULL, 0, wline) + 1;
915+
size_t size = sys_wcstombs (NULL, 0, wline) + 1;
916916
char *line = (char *) alloca (size);
917-
sys_wcstombs_no_path (line, size, wline);
917+
sys_wcstombs (line, size, wline);
918918

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

winsup/cygwin/dtable.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,7 @@ handle_to_fn (HANDLE h, char *posix_fn)
10271027
if (wcsncasecmp (w32, DEVICE_PREFIX, DEVICE_PREFIX_LEN) != 0
10281028
|| !QueryDosDeviceW (NULL, fnbuf, sizeof (fnbuf) / sizeof (WCHAR)))
10291029
{
1030-
sys_wcstombs (posix_fn, NT_MAX_PATH, w32, w32len);
1030+
sys_wcstombs_path (posix_fn, NT_MAX_PATH, w32, w32len);
10311031
return false;
10321032
}
10331033

winsup/cygwin/environ.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ win32env_to_cygenv (PWCHAR rawenv, bool posify)
918918
eventually want to use them). */
919919
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
920920
{
921-
sys_wcstombs_alloc_no_path (&newp, HEAP_NOTHEAP, w);
921+
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
922922
if (i >= envc)
923923
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
924924
envp[i] = newp;
@@ -978,15 +978,15 @@ getwinenveq (const char *name, size_t namelen, int x)
978978
int totlen = GetEnvironmentVariableW (name0, valbuf, 32768);
979979
if (totlen > 0)
980980
{
981-
totlen = sys_wcstombs_no_path (NULL, 0, valbuf) + 1;
981+
totlen = sys_wcstombs (NULL, 0, valbuf) + 1;
982982
if (x == HEAP_1_STR)
983983
totlen += namelen;
984984
else
985985
namelen = 0;
986986
char *p = (char *) cmalloc_abort ((cygheap_types) x, totlen);
987987
if (namelen)
988988
strcpy (p, name);
989-
sys_wcstombs_no_path (p + namelen, totlen, valbuf);
989+
sys_wcstombs (p + namelen, totlen, valbuf);
990990
debug_printf ("using value from GetEnvironmentVariable for '%W'", name0);
991991
return p;
992992
}
@@ -1144,7 +1144,7 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
11441144
for (winnum = 0, var = cwinenv;
11451145
*var;
11461146
++winnum, var = wcschr (var, L'\0') + 1)
1147-
sys_wcstombs_alloc_no_path (&winenv[winnum], HEAP_NOTHEAP, var);
1147+
sys_wcstombs_alloc (&winenv[winnum], HEAP_NOTHEAP, var);
11481148
}
11491149
DestroyEnvironmentBlock (cwinenv);
11501150
/* 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
@@ -2403,7 +2403,7 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
24032403
char *p = stpcpy (file, pc.get_posix ());
24042404
if (p[-1] != '/')
24052405
*p++ = '/';
2406-
sys_wcstombs (p, NT_MAX_PATH - (p - file),
2406+
sys_wcstombs_path (p, NT_MAX_PATH - (p - file),
24072407
fname->Buffer, fname->Length / sizeof (WCHAR));
24082408
path_conv fpath (file, PC_SYM_NOFOLLOW);
24092409
if (fpath.issymlink ())
@@ -2424,7 +2424,7 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
24242424
}
24252425
}
24262426

2427-
sys_wcstombs (de->d_name, NAME_MAX + 1, fname->Buffer,
2427+
sys_wcstombs_path (de->d_name, NAME_MAX + 1, fname->Buffer,
24282428
fname->Length / sizeof (WCHAR));
24292429

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

winsup/cygwin/fhandler/netdrive.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ fhandler_netdrive::readdir (DIR *dir, dirent *de)
648648
goto out;
649649
}
650650

651-
sys_wcstombs (de->d_name, sizeof de->d_name, DIR_cache[dir->__d_position]);
651+
sys_wcstombs_path (de->d_name, sizeof de->d_name, DIR_cache[dir->__d_position]);
652652
if (strlen (dir->__d_dirname) == 2)
653653
de->d_ino = hash_path_name (get_ino (), de->d_name);
654654
else

winsup/cygwin/fhandler/process.cc

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

@@ -1055,7 +1055,7 @@ format_process_maps (void *data, char *&destbuf)
10551055
drive_maps.fixup_if_match (msi->SectionFileName.Buffer);
10561056
if (mount_table->conv_to_posix_path (dosname,
10571057
posix_modname, 0))
1058-
sys_wcstombs (posix_modname, NT_MAX_PATH, dosname);
1058+
sys_wcstombs_path (posix_modname, NT_MAX_PATH, dosname);
10591059
stat (posix_modname, &st);
10601060
}
10611061
else if (!threads.fill_if_match (cur.abase, mb.Type,
@@ -1111,7 +1111,7 @@ format_process_stat (void *data, char *&destbuf)
11111111
else
11121112
{
11131113
PWCHAR last_slash = wcsrchr (p->progname, L'\\');
1114-
sys_wcstombs (cmd, NAME_MAX + 1,
1114+
sys_wcstombs_path (cmd, NAME_MAX + 1,
11151115
last_slash ? last_slash + 1 : p->progname);
11161116
int len = strlen (cmd);
11171117
if (len > 4)
@@ -1239,7 +1239,8 @@ format_process_status (void *data, char *&destbuf)
12391239
bool fetch_siginfo = false;
12401240

12411241
PWCHAR last_slash = wcsrchr (p->progname, L'\\');
1242-
sys_wcstombs (cmd, NAME_MAX + 1, last_slash ? last_slash + 1 : p->progname);
1242+
sys_wcstombs_path (cmd, NAME_MAX + 1,
1243+
last_slash ? last_slash + 1 : p->progname);
12431244
int len = strlen (cmd);
12441245
if (len > 4)
12451246
{

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/local_includes/wchar.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -173,29 +173,29 @@ extern size_t _sys_wcstombs_alloc (char **dst_p, int type, const wchar_t *src,
173173
size_t nwc, bool is_path);
174174

175175
static inline size_t
176-
sys_wcstombs (char *dst, size_t len, const wchar_t * src,
177-
size_t nwc = (size_t) -1)
176+
sys_wcstombs_path (char *dst, size_t len, const wchar_t * src,
177+
size_t nwc = (size_t) -1)
178178
{
179179
return _sys_wcstombs (dst, len, src, nwc, true);
180180
}
181181

182182
static inline size_t
183-
sys_wcstombs_no_path (char *dst, size_t len, const wchar_t * src,
184-
size_t nwc = (size_t) -1)
183+
sys_wcstombs (char *dst, size_t len, const wchar_t * src,
184+
size_t nwc = (size_t) -1)
185185
{
186186
return _sys_wcstombs (dst, len, src, nwc, false);
187187
}
188188

189189
static inline size_t
190-
sys_wcstombs_alloc (char **dst_p, int type, const wchar_t *src,
191-
size_t nwc = (size_t) -1)
190+
sys_wcstombs_alloc_path (char **dst_p, int type, const wchar_t *src,
191+
size_t nwc = (size_t) -1)
192192
{
193193
return _sys_wcstombs_alloc (dst_p, type, src, nwc, true);
194194
}
195195

196196
static inline size_t
197-
sys_wcstombs_alloc_no_path (char **dst_p, int type, const wchar_t *src,
198-
size_t nwc = (size_t) -1)
197+
sys_wcstombs_alloc (char **dst_p, int type, const wchar_t *src,
198+
size_t nwc = (size_t) -1)
199199
{
200200
return _sys_wcstombs_alloc (dst_p, type, src, nwc, false);
201201
}

winsup/cygwin/mount.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
506506
{
507507
/* The filesystem name is only used in fillout_mntent and only if
508508
the filesystem isn't one of the well-known filesystems anyway. */
509-
sys_wcstombs (fsn, sizeof fsn, ffai_buf.ffai.FileSystemName,
509+
sys_wcstombs_path (fsn, sizeof fsn, ffai_buf.ffai.FileSystemName,
510510
ffai_buf.ffai.FileSystemNameLength / sizeof (WCHAR));
511511
strlwr (fsn);
512512
}
@@ -547,7 +547,7 @@ mount_info::create_root_entry (const PWCHAR root)
547547
/* Create a default root dir derived from the location of the Cygwin DLL.
548548
The entry is immutable, unless the "override" option is given in /etc/fstab. */
549549
char native_root[PATH_MAX];
550-
sys_wcstombs (native_root, PATH_MAX, root);
550+
sys_wcstombs_path (native_root, PATH_MAX, root);
551551
assert (*native_root != '\0');
552552
if (add_item (native_root, "/",
553553
MOUNT_SYSTEM | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC | MOUNT_NOACL)
@@ -941,7 +941,7 @@ mount_info::conv_to_posix_path (PWCHAR src_path, char *posix_path,
941941
}
942942
tmp_pathbuf tp;
943943
char *buf = tp.c_get ();
944-
sys_wcstombs (buf, NT_MAX_PATH, src_path);
944+
sys_wcstombs_path (buf, NT_MAX_PATH, src_path);
945945
int ret = conv_to_posix_path (buf, posix_path, ccp_flags);
946946
if (changed)
947947
src_path[0] = L'C';
@@ -1275,7 +1275,7 @@ mount_info::from_fstab_line (char *line, bool user)
12751275
{
12761276
tmp_pathbuf tp;
12771277
char *mb_tmp = tp.c_get ();
1278-
sys_wcstombs (mb_tmp, PATH_MAX, tmp);
1278+
sys_wcstombs_path (mb_tmp, PATH_MAX, tmp);
12791279

12801280
mount_flags |= MOUNT_USER_TEMP;
12811281
int res = mount_table->add_item (mb_tmp, posix_path, mount_flags);
@@ -1890,7 +1890,7 @@ mount_info::cygdrive_getmntent ()
18901890
if (wide_path)
18911891
{
18921892
win32_path = tp.c_get ();
1893-
sys_wcstombs (win32_path, NT_MAX_PATH, wide_path);
1893+
sys_wcstombs_path (win32_path, NT_MAX_PATH, wide_path);
18941894
posix_path = tp.c_get ();
18951895
cygdrive_posix_path (win32_path, posix_path, 0);
18961896
return fillout_mntent (win32_path, posix_path, cygdrive_flags);

0 commit comments

Comments
 (0)