aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert1997-01-27 20:12:52 +0000
committerPaul Eggert1997-01-27 20:12:52 +0000
commitbe65c2f46a9170da6b9a508df1f31234db21fce0 (patch)
tree38ab70b6cf190f9477e6fb1012e0b8f26ef6fd80 /src
parentdd713b759cbb6a28e3b4b9bdc0d3a92222ed8370 (diff)
downloademacs-be65c2f46a9170da6b9a508df1f31234db21fce0.tar.gz
emacs-be65c2f46a9170da6b9a508df1f31234db21fce0.zip
Include <float.h> if STDC_HEADERS.
(DBL_MAX_10_EXP): Define if not defined; default is IEEE double. (doprnt1): Allocate enough buffer space to handle very large floating point numbers, or very large field widths or precisions. Detect overflow in field widths or precisions.
Diffstat (limited to 'src')
-rw-r--r--src/doprnt.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/src/doprnt.c b/src/doprnt.c
index d9b6566b1bc..aa0b2c20055 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -26,6 +26,14 @@ Boston, MA 02111-1307, USA. */
26#include <ctype.h> 26#include <ctype.h>
27#include "lisp.h" 27#include "lisp.h"
28 28
29#if STDC_HEADERS
30#include <float.h>
31#endif
32
33#ifndef DBL_MAX_10_EXP
34#define DBL_MAX_10_EXP 308 /* IEEE double */
35#endif
36
29extern long *xmalloc (), *xrealloc (); 37extern long *xmalloc (), *xrealloc ();
30 38
31static int doprnt1 (); 39static int doprnt1 ();
@@ -80,10 +88,10 @@ doprnt1 (lispstrings, buffer, bufsize, format, format_end, nargs, args)
80 register char *bufptr = buffer; /* Pointer into output buffer.. */ 88 register char *bufptr = buffer; /* Pointer into output buffer.. */
81 89
82 /* Use this for sprintf unless we need something really big. */ 90 /* Use this for sprintf unless we need something really big. */
83 char tembuf[100]; 91 char tembuf[DBL_MAX_10_EXP + 100];
84 92
85 /* Size of sprintf_buffer. */ 93 /* Size of sprintf_buffer. */
86 int size_allocated = 100; 94 int size_allocated = sizeof (tembuf);
87 95
88 /* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */ 96 /* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */
89 char *sprintf_buffer = tembuf; 97 char *sprintf_buffer = tembuf;
@@ -114,7 +122,7 @@ doprnt1 (lispstrings, buffer, bufsize, format, format_end, nargs, args)
114 { 122 {
115 if (*fmt == '%') /* Check for a '%' character */ 123 if (*fmt == '%') /* Check for a '%' character */
116 { 124 {
117 int size_bound; 125 int size_bound = 0;
118 126
119 fmt++; 127 fmt++;
120 /* Copy this one %-spec into fmtcpy. */ 128 /* Copy this one %-spec into fmtcpy. */
@@ -123,22 +131,38 @@ doprnt1 (lispstrings, buffer, bufsize, format, format_end, nargs, args)
123 while (1) 131 while (1)
124 { 132 {
125 *string++ = *fmt; 133 *string++ = *fmt;
126 if (! (*fmt >= '0' && *fmt <= '9') 134 if ('0' <= *fmt && *fmt <= '9')
127 && *fmt != '-' && *fmt != ' '&& *fmt != '.') 135 {
136 /* Get an idea of how much space we might need.
137 This might be a field width or a precision; e.g.
138 %1.1000f and %1000.1f both might need 1000+ bytes.
139 Parse the width or precision, checking for overflow. */
140 int n = *fmt - '0';
141 while ('0' <= fmt[1] && fmt[1] <= '9')
142 {
143 if (n * 10 / 10 != n
144 || (n = n * 10 + (fmt[1] - '0')) < 0)
145 error ("Format width or precision too large");
146 *string++ = *++fmt;
147 }
148
149 if (size_bound < n)
150 size_bound = n;
151 }
152 else if (*fmt == '-' || *fmt == ' ' || *fmt == '.')
153 ;
154 else
128 break; 155 break;
129 fmt++; 156 fmt++;
130 } 157 }
131 *string = 0; 158 *string = 0;
132 /* Get an idea of how much space we might need. */
133 size_bound = atoi (&fmtcpy[1]);
134 159
135 /* Avoid pitfall of negative "size" parameter ("%-200d"). */ 160 /* Make the size bound large enough to handle floating point formats
136 if (size_bound < 0) 161 with large numbers. */
137 size_bound = -size_bound; 162 size_bound += DBL_MAX_10_EXP + 50;
138 size_bound += 50;
139 163
140 if (size_bound > (((unsigned) 1) << (BITS_PER_INT - 1))) 164 if (size_bound < 0)
141 error ("Format padding too large"); 165 error ("Format width or precision too large");
142 166
143 /* Make sure we have that much. */ 167 /* Make sure we have that much. */
144 if (size_bound > size_allocated) 168 if (size_bound > size_allocated)