changeset 103095:65cc22e2c624

* fns.c (Flocale_info): Protect vector from GC during decoding. * process.c (Fstart_process): Protect argv strings from GC during encoding.
author Andreas Schwab <schwab@linux-m68k.org>
date Tue, 28 Apr 2009 19:02:26 +0000
parents 64ac89a8b9a8
children d98eb168e700
files src/ChangeLog src/fns.c src/process.c
diffstat 3 files changed, 54 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Tue Apr 28 19:00:38 2009 +0000
+++ b/src/ChangeLog	Tue Apr 28 19:02:26 2009 +0000
@@ -1,3 +1,10 @@
+2009-04-28  Andreas Schwab  <schwab@linux-m68k.org>
+
+	* fns.c (Flocale_info): Protect vector from GC during decoding.
+
+	* process.c (Fstart_process): Protect argv strings from GC during
+	encoding.
+
 2009-04-27  Andreas Schwab  <schwab@linux-m68k.org>
 
 	* sysdep.c: Include <ctype.h>.
--- a/src/fns.c	Tue Apr 28 19:00:38 2009 +0000
+++ b/src/fns.c	Tue Apr 28 19:02:26 2009 +0000
@@ -3135,8 +3135,10 @@
   else if (EQ (item, Qdays))	/* e.g. for calendar-day-name-array */
     {
       Lisp_Object v = Fmake_vector (make_number (7), Qnil);
-      int days[7] = {DAY_1, DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7};
+      const int days[7] = {DAY_1, DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7};
       int i;
+      struct gcpro gcpro1;
+      GCPRO1 (v);
       synchronize_system_time_locale ();
       for (i = 0; i < 7; i++)
 	{
@@ -3148,26 +3150,29 @@
 		 code_convert_string_norecord (val, Vlocale_coding_system,
 					       0));
 	}
+      UNGCPRO;
       return v;
     }
 #endif	/* DAY_1 */
 #ifdef MON_1
   else if (EQ (item, Qmonths))	/* e.g. for calendar-month-name-array */
     {
-      struct Lisp_Vector *p = allocate_vector (12);
-      int months[12] = {MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, MON_7,
-			MON_8, MON_9, MON_10, MON_11, MON_12};
+      Lisp_Object v = Fmake_vector (make_number (12), Qnil);
+      const int months[12] = {MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, MON_7,
+			      MON_8, MON_9, MON_10, MON_11, MON_12};
       int i;
+      struct gcpro gcpro1;
+      GCPRO1 (v);
       synchronize_system_time_locale ();
       for (i = 0; i < 12; i++)
 	{
 	  str = nl_langinfo (months[i]);
 	  val = make_unibyte_string (str, strlen (str));
-	  p->contents[i] =
-	    code_convert_string_norecord (val, Vlocale_coding_system, 0);
+	  Faset (v, make_number (i),
+		 code_convert_string_norecord (val, Vlocale_coding_system, 0));
 	}
-      XSETVECTOR (val, p);
-      return val;
+      UNGCPRO;
+      return v;
     }
 #endif	/* MON_1 */
 /* LC_PAPER stuff isn't defined as accessible in glibc as of 2.3.1,
--- a/src/process.c	Tue Apr 28 19:00:38 2009 +0000
+++ b/src/process.c	Tue Apr 28 19:02:26 2009 +0000
@@ -1698,8 +1698,6 @@
     XPROCESS (proc)->encode_coding_system = val;
   }
 
-  new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *));
-
   /* If program file name is not absolute, search our path for it.
      Put the name we will really use in TEM.  */
   if (!IS_DIRECTORY_SEP (SREF (program, 0))
@@ -1729,26 +1727,42 @@
       && SREF (tem, 1) == ':')
     tem = Fsubstring (tem, make_number (2), Qnil);
 
-  /* Encode the file name and put it in NEW_ARGV.
-     That's where the child will use it to execute the program.  */
-  tem = ENCODE_FILE (tem);
-  new_argv[0] = SDATA (tem);
-
-  /* Here we encode arguments by the coding system used for sending
-     data to the process.  We don't support using different coding
-     systems for encoding arguments and for encoding data sent to the
-     process.  */
-
-  for (i = 3; i < nargs; i++)
+  {
+    struct gcpro gcpro1;
+    GCPRO1 (tem);
+
+    /* Encode the file name and put it in NEW_ARGV.
+       That's where the child will use it to execute the program.  */
+    tem = Fcons (ENCODE_FILE (tem), Qnil);
+
+    /* Here we encode arguments by the coding system used for sending
+       data to the process.  We don't support using different coding
+       systems for encoding arguments and for encoding data sent to the
+       process.  */
+
+    for (i = 3; i < nargs; i++)
+      {
+	tem = Fcons (args[i], tem);
+	CHECK_STRING (XCAR (tem));
+	if (STRING_MULTIBYTE (XCAR (tem)))
+	  XSETCAR (tem,
+		   code_convert_string_norecord
+		   (XCAR (tem), XPROCESS (proc)->encode_coding_system, 1));
+      }
+
+    UNGCPRO;
+  }
+
+  /* Now that everything is encoded we can collect the strings into
+     NEW_ARGV.  */
+  new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *));
+  new_argv[nargs - 2] = 0;
+
+  for (i = nargs - 3; i >= 0; i--)
     {
-      tem = args[i];
-      CHECK_STRING (tem);
-      if (STRING_MULTIBYTE (tem))
-	tem = (code_convert_string_norecord
-	       (tem, XPROCESS (proc)->encode_coding_system, 1));
-      new_argv[i - 2] = SDATA (tem);
+      new_argv[i] = SDATA (XCAR (tem));
+      tem = XCDR (tem);
     }
-  new_argv[i - 2] = 0;
 
   XPROCESS (proc)->decoding_buf = make_uninit_string (0);
   XPROCESS (proc)->decoding_carryover = 0;