This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran 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, fortran] Fix PR 32977


:ADDPATCH fortran:

Hello world,

looks like vsnprintf wasn't available on every platform after all.
This patch fixes that by using a buffer that should be large enough,
and by issuing an error message in case of a buffer overflow.

Because the buffer is static, chances are pretty good that an overrun
won't clobber the other automatic variables in that routine.

Regression-tested on i686-pc-linux-gnu twice:

- with the #ifdef HAVE_VSNPRINTF replaced by #if 0 to check that
  codepath

- 'as is', to check the normal codepath

without any regressions.

OK for trunk?

	Thomas

2007-07-29  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR libfortran/32977
	* io/unix.c:  If there is no vsnprintf, use vsprintf and issue
	a fatal error when a buffer overrun occurs.


Index: io/unix.c
===================================================================
--- io/unix.c	(revision 127138)
+++ io/unix.c	(working copy)
@@ -1386,7 +1386,8 @@ error_stream (void)
    overruns, we limit the length of the buffer to ST_VPRINTF_SIZE.  2k
    is big enough to completely fill a 80x25 terminal, so it shuld be
    OK.  We use a direct write() because it is simpler and least likely
-   to be clobbered by memory corruption.  */
+   to be clobbered by memory corruption.  Writing an error message
+   longer than that is an error.  */
 
 #define ST_VPRINTF_SIZE 2048
 
@@ -1401,8 +1402,22 @@ st_vprintf (const char *format, va_list 
 #ifdef HAVE_VSNPRINTF
   written = vsnprintf(buffer, ST_VPRINTF_SIZE, format, ap);
 #else
-  written = __builtin_vsnprintf(buffer, ST_VPRINTF_SIZE, format, ap);
+  written = vsprintf(buffer, format, ap);
+
+  if (written >= ST_VPRINTF_SIZE-1)
+    {
+      /* The error message was longer than our buffer.  Ouch.  Because
+	 we may have messed up things badly, report the error and
+	 quit.  */
+#define ERROR_MESSAGE "Internal error: buffer overrun in st_vprintf()\n"
+      write (fd, buffer, ST_VPRINTF_SIZE-1);
+      write (fd, ERROR_MESSAGE, strlen(ERROR_MESSAGE));
+      sys_exit(2);
+#undef ERROR_MESSAGE
+
+    }
 #endif
+
   written = write (fd, buffer, written);
   return written;
 }

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