This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, libfortran] Replace sprintf() with snprintf()


Hi,

as is well known, sprintf() is prone to buffer overflow, hence
snprintf(). libgfortran uses snprintf() in some places, but not
everywhere. Rather than analyzing every sprintf() call for a potential
overflow, the attached patch takes the dogmatic but simple approach of
replacing all the remaining sprintf() usage with snprintf().

For targets without snprintf(), io/list_read.c contained a fallback
macro that uses sprintf(); this is moved to libgfortran.h so that it's
available everywhere.

readelf -s libgfortran.so|grep sprintf

confirms that there is no remaining usage of sprintf().

Regtested on x86_64-unknown-linux-gnu, Ok for trunk?

2011-04-15  Janne Blomqvist  <jb@gcc.gnu.org>

	* intrinsics/date_and_time.c (date_and_time): Remove sprintf CPP
	branch.
	* io/format.c (format_error): Use snprintf instead of sprintf.
	* io/list_read.c: Move snprintf fallback macro to libgfortran.h.
	(convert_integer): Use snprintf instead of sprintf.
	(parse_repeat): Likewise.
	(read_logical): Likewise.
	(read_integer): Likewise.
	(read_character): Likewise.
	(parse_real): Likewise.
	(read_complex): Likewise.
	(read_real): Likewise.
	(check_type): Likewise.
	(nml_parse_qualifier): Add string length argument, use snprintf
	instead of sprintf.
	(nml_get_obj_data): Use snprintf instead of sprintf.
	* io/open.c (new_unit): Remove sprintf CPP branch, use snprintf
	instead of sprintf.
	* io/transfer.c (require_type): Use snprintf instead of sprintf.
	* io/unix.c (tempfile): Likewise.
	* io/write.c (nml_write_obj): Likewise.
	* io/write_float.def (output_float): Remove sprintf CPP branch,
	use snprintf instead of sprintf.
	* libgfortran.h: Add fallback snprintf macro from io/list_read.c.
	* runtime/backtrace.c (show_backtrace): Remove sprintf CPP branch.
	* runtime/main.c (store_exe_path): Use snprintf instead of
	sprintf.


