[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] /srv/bzr/emacs/emacs-24 r111077: Fix bug #13262 with crash
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] /srv/bzr/emacs/emacs-24 r111077: Fix bug #13262 with crashes in completion on MS-Windows with non-ASCII filenames. |
Date: |
Mon, 24 Dec 2012 18:15:13 +0200 |
User-agent: |
Bazaar (2.5.0) |
------------------------------------------------------------
revno: 111077
fixes bug: http://debbugs.gnu.org/13262
committer: Eli Zaretskii <address@hidden>
branch nick: emacs-24
timestamp: Mon 2012-12-24 18:15:13 +0200
message:
Fix bug #13262 with crashes in completion on MS-Windows with non-ASCII
filenames.
src/fileio.c (file_name_as_directory, directory_file_name): Accept
an additional argument MULTIBYTE to indicate whether the input C
came from a multibyte or a unibyte Lisp string; all callers
adjusted. Don't assume the input string is always multibyte.
(Ffile_name_directory) [DOS_NT]: Handle unibyte strings correctly:
don't ENCODE_FILE them, and return a unibyte string if the input
was unibyte.
(Fexpand_file_name): Don't mix unibyte with multibyte strings, and
don't assume the input strings will always be multibyte. If the
input strings are multibyte, decode strings obtained from C
library functions.
modified:
src/ChangeLog
src/fileio.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog 2012-12-22 10:12:52 +0000
+++ b/src/ChangeLog 2012-12-24 16:15:13 +0000
@@ -1,3 +1,18 @@
+2012-12-24 Eli Zaretskii <address@hidden>
+
+ * fileio.c (file_name_as_directory, directory_file_name): Accept
+ an additional argument MULTIBYTE to indicate whether the input C
+ came from a multibyte or a unibyte Lisp string; all callers
+ adjusted. Don't assume the input string is always multibyte.
+ (Bug#13262)
+ (Ffile_name_directory) [DOS_NT]: Handle unibyte strings correctly:
+ don't ENCODE_FILE them, and return a unibyte string if the input
+ was unibyte.
+ (Fexpand_file_name): Don't mix unibyte with multibyte strings, and
+ don't assume the input strings will always be multibyte. If the
+ input strings are multibyte, decode strings obtained from C
+ library functions.
+
2012-12-22 Martin Rudalics <address@hidden>
* window.c (Fselect_window): Reword doc-string (Bug#13248).
=== modified file 'src/fileio.c'
--- a/src/fileio.c 2012-12-21 11:52:18 +0000
+++ b/src/fileio.c 2012-12-24 16:15:13 +0000
@@ -373,12 +373,26 @@
strcat (res, "/");
beg = res;
p = beg + strlen (beg);
+ dostounix_filename (beg);
+ tem_fn = make_specified_string (beg, -1, p - beg,
+ STRING_MULTIBYTE (filename));
}
- }
- tem_fn = ENCODE_FILE (make_specified_string (beg, -1, p - beg,
- STRING_MULTIBYTE (filename)));
- dostounix_filename (SSDATA (tem_fn));
- return DECODE_FILE (tem_fn);
+ else
+ tem_fn = make_specified_string (beg - 2, -1, p - beg + 2,
+ STRING_MULTIBYTE (filename));
+ }
+ else if (STRING_MULTIBYTE (filename))
+ {
+ tem_fn = ENCODE_FILE (make_specified_string (beg, -1, p - beg, 1));
+ dostounix_filename (SSDATA (tem_fn));
+ tem_fn = DECODE_FILE (tem_fn);
+ }
+ else
+ {
+ dostounix_filename (beg);
+ tem_fn = make_specified_string (beg, -1, p - beg, 0);
+ }
+ return tem_fn;
#else /* DOS_NT */
return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename));
#endif /* DOS_NT */
@@ -453,12 +467,14 @@
return Ffile_name_directory (filename);
}
-/* Convert from file name SRC of length SRCLEN to directory name
- in DST. On UNIX, just make sure there is a terminating /.
- Return the length of DST in bytes. */
+/* Convert from file name SRC of length SRCLEN to directory name in
+ DST. MULTIBYTE non-zero means the file name in SRC is a multibyte
+ string. On UNIX, just make sure there is a terminating /. Return
+ the length of DST in bytes. */
static ptrdiff_t
-file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen)
+file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen,
+ bool multibyte)
{
if (srclen == 0)
{
@@ -477,14 +493,17 @@
srclen++;
}
#ifdef DOS_NT
- {
- Lisp_Object tem_fn = make_specified_string (dst, -1, srclen, 1);
+ if (multibyte)
+ {
+ Lisp_Object tem_fn = make_specified_string (dst, -1, srclen, 1);
- tem_fn = ENCODE_FILE (tem_fn);
- dostounix_filename (SSDATA (tem_fn));
- tem_fn = DECODE_FILE (tem_fn);
- memcpy (dst, SSDATA (tem_fn), (srclen = SBYTES (tem_fn)) + 1);
- }
+ tem_fn = ENCODE_FILE (tem_fn);
+ dostounix_filename (SSDATA (tem_fn));
+ tem_fn = DECODE_FILE (tem_fn);
+ memcpy (dst, SSDATA (tem_fn), (srclen = SBYTES (tem_fn)) + 1);
+ }
+ else
+ dostounix_filename (dst);
#endif
return srclen;
}
@@ -520,16 +539,18 @@
}
buf = alloca (SBYTES (file) + 10);
- length = file_name_as_directory (buf, SSDATA (file), SBYTES (file));
+ length = file_name_as_directory (buf, SSDATA (file), SBYTES (file),
+ STRING_MULTIBYTE (file));
return make_specified_string (buf, -1, length, STRING_MULTIBYTE (file));
}
-/* Convert from directory name SRC of length SRCLEN to
- file name in DST. On UNIX, just make sure there isn't
- a terminating /. Return the length of DST in bytes. */
+/* Convert from directory name SRC of length SRCLEN to file name in
+ DST. MULTIBYTE non-zero means the file name in SRC is a multibyte
+ string. On UNIX, just make sure there isn't a terminating /.
+ Return the length of DST in bytes. */
static ptrdiff_t
-directory_file_name (char *dst, char *src, ptrdiff_t srclen)
+directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte)
{
/* Process as Unix format: just remove any final slash.
But leave "/" unchanged; do not change it to "". */
@@ -545,14 +566,17 @@
srclen--;
}
#ifdef DOS_NT
- {
- Lisp_Object tem_fn = make_specified_string (dst, -1, srclen, 1);
+ if (multibyte)
+ {
+ Lisp_Object tem_fn = make_specified_string (dst, -1, srclen, 1);
- tem_fn = ENCODE_FILE (tem_fn);
- dostounix_filename (SSDATA (tem_fn));
- tem_fn = DECODE_FILE (tem_fn);
- memcpy (dst, SSDATA (tem_fn), (srclen = SBYTES (tem_fn)) + 1);
- }
+ tem_fn = ENCODE_FILE (tem_fn);
+ dostounix_filename (SSDATA (tem_fn));
+ tem_fn = DECODE_FILE (tem_fn);
+ memcpy (dst, SSDATA (tem_fn), (srclen = SBYTES (tem_fn)) + 1);
+ }
+ else
+ dostounix_filename (dst);
#endif
return srclen;
}
@@ -588,7 +612,8 @@
}
buf = alloca (SBYTES (directory) + 20);
- length = directory_file_name (buf, SSDATA (directory), SBYTES (directory));
+ length = directory_file_name (buf, SSDATA (directory), SBYTES (directory),
+ STRING_MULTIBYTE (directory));
return make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory));
}
@@ -1038,7 +1063,7 @@
/* `egetenv' may return a unibyte string, which will bite us since
we expect the directory to be multibyte. */
tem = build_string (newdir);
- if (!STRING_MULTIBYTE (tem))
+ if (multibyte && !STRING_MULTIBYTE (tem))
{
hdir = DECODE_FILE (tem);
newdir = SSDATA (hdir);
@@ -1060,7 +1085,18 @@
unblock_input ();
if (pw)
{
+ Lisp_Object tem;
+
newdir = pw->pw_dir;
+ /* `getpwnam' may return a unibyte string, which will
+ bite us since we expect the directory to be
+ multibyte. */
+ tem = build_string (newdir);
+ if (multibyte && !STRING_MULTIBYTE (tem))
+ {
+ hdir = DECODE_FILE (tem);
+ newdir = SSDATA (hdir);
+ }
nm = p;
#ifdef DOS_NT
collapse_newdir = 0;
@@ -1084,6 +1120,13 @@
adir = alloca (MAXPATHLEN + 1);
if (!getdefdir (c_toupper (drive) - 'A' + 1, adir))
adir = NULL;
+ else if (multibyte)
+ {
+ Lisp_Object tem = build_string (adir);
+
+ tem = DECODE_FILE (tem);
+ memcpy (adir, SSDATA (tem), SBYTES (tem) + 1);
+ }
}
if (!adir)
{
@@ -1142,6 +1185,7 @@
indirectly by prepending newdir to nm if necessary, and using
cwd (or the wd of newdir's drive) as the new newdir. */
char *adir;
+
if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
{
drive = (unsigned char) newdir[0];
@@ -1151,7 +1195,7 @@
{
ptrdiff_t newlen = strlen (newdir);
char *tmp = alloca (newlen + strlen (nm) + 2);
- file_name_as_directory (tmp, newdir, newlen);
+ file_name_as_directory (tmp, newdir, newlen, multibyte);
strcat (tmp, nm);
nm = tmp;
}
@@ -1159,10 +1203,17 @@
if (drive)
{
if (!getdefdir (c_toupper (drive) - 'A' + 1, adir))
- newdir = "/";
+ strcpy (adir, "/");
}
else
getwd (adir);
+ if (multibyte)
+ {
+ Lisp_Object tem = build_string (adir);
+
+ tem = DECODE_FILE (tem);
+ memcpy (adir, SSDATA (tem), SBYTES (tem) + 1);
+ }
newdir = adir;
}
@@ -1249,7 +1300,7 @@
strcpy (target, newdir);
}
else
- file_name_as_directory (target, newdir, length);
+ file_name_as_directory (target, newdir, length, multibyte);
}
strcat (target, nm);
@@ -1335,9 +1386,14 @@
target[1] = ':';
}
result = make_specified_string (target, -1, o - target, multibyte);
- result = ENCODE_FILE (result);
- dostounix_filename (SSDATA (result));
- result = DECODE_FILE (result);
+ if (multibyte)
+ {
+ result = ENCODE_FILE (result);
+ dostounix_filename (SSDATA (result));
+ result = DECODE_FILE (result);
+ }
+ else
+ dostounix_filename (SSDATA (result));
#else /* !DOS_NT */
result = make_specified_string (target, -1, o - target, multibyte);
#endif /* !DOS_NT */
@@ -1619,18 +1675,24 @@
memcpy (nm, SDATA (filename), SBYTES (filename) + 1);
#ifdef DOS_NT
- {
- Lisp_Object encoded_filename = ENCODE_FILE (filename);
- Lisp_Object tem_fn;
+ if (multibyte)
+ {
+ Lisp_Object encoded_filename = ENCODE_FILE (filename);
+ Lisp_Object tem_fn;
- dostounix_filename (SDATA (encoded_filename));
- tem_fn = DECODE_FILE (encoded_filename);
- nm = alloca (SBYTES (tem_fn) + 1);
- memcpy (nm, SDATA (tem_fn), SBYTES (tem_fn) + 1);
- substituted = (memcmp (nm, SDATA (filename), SBYTES (filename)) != 0);
- if (substituted)
- filename = tem_fn;
- }
+ dostounix_filename (SDATA (encoded_filename));
+ tem_fn = DECODE_FILE (encoded_filename);
+ nm = alloca (SBYTES (tem_fn) + 1);
+ memcpy (nm, SDATA (tem_fn), SBYTES (tem_fn) + 1);
+ substituted = (memcmp (nm, SDATA (filename), SBYTES (filename)) != 0);
+ if (substituted)
+ filename = tem_fn;
+ }
+ else
+ {
+ dostounix_filename (nm);
+ substituted = (memcmp (nm, SDATA (filename), SBYTES (filename)) != 0);
+ }
#endif
endp = nm + SBYTES (filename);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] /srv/bzr/emacs/emacs-24 r111077: Fix bug #13262 with crashes in completion on MS-Windows with non-ASCII filenames.,
Eli Zaretskii <=