[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] emacs/src ChangeLog fileio.c
From: |
Jason Rumney |
Subject: |
[Emacs-diffs] emacs/src ChangeLog fileio.c |
Date: |
Tue, 24 Mar 2009 14:14:55 +0000 |
CVSROOT: /sources/emacs
Module name: emacs
Changes by: Jason Rumney <jasonr> 09/03/24 14:14:55
Modified files:
src : ChangeLog fileio.c
Log message:
(Fsubstitute_in_file_name): Always work on a copy.
Calculate total size precisely. Decode environment variables
before substituting. (Bug#38)
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/emacs/src/ChangeLog?cvsroot=emacs&r1=1.7448&r2=1.7449
http://cvs.savannah.gnu.org/viewcvs/emacs/src/fileio.c?cvsroot=emacs&r1=1.650&r2=1.651
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/emacs/emacs/src/ChangeLog,v
retrieving revision 1.7448
retrieving revision 1.7449
diff -u -b -r1.7448 -r1.7449
--- ChangeLog 24 Mar 2009 01:41:41 -0000 1.7448
+++ ChangeLog 24 Mar 2009 14:14:53 -0000 1.7449
@@ -1,3 +1,9 @@
+2009-03-24 Jason Rumney <address@hidden>
+
+ * fileio.c (Fsubstitute_in_file_name): Always work on a copy.
+ Calculate total size precisely. Decode environment variables
+ before substituting. (Bug#38)
+
2009-03-24 Kenichi Handa <address@hidden>
* font.c (find_font_encoding): Return Qnil for unsupported
Index: fileio.c
===================================================================
RCS file: /sources/emacs/emacs/src/fileio.c,v
retrieving revision 1.650
retrieving revision 1.651
diff -u -b -r1.650 -r1.651
--- fileio.c 19 Mar 2009 06:26:07 -0000 1.650
+++ fileio.c 24 Mar 2009 14:14:54 -0000 1.651
@@ -1629,11 +1629,14 @@
unsigned char *target = NULL;
int total = 0;
int substituted = 0;
+ int multibyte;
unsigned char *xnm;
Lisp_Object handler;
CHECK_STRING (filename);
+ multibyte = STRING_MULTIBYTE (filename);
+
/* If the file name has special constructs in it,
call the corresponding file handler. */
handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
@@ -1641,8 +1644,11 @@
return call2 (handler, Qsubstitute_in_file_name, filename);
nm = SDATA (filename);
-#ifdef DOS_NT
+ /* Always work on a copy of the string, in case GC happens during
+ decode of environment variables, causing the original Lisp_String
+ data to be relocated. */
nm = strcpy (alloca (strlen (nm) + 1), nm);
+#ifdef DOS_NT
CORRECT_DIR_SEPS (nm);
substituted = (strcmp (nm, SDATA (filename)) != 0);
#endif
@@ -1655,9 +1661,7 @@
again. Important with filenames like "/home/foo//:/hello///there"
which whould substitute to "/:/hello///there" rather than "/there". */
return Fsubstitute_in_file_name
- (make_specified_string (p, -1, endp - p,
- STRING_MULTIBYTE (filename)));
-
+ (make_specified_string (p, -1, endp - p, multibyte));
/* See if any variables are substituted into the string
and find the total length of their values in `total' */
@@ -1703,8 +1707,16 @@
/* Get variable value */
o = (unsigned char *) egetenv (target);
if (o)
- { /* Eight-bit chars occupy upto 2 bytes in multibyte. */
- total += strlen (o) * (STRING_MULTIBYTE (filename) ? 2 : 1);
+ {
+ /* Don't try to guess a maximum length - UTF8 can use up to
+ four bytes per character. This code is unlikely to run
+ in a situation that requires performance, so decoding the
+ env variables twice should be acceptable. Note that
+ decoding may cause a garbage collect. */
+ Lisp_Object orig, decoded;
+ orig = make_unibyte_string (o, strlen (o));
+ decoded = DECODE_FILE (orig);
+ total += SBYTES (decoded);
substituted = 1;
}
else if (*p == '}')
@@ -1762,21 +1774,22 @@
*x++ = '$';
strcpy (x, target); x+= strlen (target);
}
- else if (STRING_MULTIBYTE (filename))
- {
- /* If the original string is multibyte,
- convert what we substitute into multibyte. */
- while (*o)
- {
- int c = *o++;
- c = unibyte_char_to_multibyte (c);
- x += CHAR_STRING (c, x);
- }
- }
else
{
- strcpy (x, o);
- x += strlen (o);
+ Lisp_Object orig, decoded;
+ int orig_length, decoded_length;
+ orig_length = strlen (o);
+ orig = make_unibyte_string (o, orig_length);
+ decoded = DECODE_FILE (orig);
+ decoded_length = SBYTES (decoded);
+ strncpy (x, SDATA (decoded), decoded_length);
+ x += decoded_length;
+
+ /* If environment variable needed decoding, return value
+ needs to be multibyte. */
+ if (decoded_length != orig_length
+ || strncmp (SDATA (decoded), o, orig_length))
+ multibyte = 1;
}
}
@@ -1789,7 +1802,7 @@
need to quote some $ to $$ first. */
xnm = p;
- return make_specified_string (xnm, -1, x - xnm, STRING_MULTIBYTE (filename));
+ return make_specified_string (xnm, -1, x - xnm, multibyte);
badsubst:
error ("Bad format environment-variable substitution");