Commit 04a4a57b by Janne Blomqvist

PR 19155 Check for strtod failure via endptr

From-SVN: r174393
parent be7a8395
2011-05-29 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/19155
* io/read.c (convert_real): Check for invalid input by comparing
endptr instead of EINVAL.
(read_f): Fixup floating point input without significand.
2011-05-22 Tobias Burnus <burnus@net-b.de> 2011-05-22 Tobias Burnus <burnus@net-b.de>
* runtime/stop.c (stop_string,error_stop_string): Minor cleanup. * runtime/stop.c (stop_string,error_stop_string): Minor cleanup.
......
/* Copyright (C) 2002, 2003, 2005, 2007, 2008, 2009, 2010 /* Copyright (C) 2002, 2003, 2005, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc. Free Software Foundation, Inc.
Contributed by Andy Vaught Contributed by Andy Vaught
F2003 I/O support contributed by Jerry DeLisle F2003 I/O support contributed by Jerry DeLisle
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 Libgfortran is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -131,45 +131,45 @@ max_value (int length, int signed_flag) ...@@ -131,45 +131,45 @@ max_value (int length, int signed_flag)
/* convert_real()-- Convert a character representation of a floating /* convert_real()-- Convert a character representation of a floating
point number to the machine number. Returns nonzero if there is a point number to the machine number. Returns nonzero if there is an
range problem during conversion. Note: many architectures invalid input. Note: many architectures (e.g. IA-64, HP-PA)
(e.g. IA-64, HP-PA) require that the storage pointed to by the dest require that the storage pointed to by the dest argument is
argument is properly aligned for the type in question. */ properly aligned for the type in question. */
int int
convert_real (st_parameter_dt *dtp, void *dest, const char *buffer, int length) convert_real (st_parameter_dt *dtp, void *dest, const char *buffer, int length)
{ {
errno = 0; char *endptr = NULL;
switch (length) switch (length)
{ {
case 4: case 4:
*((GFC_REAL_4*) dest) = *((GFC_REAL_4*) dest) =
#if defined(HAVE_STRTOF) #if defined(HAVE_STRTOF)
gfc_strtof (buffer, NULL); gfc_strtof (buffer, &endptr);
#else #else
(GFC_REAL_4) gfc_strtod (buffer, NULL); (GFC_REAL_4) gfc_strtod (buffer, &endptr);
#endif #endif
break; break;
case 8: case 8:
*((GFC_REAL_8*) dest) = gfc_strtod (buffer, NULL); *((GFC_REAL_8*) dest) = gfc_strtod (buffer, &endptr);
break; break;
#if defined(HAVE_GFC_REAL_10) && defined (HAVE_STRTOLD) #if defined(HAVE_GFC_REAL_10) && defined (HAVE_STRTOLD)
case 10: case 10:
*((GFC_REAL_10*) dest) = gfc_strtold (buffer, NULL); *((GFC_REAL_10*) dest) = gfc_strtold (buffer, &endptr);
break; break;
#endif #endif
#if defined(HAVE_GFC_REAL_16) #if defined(HAVE_GFC_REAL_16)
# if defined(GFC_REAL_16_IS_FLOAT128) # if defined(GFC_REAL_16_IS_FLOAT128)
case 16: case 16:
*((GFC_REAL_16*) dest) = __qmath_(strtoflt128) (buffer, NULL); *((GFC_REAL_16*) dest) = __qmath_(strtoflt128) (buffer, &endptr);
break; break;
# elif defined(HAVE_STRTOLD) # elif defined(HAVE_STRTOLD)
case 16: case 16:
*((GFC_REAL_16*) dest) = gfc_strtold (buffer, NULL); *((GFC_REAL_16*) dest) = gfc_strtold (buffer, &endptr);
break; break;
# endif # endif
#endif #endif
...@@ -178,10 +178,10 @@ convert_real (st_parameter_dt *dtp, void *dest, const char *buffer, int length) ...@@ -178,10 +178,10 @@ convert_real (st_parameter_dt *dtp, void *dest, const char *buffer, int length)
internal_error (&dtp->common, "Unsupported real kind during IO"); internal_error (&dtp->common, "Unsupported real kind during IO");
} }
if (errno == EINVAL) if (buffer == endptr)
{ {
generate_error (&dtp->common, LIBERROR_READ_VALUE, generate_error (&dtp->common, LIBERROR_READ_VALUE,
"Error during floating point read"); "Error during floating point read");
next_record (dtp, 1); next_record (dtp, 1);
return 1; return 1;
} }
...@@ -1114,6 +1114,14 @@ done: ...@@ -1114,6 +1114,14 @@ done:
/* Output a trailing '0' after decimal point if not yet found. */ /* Output a trailing '0' after decimal point if not yet found. */
if (seen_dp && !seen_dec_digit) if (seen_dp && !seen_dec_digit)
*(out++) = '0'; *(out++) = '0';
/* Handle input of style "E+NN" by inserting a 0 for the
significand. */
else if (!seen_int_digit && !seen_dec_digit)
{
notify_std (&dtp->common, GFC_STD_LEGACY,
"REAL input of style 'E+NN'");
*(out++) = '0';
}
/* Print out the exponent to finish the reformatted number. Maximum 4 /* Print out the exponent to finish the reformatted number. Maximum 4
digits for the exponent. */ digits for the exponent. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment