From patchwork Fri Apr 15 06:53:52 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Janne Blomqvist X-Patchwork-Id: 91320 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 605D1B6FB7 for ; Fri, 15 Apr 2011 16:54:14 +1000 (EST) Received: (qmail 17392 invoked by alias); 15 Apr 2011 06:54:06 -0000 Received: (qmail 17364 invoked by uid 22791); 15 Apr 2011 06:54:00 -0000 X-SWARE-Spam-Status: No, hits=-0.9 required=5.0 tests=AWL, BAYES_50, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RFC_ABUSE_POST, TW_BG, TW_CP, TW_TP X-Spam-Check-By: sourceware.org Received: from mail-pw0-f47.google.com (HELO mail-pw0-f47.google.com) (209.85.160.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 15 Apr 2011 06:53:53 +0000 Received: by pwj9 with SMTP id 9so1149994pwj.20 for ; Thu, 14 Apr 2011 23:53:53 -0700 (PDT) MIME-Version: 1.0 Received: by 10.68.23.5 with SMTP id i5mr1568320pbf.272.1302850433018; Thu, 14 Apr 2011 23:53:53 -0700 (PDT) Received: by 10.68.42.34 with HTTP; Thu, 14 Apr 2011 23:53:52 -0700 (PDT) Date: Fri, 15 Apr 2011 09:53:52 +0300 Message-ID: Subject: [Patch, libfortran] Replace sprintf() with snprintf() From: Janne Blomqvist To: Fortran List , GCC Patches Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 * 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. 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 -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; }