-- 
Janne Blomqvist
diff --git a/libgfortran/intrinsics/date_and_time.c b/libgfortran/intrinsics/date_and_time.c
index 793df68..fa51d5f 100644
--- a/libgfortran/intrinsics/date_and_time.c
+++ b/libgfortran/intrinsics/date_and_time.c
@@ -168,7 +168,6 @@ date_and_time (char *__date, char *__time, char *__zone,
       values[5] = local_time.tm_min;
       values[6] = local_time.tm_sec;
 
-#if HAVE_SNPRINTF
       if (__date)
 	snprintf (date, DATE_LEN + 1, "%04d%02d%02d",
 		  values[0], values[1], values[2]);
@@ -179,18 +178,6 @@ date_and_time (char *__date, char *__time, char *__zone,
       if (__zone)
 	snprintf (zone, ZONE_LEN + 1, "%+03d%02d",
 		  values[3] / 60, abs (values[3] % 60));
-#else
-      if (__date)
-	sprintf (date, "%04d%02d%02d", values[0], values[1], values[2]);
-
-      if (__time)
-	sprintf (timec, "%02d%02d%02d.%03d",
-		 values[4], values[5], values[6], values[7]);
-
-      if (__zone)
-	sprintf (zone, "%+03d%02d",
-		 values[3] / 60, abs (values[3] % 60));
-#endif
     }
   else
     {
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
index d540fc4..5760e0c 100644
--- a/libgfortran/io/format.c
+++ b/libgfortran/io/format.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Andy Vaught
    F2003 I/O support contributed by Jerry DeLisle
@@ -1127,16 +1127,17 @@ void
 format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
 {
   int width, i, j, offset;
-  char *p, buffer[300];
+#define BUFLEN 300
+  char *p, buffer[BUFLEN];
   format_data *fmt = dtp->u.p.fmt;
 
   if (f != NULL)
     fmt->format_string = f->source;
 
   if (message == unexpected_element)
-    sprintf (buffer, message, fmt->error_element);
+    snprintf (buffer, BUFLEN, message, fmt->error_element);
   else
-    sprintf (buffer, "%s\n", message);
+    snprintf (buffer, BUFLEN, "%s\n", message);
 
   j = fmt->format_string - dtp->format;
 
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index 39783bf..38a92e1 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Andy Vaught
    Namelist input contributed by Paul Thomas
@@ -63,10 +63,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 #define MAX_REPEAT 200000000
 
-#ifndef HAVE_SNPRINTF
-# undef snprintf
-# define snprintf(str, size, ...) sprintf (str, __VA_ARGS__)
-#endif
+
+#define MSGLEN 100
 
 /* Save a character to a string buffer, enlarging it as necessary.  */
 
@@ -471,7 +469,7 @@ nml_bad_return (st_parameter_dt *dtp, char c)
 static int
 convert_integer (st_parameter_dt *dtp, int length, int negative)
 {
-  char c, *buffer, message[100];
+  char c, *buffer, message[MSGLEN];
   int m;
   GFC_INTEGER_LARGEST v, max, max10;
 
@@ -511,7 +509,7 @@ convert_integer (st_parameter_dt *dtp, int length, int negative)
 
       if (dtp->u.p.repeat_count == 0)
 	{
-	  sprintf (message, "Zero repeat count in item %d of list input",
+	  snprintf (message, MSGLEN, "Zero repeat count in item %d of list input",
 		   dtp->u.p.item_count);
 
 	  generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
@@ -524,10 +522,10 @@ convert_integer (st_parameter_dt *dtp, int length, int negative)
 
  overflow:
   if (length == -1)
-    sprintf (message, "Repeat count overflow in item %d of list input",
+    snprintf (message, MSGLEN, "Repeat count overflow in item %d of list input",
 	     dtp->u.p.item_count);
   else
-    sprintf (message, "Integer overflow while reading item %d",
+    snprintf (message, MSGLEN, "Integer overflow while reading item %d",
 	     dtp->u.p.item_count);
 
   free_saved (dtp);
@@ -544,7 +542,7 @@ convert_integer (st_parameter_dt *dtp, int length, int negative)
 static int
 parse_repeat (st_parameter_dt *dtp)
 {
-  char message[100];
+  char message[MSGLEN];
   int c, repeat;
 
   if ((c = next_char (dtp)) == EOF)
@@ -575,7 +573,7 @@ parse_repeat (st_parameter_dt *dtp)
 
 	  if (repeat > MAX_REPEAT)
 	    {
-	      sprintf (message,
+	      snprintf (message, MSGLEN,
 		       "Repeat count overflow in item %d of list input",
 		       dtp->u.p.item_count);
 
@@ -588,7 +586,7 @@ parse_repeat (st_parameter_dt *dtp)
 	case '*':
 	  if (repeat == 0)
 	    {
-	      sprintf (message,
+	      snprintf (message, MSGLEN,
 		       "Zero repeat count in item %d of list input",
 		       dtp->u.p.item_count);
 
@@ -617,7 +615,7 @@ parse_repeat (st_parameter_dt *dtp)
     }
   else
     eat_line (dtp);
-  sprintf (message, "Bad repeat count in item %d of list input",
+  snprintf (message, MSGLEN, "Bad repeat count in item %d of list input",
 	   dtp->u.p.item_count);
   generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
   return 1;
@@ -647,7 +645,7 @@ l_push_char (st_parameter_dt *dtp, char c)
 static void
 read_logical (st_parameter_dt *dtp, int length)
 {
-  char message[100];
+  char message[MSGLEN];
   int c, i, v;
 
   if (parse_repeat (dtp))
@@ -770,7 +768,7 @@ read_logical (st_parameter_dt *dtp, int length)
     }
   else if (c != '\n')
     eat_line (dtp);
-  sprintf (message, "Bad logical value while reading item %d",
+  snprintf (message, MSGLEN, "Bad logical value while reading item %d",
 	      dtp->u.p.item_count);
   generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
   return;
@@ -793,7 +791,7 @@ read_logical (st_parameter_dt *dtp, int length)
 static void
 read_integer (st_parameter_dt *dtp, int length)
 {
-  char message[100];
+  char message[MSGLEN];
   int c, negative;
 
   negative = 0;
@@ -908,7 +906,7 @@ read_integer (st_parameter_dt *dtp, int length)
     }
   else if (c != '\n')
     eat_line (dtp);
-  sprintf (message, "Bad integer for item %d in list input",
+  snprintf (message, MSGLEN, "Bad integer for item %d in list input",
 	      dtp->u.p.item_count);
   generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
 
@@ -935,7 +933,7 @@ read_integer (st_parameter_dt *dtp, int length)
 static void
 read_character (st_parameter_dt *dtp, int length __attribute__ ((unused)))
 {
-  char quote, message[100];
+  char quote, message[MSGLEN];
   int c;
 
   quote = ' ';			/* Space means no quote character.  */
@@ -1086,7 +1084,7 @@ read_character (st_parameter_dt *dtp, int length __attribute__ ((unused)))
 	  hit_eof (dtp);
 	  return;
 	}
-      sprintf (message, "Invalid string input in item %d",
+      snprintf (message, MSGLEN, "Invalid string input in item %d",
 		  dtp->u.p.item_count);
       generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
     }
@@ -1099,7 +1097,7 @@ read_character (st_parameter_dt *dtp, int length __attribute__ ((unused)))
 static int
 parse_real (st_parameter_dt *dtp, void *buffer, int length)
 {
-  char message[100];
+  char message[MSGLEN];
   int c, m, seen_dp;
 
   if ((c = next_char (dtp)) == EOF)
@@ -1284,7 +1282,7 @@ parse_real (st_parameter_dt *dtp, void *buffer, int length)
     }
   else if (c != '\n')
     eat_line (dtp);
-  sprintf (message, "Bad floating point number for item %d",
+  snprintf (message, MSGLEN, "Bad floating point number for item %d",
 	      dtp->u.p.item_count);
   generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
 
@@ -1298,7 +1296,7 @@ parse_real (st_parameter_dt *dtp, void *buffer, int length)
 static void
 read_complex (st_parameter_dt *dtp, void * dest, int kind, size_t size)
 {
-  char message[100];
+  char message[MSGLEN];
   int c;
 
   if (parse_repeat (dtp))
@@ -1388,7 +1386,7 @@ eol_4:
     }
   else if (c != '\n')   
     eat_line (dtp);
-  sprintf (message, "Bad complex value in item %d of list input",
+  snprintf (message, MSGLEN, "Bad complex value in item %d of list input",
 	      dtp->u.p.item_count);
   generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
 }
@@ -1399,7 +1397,7 @@ eol_4:
 static void
 read_real (st_parameter_dt *dtp, void * dest, int length)
 {
-  char message[100];
+  char message[MSGLEN];
   int c;
   int seen_dp;
   int is_inf;
@@ -1760,7 +1758,7 @@ read_real (st_parameter_dt *dtp, void * dest, int length)
   else if (c != '\n')
     eat_line (dtp);
 
-  sprintf (message, "Bad real number in item %d of list input",
+  snprintf (message, MSGLEN, "Bad real number in item %d of list input",
 	      dtp->u.p.item_count);
   generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
 }
@@ -1772,11 +1770,11 @@ read_real (st_parameter_dt *dtp, void * dest, int length)
 static int
 check_type (st_parameter_dt *dtp, bt type, int len)
 {
-  char message[100];
+  char message[MSGLEN];
 
   if (dtp->u.p.saved_type != BT_UNKNOWN && dtp->u.p.saved_type != type)
     {
-      sprintf (message, "Read type %s where %s was expected for item %d",
+      snprintf (message, MSGLEN, "Read type %s where %s was expected for item %d",
 		  type_name (dtp->u.p.saved_type), type_name (type),
 		  dtp->u.p.item_count);
 
@@ -1789,7 +1787,7 @@ check_type (st_parameter_dt *dtp, bt type, int len)
 
   if (dtp->u.p.saved_length != len)
     {
-      sprintf (message,
+      snprintf (message, MSGLEN,
 		  "Read kind %d %s where kind %d is required for item %d",
 		  dtp->u.p.saved_length, type_name (dtp->u.p.saved_type), len,
 		  dtp->u.p.item_count);
@@ -2040,6 +2038,7 @@ calls:
 static try
 nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad,
 		     array_loop_spec *ls, int rank, char *parse_err_msg,
+		     size_t parse_err_msg_size,
 		     int *parsed_rank)
 {
   int dim;
@@ -2109,9 +2108,11 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad,
 		      || (c==')' && dim < rank -1))
 		    {
 		      if (is_char)
-		        sprintf (parse_err_msg, "Bad substring qualifier");
+		        snprintf (parse_err_msg, parse_err_msg_size, 
+				  "Bad substring qualifier");
 		      else
-			sprintf (parse_err_msg, "Bad number of index fields");
+			snprintf (parse_err_msg, parse_err_msg_size, 
+				 "Bad number of index fields");
 		      goto err_ret;
 		    }
 		  break;
@@ -2128,10 +2129,11 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad,
 
 		default:
 		  if (is_char)
-		    sprintf (parse_err_msg,
+		    snprintf (parse_err_msg, parse_err_msg_size,
 			     "Bad character in substring qualifier");
 		  else
-		    sprintf (parse_err_msg, "Bad character in index");
+		    snprintf (parse_err_msg, parse_err_msg_size, 
+			      "Bad character in index");
 		  goto err_ret;
 		}
 
@@ -2139,9 +2141,11 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad,
 		  && dtp->u.p.saved_string == 0)
 		{
 		  if (is_char)
-		    sprintf (parse_err_msg, "Null substring qualifier");
+		    snprintf (parse_err_msg, parse_err_msg_size, 
+			      "Null substring qualifier");
 		  else
-		    sprintf (parse_err_msg, "Null index field");
+		    snprintf (parse_err_msg, parse_err_msg_size, 
+			      "Null index field");
 		  goto err_ret;
 		}
 
@@ -2149,15 +2153,17 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad,
 		  || (indx == 2 && dtp->u.p.saved_string == 0))
 		{
 		  if (is_char)
-		    sprintf (parse_err_msg, "Bad substring qualifier");
+		    snprintf (parse_err_msg, parse_err_msg_size, 
+			      "Bad substring qualifier");
 		  else
-		    sprintf (parse_err_msg, "Bad index triplet");
+		    snprintf (parse_err_msg, parse_err_msg_size,
+			      "Bad index triplet");
 		  goto err_ret;
 		}
 
 	      if (is_char && !is_array_section)
 		{
-		  sprintf (parse_err_msg,
+		  snprintf (parse_err_msg, parse_err_msg_size,
 			   "Missing colon in substring qualifier");
 		  goto err_ret;
 		}
@@ -2175,9 +2181,11 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad,
 	      if (convert_integer (dtp, sizeof(index_type), neg))
 		{
 		  if (is_char)
-		    sprintf (parse_err_msg, "Bad integer substring qualifier");
+		    snprintf (parse_err_msg, parse_err_msg_size,
+			      "Bad integer substring qualifier");
 		  else
-		    sprintf (parse_err_msg, "Bad integer in index");
+		    snprintf (parse_err_msg, parse_err_msg_size,
+			      "Bad integer in index");
 		  goto err_ret;
 		}
 	      break;
@@ -2235,16 +2243,19 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad,
 	   || (ls[dim].end < GFC_DIMENSION_LBOUND(ad[dim])))
 	{
 	  if (is_char)
-	    sprintf (parse_err_msg, "Substring out of range");
+	    snprintf (parse_err_msg, parse_err_msg_size, 
+		      "Substring out of range");
 	  else
-	    sprintf (parse_err_msg, "Index %d out of range", dim + 1);
+	    snprintf (parse_err_msg, parse_err_msg_size, 
+		      "Index %d out of range", dim + 1);
 	  goto err_ret;
 	}
 
       if (((ls[dim].end - ls[dim].start ) * ls[dim].step < 0)
 	  || (ls[dim].step == 0))
 	{
-	  sprintf (parse_err_msg, "Bad range in index %d", dim + 1);
+	  snprintf (parse_err_msg, parse_err_msg_size, 
+		   "Bad range in index %d", dim + 1);
 	  goto err_ret;
 	}
 
@@ -2732,7 +2743,8 @@ nml_get_obj_data (st_parameter_dt *dtp, namelist_info **pprev_nl,
 	return FAILURE;
       if (c != '?')
 	{
-	  sprintf (nml_err_msg, "namelist read: misplaced = sign");
+	  snprintf (nml_err_msg, nml_err_msg_size, 
+		    "namelist read: misplaced = sign");
 	  goto nml_err_ret;
 	}
       nml_query (dtp, '=');
@@ -2747,7 +2759,8 @@ nml_get_obj_data (st_parameter_dt *dtp, namelist_info **pprev_nl,
       nml_match_name (dtp, "end", 3);
       if (dtp->u.p.nml_read_error)
 	{
-	  sprintf (nml_err_msg, "namelist not terminated with / or &end");
+	  snprintf (nml_err_msg, nml_err_msg_size, 
+		    "namelist not terminated with / or &end");
 	  goto nml_err_ret;
 	}
     case '/':
@@ -2838,7 +2851,8 @@ get_name:
     {
       parsed_rank = 0;
       if (nml_parse_qualifier (dtp, nl->dim, nl->ls, nl->var_rank,
-			       nml_err_msg, &parsed_rank) == FAILURE)
+			       nml_err_msg, nml_err_msg_size, 
+			       &parsed_rank) == FAILURE)
 	{
 	  char *nml_err_msg_end = strchr (nml_err_msg, '\0');
 	  snprintf (nml_err_msg_end,
@@ -2893,7 +2907,8 @@ get_name:
       descriptor_dimension chd[1] = { {1, clow, nl->string_length} };
       array_loop_spec ind[1] = { {1, clow, nl->string_length, 1} };
 
-      if (nml_parse_qualifier (dtp, chd, ind, -1, nml_err_msg, &parsed_rank)
+      if (nml_parse_qualifier (dtp, chd, ind, -1, nml_err_msg, 
+			       nml_err_msg_size, &parsed_rank)
 	  == FAILURE)
 	{
 	  char *nml_err_msg_end = strchr (nml_err_msg, '\0');
diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c
index d7448c0..bcf7941 100644
--- a/libgfortran/io/open.c
+++ b/libgfortran/io/open.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Andy Vaught
    F2003 I/O support contributed by Jerry DeLisle
@@ -467,12 +467,8 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags)
 	break;
 
       opp->file = tmpname;
-#ifdef HAVE_SNPRINTF
       opp->file_len = snprintf(opp->file, sizeof (tmpname), "fort.%d", 
 			       (int) opp->common.unit);
-#else
-      opp->file_len = sprintf(opp->file, "fort.%d", (int) opp->common.unit);
-#endif
       break;
 
     default:
@@ -504,26 +500,29 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags)
   if (s == NULL)
     {
       char *path, *msg;
+      size_t msglen;
       path = (char *) gfc_alloca (opp->file_len + 1);
-      msg = (char *) gfc_alloca (opp->file_len + 51);
+      msglen = opp->file_len + 51;
+      msg = (char *) gfc_alloca (msglen);
       unpack_filename (path, opp->file, opp->file_len);
 
       switch (errno)
 	{
 	case ENOENT: 
-	  sprintf (msg, "File '%s' does not exist", path);
+	  snprintf (msg, msglen, "File '%s' does not exist", path);
 	  break;
 
 	case EEXIST:
-	  sprintf (msg, "File '%s' already exists", path);
+	  snprintf (msg, msglen, "File '%s' already exists", path);
 	  break;
 
 	case EACCES:
-	  sprintf (msg, "Permission denied trying to open file '%s'", path);
+	  snprintf (msg, msglen, 
+		    "Permission denied trying to open file '%s'", path);
 	  break;
 
 	case EISDIR:
-	  sprintf (msg, "'%s' is a directory", path);
+	  snprintf (msg, msglen, "'%s' is a directory", path);
 	  break;
 
 	default:
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index 15f90e7..12aca97 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -1047,13 +1047,15 @@ write_constant_string (st_parameter_dt *dtp, const fnode *f)
 static int
 require_type (st_parameter_dt *dtp, bt expected, bt actual, const fnode *f)
 {
-  char buffer[100];
+#define BUFLEN 100
+  char buffer[BUFLEN];
 
   if (actual == expected)
     return 0;
 
   /* Adjust item_count before emitting error message.  */
-  sprintf (buffer, "Expected %s for item %d in formatted transfer, got %s",
+  snprintf (buffer, BUFLEN, 
+	    "Expected %s for item %d in formatted transfer, got %s",
 	   type_name (expected), dtp->u.p.item_count - 1, type_name (actual));
 
   format_error (dtp, f, buffer);
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index d14d2b4..4295071 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -1068,7 +1068,8 @@ tempfile (st_parameter_open *opp)
   template = get_mem (tempdirlen + 23);
 
 #ifdef HAVE_MKSTEMP
-  sprintf (template, "%s%sgfortrantmpXXXXXX", tempdir, slash);
+  snprintf (template, tempdirlen + 23, "%s%sgfortrantmpXXXXXX", 
+	    tempdir, slash);
 
   fd = mkstemp (template);
 
@@ -1078,7 +1079,8 @@ tempfile (st_parameter_open *opp)
   slashlen = strlen (slash);
   do
     {
-      sprintf (template, "%s%sgfortrantmpaaaXXXXXX", tempdir, slash);
+      snprintf (template, tempdirlen + 23, "%s%sgfortrantmpaaaXXXXXX", 
+		tempdir, slash);
       if (count > 0)
 	{
 	  int c = count;
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 4733d51..5338162 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Andy Vaught
    Namelist output contributed by Paul Thomas
@@ -1689,6 +1689,7 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info * obj, index_type offset,
   char cup;
   char * obj_name;
   char * ext_name;
+  size_t ext_name_len;
   char rep_buff[NML_DIGITS];
   namelist_info * cmp;
   namelist_info * retval = obj->next;
@@ -1797,7 +1798,7 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info * obj, index_type offset,
 	{
 	  if (rep_ctr > 1)
 	    {
-	      sprintf(rep_buff, " %d*", rep_ctr);
+	      snprintf(rep_buff, NML_DIGITS, " %d*", rep_ctr);
 	      write_character (dtp, rep_buff, 1, strlen (rep_buff));
 	      dtp->u.p.no_leading_blank = 1;
 	    }
@@ -1851,11 +1852,9 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info * obj, index_type offset,
 
 	      base_name_len = base_name ? strlen (base_name) : 0;
 	      base_var_name_len = base ? strlen (base->var_name) : 0;
-	      ext_name = (char*)get_mem ( base_name_len
-					+ base_var_name_len
-					+ strlen (obj->var_name)
-					+ obj->var_rank * NML_DIGITS
-					+ 1);
+	      ext_name_len = base_name_len + base_var_name_len 
+		+ strlen (obj->var_name) + obj->var_rank * NML_DIGITS + 1;
+	      ext_name = (char*)get_mem (ext_name_len);
 
 	      memcpy (ext_name, base_name, base_name_len);
 	      clen = strlen (obj->var_name + base_var_name_len);
@@ -1872,7 +1871,8 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info * obj, index_type offset,
 		      ext_name[tot_len] = '(';
 		      tot_len++;
 		    }
-		  sprintf (ext_name + tot_len, "%d", (int) obj->ls[dim_i].idx);
+		  snprintf (ext_name + tot_len, ext_name_len - tot_len, "%d", 
+			    (int) obj->ls[dim_i].idx);
 		  tot_len += strlen (ext_name + tot_len);
 		  ext_name[tot_len] = ((int) dim_i == obj->var_rank - 1) ? ')' : ',';
 		  tot_len++;
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def
index b72cf9f..9661b2b 100644
--- a/libgfortran/io/write_float.def
+++ b/libgfortran/io/write_float.def
@@ -524,11 +524,7 @@ output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size,
 	      *(out4++) = expchar;
 	      edigits--;
 	    }
-#if HAVE_SNPRINTF
 	  snprintf (buffer, size, "%+0*d", edigits, e);
-#else
-	  sprintf (buffer, "%+0*d", edigits, e);
-#endif
 	  memcpy4 (out4, buffer, edigits);
 	}
 
@@ -616,11 +612,7 @@ output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size,
 	  *(out++) = expchar;
 	  edigits--;
 	}
-#if HAVE_SNPRINTF
       snprintf (buffer, size, "%+0*d", edigits, e);
-#else
-      sprintf (buffer, "%+0*d", edigits, e);
-#endif
       memcpy (out, buffer, edigits);
     }
 
@@ -940,7 +932,7 @@ OUTPUT_FLOAT_FMT_G(16)
 
 /* Define a macro to build code for write_float.  */
 
-  /* Note: Before output_float is called, sprintf is used to print to buffer the
+  /* Note: Before output_float is called, snprintf is used to print to buffer the
      number in the format +D.DDDDe+ddd. For an N digit exponent, this gives us
      (MIN_FIELD_WIDTH-5)-N digits after the decimal point, plus another one
      before the decimal point.
@@ -961,8 +953,6 @@ OUTPUT_FLOAT_FMT_G(16)
        equal to the precision. The exponent always contains at least two
        digits; if the value is zero, the exponent is 00.  */
 
-#ifdef HAVE_SNPRINTF
-
 #define DTOA \
 snprintf (buffer, size, "%+-#" STR(MIN_FIELD_WIDTH) ".*" \
 	  "e", ndigits - 1, tmp);
@@ -971,17 +961,6 @@ snprintf (buffer, size, "%+-#" STR(MIN_FIELD_WIDTH) ".*" \
 snprintf (buffer, size, "%+-#" STR(MIN_FIELD_WIDTH) ".*" \
 	  "Le", ndigits - 1, tmp);
 
-#else
-
-#define DTOA \
-sprintf (buffer, "%+-#" STR(MIN_FIELD_WIDTH) ".*" \
-	 "e", ndigits - 1, tmp);
-
-#define DTOAL \
-sprintf (buffer, "%+-#" STR(MIN_FIELD_WIDTH) ".*" \
-	 "Le", ndigits - 1, tmp);
-
-#endif
 
 #if defined(GFC_REAL_16_IS_FLOAT128)
 #define DTOAQ \
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index 7d9aca1..6cccaca 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -119,6 +119,10 @@ extern int __mingw_snprintf (char *, size_t, const char *, ...)
      __attribute__ ((format (gnu_printf, 3, 4)));
 #undef snprintf
 #define snprintf __mingw_snprintf
+/* Fallback to sprintf if target does not have snprintf.  */
+#elif !defined(HAVE_SNPRINTF)
+#undef snprintf
+#define snprintf(str, size, ...) sprintf (str, __VA_ARGS__)
 #endif
 
 
diff --git a/libgfortran/runtime/backtrace.c b/libgfortran/runtime/backtrace.c
index 4a831c0..5e4f15c 100644
--- a/libgfortran/runtime/backtrace.c
+++ b/libgfortran/runtime/backtrace.c
@@ -1,7 +1,7 @@
-/* Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007, 2009, 2011 Free Software Foundation, Inc.
    Contributed by FranÃois-Xavier Coudert
 
-This file is part of the GNU Fortran 95 runtime library (libgfortran).
+This file is part of the GNU Fortran runtime library (libgfortran).
 
 Libgfortran is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -290,11 +290,7 @@ fallback:
 
 	st_printf ("\nBacktrace for this error:\n");
 	arg[0] = (char *) "pstack";
-#ifdef HAVE_SNPRINTF
 	snprintf (buf, sizeof(buf), "%d", (int) getppid ());
-#else
-	sprintf (buf, "%d", (int) getppid ());
-#endif
 	arg[1] = buf;
 	arg[2] = NULL;
 	execvp (arg[0], arg);
diff --git a/libgfortran/runtime/main.c b/libgfortran/runtime/main.c
index 28247ca..f5d4721 100644
--- a/libgfortran/runtime/main.c
+++ b/libgfortran/runtime/main.c
@@ -1,7 +1,8 @@
-/* Copyright (C) 2002-2003, 2005, 2007, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2003, 2005, 2007, 2009, 2011 
+   Free Software Foundation, Inc.
    Contributed by Andy Vaught and Paul Brook <paul@nowt.org>
 
-This file is part of the GNU Fortran 95 runtime library (libgfortran).
+This file is part of the GNU Fortran runtime library (libgfortran).
 
 Libgfortran is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -107,8 +108,9 @@ store_exe_path (const char * argv0)
 #endif
 
   /* exe_path will be cwd + "/" + argv[0] + "\0" */
-  path = malloc (strlen (cwd) + 1 + strlen (argv0) + 1);
-  sprintf (path, "%s%c%s", cwd, DIR_SEPARATOR, argv0);
+  size_t pathlen = strlen (cwd) + 1 + strlen (argv0) + 1;
+  path = malloc (pathlen);
+  snprintf (path, pathlen, "%s%c%s", cwd, DIR_SEPARATOR, argv0);
   exe_path = path;
   please_free_exe_path_when_done = 1;
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]