Hi,
When opening a very long file name on Windows, the file becomes an empty file
if 'encoding' is not utf-8.
E.g.:
Step 1: Create a file with a very long name (longer than MAX_PATH bytes and
shorter than MAX_PATH characters)
> vim
> あいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえお.txt
(A file name with 200 multibyte characters and '.txt')
iHello<Esc>
:wq
The length of the file name is:
- 404 bytes in CP932 (longer than MAX_PATH bytes)
- 204 characters in UTF-16LE (shorter than MAX_PATH characters)
Step 2: Open the file again
> vim
> あいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえお.txt
The file becomes empty (when swapfile is on).
The following block is extracted from findswapname() in memline.c:
/*
* If we start editing a new file, e.g. "test.doc", which resides on an
* MSDOS compatible filesystem, it is possible that the file
* "test.doc.swp" which we create will be exactly the same file. To avoid
* this problem we temporarily create "test.doc". Don't do this when the
* check below for a 8.3 file name is used.
*/
if (!(buf->b_p_sn || buf->b_shortname) && buf_fname != NULL
&& mch_getperm(buf_fname) < 0)
dummyfd = mch_fopen((char *)buf_fname, "w");
If buf_fname is longer than MAX_PATH bytes, mch_getperm() always returns an
error and mch_fopen() creates an empty file.
open() and fopen() are implemented with CreateFileA(), and CreateFileA() can
handle maximum MAX_PATH characters (*1).
However, some other CRT functions are limited to MAX_PATH bytes (e.g. stat()).
This inconsistency causes the problem.
(*1) http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
"In the ANSI version of this function, the name is limited to MAX_PATH
characters."
To avoid this problem, maximum length should be limited to MAX_PATH bytes.
(If someone want to handle a file name which is longer than MAX_PATH bytes and
shorter than MAX_PATH characters, he should set 'enc' to utf-8.)
I wrote a patch to fix this problem.
Please check the attached patch.
Regards,
Ken Takata
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
# HG changeset patch
# Parent d62740f5eda33e309f0e68c95d6d8451cc691c1b
diff --git a/src/os_win32.c b/src/os_win32.c
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -6164,6 +6164,13 @@ mch_open(char *name, int flags, int mode
}
# endif
+ /* open() can open a file which name is longer than _MAX_PATH bytes
+ * and shorter than _MAX_PATH characters successfully, but sometimes it
+ * causes unexpected error in another part. We make it error explicitly
+ * at here. */
+ if (strlen(name) >= _MAX_PATH)
+ return -1;
+
return open(name, flags, mode);
}
@@ -6213,6 +6220,13 @@ mch_fopen(char *name, char *mode)
* the _wfopen() fails for missing wide functions. */
}
+ /* fopen() can open a file which name is longer than _MAX_PATH bytes
+ * and shorter than _MAX_PATH characters successfully, but sometimes it
+ * causes unexpected error in another part. We make it error explicitly
+ * at here. */
+ if (strlen(name) >= _MAX_PATH)
+ return NULL;
+
return fopen(name, mode);
}
#endif