This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, libfortran] Replace sprintf() with snprintf()
- From: Janne Blomqvist <blomqvist dot janne at gmail dot com>
- To: Fortran List <fortran at gcc dot gnu dot org>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 15 Apr 2011 09:53:52 +0300
- Subject: [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;
}