aboutsummaryrefslogtreecommitdiffstats
path: root/src/doprnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/doprnt.c')
-rw-r--r--src/doprnt.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/src/doprnt.c b/src/doprnt.c
index 195598c07ea..79f9f36e461 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -102,13 +102,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
102#include <stdio.h> 102#include <stdio.h>
103#include <ctype.h> 103#include <ctype.h>
104#include <setjmp.h> 104#include <setjmp.h>
105
106#ifdef STDC_HEADERS
107#include <float.h> 105#include <float.h>
108#endif
109
110#include <unistd.h> 106#include <unistd.h>
111
112#include <limits.h> 107#include <limits.h>
113 108
114#include "lisp.h" 109#include "lisp.h"
@@ -134,8 +129,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
134 String arguments are passed as C strings. 129 String arguments are passed as C strings.
135 Integers are passed as C integers. */ 130 Integers are passed as C integers. */
136 131
137size_t 132ptrdiff_t
138doprnt (char *buffer, register size_t bufsize, const char *format, 133doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
139 const char *format_end, va_list ap) 134 const char *format_end, va_list ap)
140{ 135{
141 const char *fmt = format; /* Pointer into format string */ 136 const char *fmt = format; /* Pointer into format string */
@@ -145,7 +140,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
145 char tembuf[DBL_MAX_10_EXP + 100]; 140 char tembuf[DBL_MAX_10_EXP + 100];
146 141
147 /* Size of sprintf_buffer. */ 142 /* Size of sprintf_buffer. */
148 size_t size_allocated = sizeof (tembuf); 143 ptrdiff_t size_allocated = sizeof (tembuf);
149 144
150 /* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */ 145 /* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */
151 char *sprintf_buffer = tembuf; 146 char *sprintf_buffer = tembuf;
@@ -164,7 +159,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
164 if (format_end == 0) 159 if (format_end == 0)
165 format_end = format + strlen (format); 160 format_end = format + strlen (format);
166 161
167 if ((format_end - format + 1) < sizeof (fixed_buffer)) 162 if (format_end - format < sizeof (fixed_buffer) - 1)
168 fmtcpy = fixed_buffer; 163 fmtcpy = fixed_buffer;
169 else 164 else
170 SAFE_ALLOCA (fmtcpy, char *, format_end - format + 1); 165 SAFE_ALLOCA (fmtcpy, char *, format_end - format + 1);
@@ -176,7 +171,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
176 { 171 {
177 if (*fmt == '%') /* Check for a '%' character */ 172 if (*fmt == '%') /* Check for a '%' character */
178 { 173 {
179 size_t size_bound = 0; 174 ptrdiff_t size_bound = 0;
180 EMACS_INT width; /* Columns occupied by STRING on display. */ 175 EMACS_INT width; /* Columns occupied by STRING on display. */
181 int long_flag = 0; 176 int long_flag = 0;
182 int pIlen = sizeof pI - 1; 177 int pIlen = sizeof pI - 1;
@@ -194,16 +189,16 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
194 This might be a field width or a precision; e.g. 189 This might be a field width or a precision; e.g.
195 %1.1000f and %1000.1f both might need 1000+ bytes. 190 %1.1000f and %1000.1f both might need 1000+ bytes.
196 Parse the width or precision, checking for overflow. */ 191 Parse the width or precision, checking for overflow. */
197 size_t n = *fmt - '0'; 192 ptrdiff_t n = *fmt - '0';
198 while (fmt + 1 < format_end 193 while (fmt + 1 < format_end
199 && '0' <= fmt[1] && fmt[1] <= '9') 194 && '0' <= fmt[1] && fmt[1] <= '9')
200 { 195 {
201 /* Avoid size_t overflow. Avoid int overflow too, as 196 /* Avoid ptrdiff_t, size_t, and int overflow, as
202 many sprintfs mishandle widths greater than INT_MAX. 197 many sprintfs mishandle widths greater than INT_MAX.
203 This test is simple but slightly conservative: e.g., 198 This test is simple but slightly conservative: e.g.,
204 (INT_MAX - INT_MAX % 10) is reported as an overflow 199 (INT_MAX - INT_MAX % 10) is reported as an overflow
205 even when it's not. */ 200 even when it's not. */
206 if (n >= min (INT_MAX, SIZE_MAX) / 10) 201 if (n >= min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX)) / 10)
207 error ("Format width or precision too large"); 202 error ("Format width or precision too large");
208 n = n * 10 + fmt[1] - '0'; 203 n = n * 10 + fmt[1] - '0';
209 *string++ = *++fmt; 204 *string++ = *++fmt;
@@ -235,7 +230,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
235 230
236 /* Make the size bound large enough to handle floating point formats 231 /* Make the size bound large enough to handle floating point formats
237 with large numbers. */ 232 with large numbers. */
238 if (size_bound > SIZE_MAX - DBL_MAX_10_EXP - 50) 233 if (size_bound > min (PTRDIFF_MAX, SIZE_MAX) - DBL_MAX_10_EXP - 50)
239 error ("Format width or precision too large"); 234 error ("Format width or precision too large");
240 size_bound += DBL_MAX_10_EXP + 50; 235 size_bound += DBL_MAX_10_EXP + 50;
241 236