aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2015-08-31 17:52:47 +0300
committerEli Zaretskii2015-08-31 17:52:47 +0300
commit5ee3ef8e1867d284be0ff9f654f8bde46e751978 (patch)
tree6e82d1b10ae6b1f8f208ed43e2cc55ff7eb160b8 /src
parent697be62c5f2b86e8ad93dfcaa0df07890c24d989 (diff)
downloademacs-5ee3ef8e1867d284be0ff9f654f8bde46e751978.tar.gz
emacs-5ee3ef8e1867d284be0ff9f654f8bde46e751978.zip
Fix handling long file names in readdir on MS-Windows
* src/w32.c (sys_readdir): Append "\*" to the directory after converting it to UTF-16/ANSI, not before, to avoid overflowing the 260-character limit on file names in filename_to_utf16/ansi.
Diffstat (limited to 'src')
-rw-r--r--src/w32.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/w32.c b/src/w32.c
index 60fbe92e082..dea8431ed7a 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -3399,30 +3399,41 @@ sys_readdir (DIR *dirp)
3399 /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */ 3399 /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
3400 else if (dir_find_handle == INVALID_HANDLE_VALUE) 3400 else if (dir_find_handle == INVALID_HANDLE_VALUE)
3401 { 3401 {
3402 char filename[MAX_UTF8_PATH + 2]; 3402 char filename[MAX_UTF8_PATH];
3403 int ln; 3403 int ln;
3404 bool last_slash = true;
3404 3405
3406 /* Note: We don't need to worry about dir_pathname being longer
3407 than MAX_UTF8_PATH, as sys_opendir already took care of that
3408 when it called map_w32_filename: that function will put a "?"
3409 in its return value in that case, thus failing all the calls
3410 below. */
3405 strcpy (filename, dir_pathname); 3411 strcpy (filename, dir_pathname);
3406 ln = strlen (filename); 3412 ln = strlen (filename);
3407 if (!IS_DIRECTORY_SEP (filename[ln - 1])) 3413 if (!IS_DIRECTORY_SEP (filename[ln - 1]))
3408 filename[ln++] = '\\'; 3414 last_slash = false;
3409 strcpy (filename + ln, "*");
3410 3415
3411 /* Note: No need to resolve symlinks in FILENAME, because 3416 /* Note: No need to resolve symlinks in FILENAME, because
3412 FindFirst opens the directory that is the target of a 3417 FindFirst opens the directory that is the target of a
3413 symlink. */ 3418 symlink. */
3414 if (w32_unicode_filenames) 3419 if (w32_unicode_filenames)
3415 { 3420 {
3416 wchar_t fnw[MAX_PATH]; 3421 wchar_t fnw[MAX_PATH + 2];
3417 3422
3418 filename_to_utf16 (filename, fnw); 3423 filename_to_utf16 (filename, fnw);
3424 if (!last_slash)
3425 wcscat (fnw, L"\\");
3426 wcscat (fnw, L"*");
3419 dir_find_handle = FindFirstFileW (fnw, &dir_find_data_w); 3427 dir_find_handle = FindFirstFileW (fnw, &dir_find_data_w);
3420 } 3428 }
3421 else 3429 else
3422 { 3430 {
3423 char fna[MAX_PATH]; 3431 char fna[MAX_PATH + 2];
3424 3432
3425 filename_to_ansi (filename, fna); 3433 filename_to_ansi (filename, fna);
3434 if (!last_slash)
3435 strcat (fna, "\\");
3436 strcat (fna, "*");
3426 /* If FILENAME is not representable by the current ANSI 3437 /* If FILENAME is not representable by the current ANSI
3427 codepage, we don't want FindFirstFileA to interpret the 3438 codepage, we don't want FindFirstFileA to interpret the
3428 '?' characters as a wildcard. */ 3439 '?' characters as a wildcard. */
@@ -3860,6 +3871,8 @@ w32_accessible_directory_p (const char *dirname, ptrdiff_t dirlen)
3860 bool last_slash = dirlen > 0 && IS_DIRECTORY_SEP (dirname[dirlen - 1]); 3871 bool last_slash = dirlen > 0 && IS_DIRECTORY_SEP (dirname[dirlen - 1]);
3861 HANDLE dh; 3872 HANDLE dh;
3862 3873
3874 /* Note: map_w32_filename makes sure DIRNAME is not longer than
3875 MAX_UTF8_PATH. */
3863 strcpy (pattern, map_w32_filename (dirname, NULL)); 3876 strcpy (pattern, map_w32_filename (dirname, NULL));
3864 3877
3865 /* Note: No need to resolve symlinks in FILENAME, because FindFirst 3878 /* Note: No need to resolve symlinks in FILENAME, because FindFirst