diff options
| author | Eli Zaretskii | 2011-04-27 21:15:29 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-04-27 21:15:29 +0300 |
| commit | 94dcfacf129aa99be3e375187d75a193ffe26bad (patch) | |
| tree | 69ae809354575f22d35c37d15a311242ea032ca1 /src | |
| parent | 211ec9072dc2635bf027ae6b3c58a3edf27e5969 (diff) | |
| download | emacs-94dcfacf129aa99be3e375187d75a193ffe26bad.tar.gz emacs-94dcfacf129aa99be3e375187d75a193ffe26bad.zip | |
Improve `doprnt' and its usage. (Bug#8545)
src/doprnt.c (doprnt): Make sure `format' is never accessed beyond
`format_end'. Remove support for %l as a conversion specifier.
Don't use xrealloc. Improve diagnostics when the %l size modifier
is used. Update the commentary.
src/eval.c (verror): Simplify calculation of size_t.
src/coding.c (Ffind_operation_coding_system): Fix diagnostic error
messages.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/coding.c | 5 | ||||
| -rw-r--r-- | src/doprnt.c | 53 | ||||
| -rw-r--r-- | src/eval.c | 3 |
4 files changed, 46 insertions, 28 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index e2ac23256a7..c08ef73ca1e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2011-04-27 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | Improve `doprnt' and its usage. (Bug#8545) | ||
| 4 | * doprnt.c (doprnt): Make sure `format' is never accessed beyond | ||
| 5 | `format_end'. Remove support for %l as a conversion specifier. | ||
| 6 | Don't use xrealloc. Improve diagnostics when the %l size modifier | ||
| 7 | is used. Update the commentary. | ||
| 8 | |||
| 9 | * eval.c (verror): Simplify calculation of size_t. | ||
| 10 | |||
| 11 | * coding.c (Ffind_operation_coding_system): Fix diagnostic error | ||
| 12 | messages. | ||
| 13 | |||
| 1 | 2011-04-27 Yoshiaki Kasahara <kasahara@nc.kyushu-u.ac.jp> (tiny change) | 14 | 2011-04-27 Yoshiaki Kasahara <kasahara@nc.kyushu-u.ac.jp> (tiny change) |
| 2 | 15 | ||
| 3 | * buffer.c (init_buffer) [USE_MMAP_FOR_BUFFERS]: Adjust to aliasing | 16 | * buffer.c (init_buffer) [USE_MMAP_FOR_BUFFERS]: Adjust to aliasing |
diff --git a/src/coding.c b/src/coding.c index c14a41036ac..c129c94203c 100644 --- a/src/coding.c +++ b/src/coding.c | |||
| @@ -9282,14 +9282,15 @@ usage: (find-operation-coding-system OPERATION ARGUMENTS...) */) | |||
| 9282 | || !NATNUMP (target_idx = Fget (operation, Qtarget_idx))) | 9282 | || !NATNUMP (target_idx = Fget (operation, Qtarget_idx))) |
| 9283 | error ("Invalid first argument"); | 9283 | error ("Invalid first argument"); |
| 9284 | if (nargs < 1 + XFASTINT (target_idx)) | 9284 | if (nargs < 1 + XFASTINT (target_idx)) |
| 9285 | error ("Too few arguments for operation: %s", | 9285 | error ("Too few arguments for operation `%s'", |
| 9286 | SDATA (SYMBOL_NAME (operation))); | 9286 | SDATA (SYMBOL_NAME (operation))); |
| 9287 | target = args[XFASTINT (target_idx) + 1]; | 9287 | target = args[XFASTINT (target_idx) + 1]; |
| 9288 | if (!(STRINGP (target) | 9288 | if (!(STRINGP (target) |
| 9289 | || (EQ (operation, Qinsert_file_contents) && CONSP (target) | 9289 | || (EQ (operation, Qinsert_file_contents) && CONSP (target) |
| 9290 | && STRINGP (XCAR (target)) && BUFFERP (XCDR (target))) | 9290 | && STRINGP (XCAR (target)) && BUFFERP (XCDR (target))) |
| 9291 | || (EQ (operation, Qopen_network_stream) && INTEGERP (target)))) | 9291 | || (EQ (operation, Qopen_network_stream) && INTEGERP (target)))) |
| 9292 | error ("Invalid %"pI"dth argument", XFASTINT (target_idx) + 1); | 9292 | error ("Invalid argument %"pI"d of operation `%s'", |
| 9293 | XFASTINT (target_idx) + 1, SDATA (SYMBOL_NAME (operation))); | ||
| 9293 | if (CONSP (target)) | 9294 | if (CONSP (target)) |
| 9294 | target = XCAR (target); | 9295 | target = XCAR (target); |
| 9295 | 9296 | ||
diff --git a/src/doprnt.c b/src/doprnt.c index 3ac1d9963a9..92e2d627432 100644 --- a/src/doprnt.c +++ b/src/doprnt.c | |||
| @@ -55,7 +55,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 55 | %s means print a string argument. | 55 | %s means print a string argument. |
| 56 | %S is silently treated as %s, for loose compatibility with `Fformat'. | 56 | %S is silently treated as %s, for loose compatibility with `Fformat'. |
| 57 | %d means print a `signed int' argument in decimal. | 57 | %d means print a `signed int' argument in decimal. |
| 58 | %l means print a `long int' argument in decimal. | ||
| 59 | %o means print an `unsigned int' argument in octal. | 58 | %o means print an `unsigned int' argument in octal. |
| 60 | %x means print an `unsigned int' argument in hex. | 59 | %x means print an `unsigned int' argument in hex. |
| 61 | %e means print a `double' argument in exponential notation. | 60 | %e means print a `double' argument in exponential notation. |
| @@ -65,22 +64,26 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 65 | %c means print a `signed int' argument as a single character. | 64 | %c means print a `signed int' argument as a single character. |
| 66 | %% means produce a literal % character. | 65 | %% means produce a literal % character. |
| 67 | 66 | ||
| 68 | A %-sequence may contain optional flag, width, and precision specifiers, as | 67 | A %-sequence may contain optional flag, width, and precision specifiers, and |
| 69 | follows: | 68 | a length modifier, as follows: |
| 70 | 69 | ||
| 71 | %<flags><width><precision>character | 70 | %<flags><width><precision><length>character |
| 72 | 71 | ||
| 73 | where flags is [+ -0l], width is [0-9]+, and precision is .[0-9]+ | 72 | where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length |
| 73 | modifier is l. | ||
| 74 | 74 | ||
| 75 | The + flag character inserts a + before any positive number, while a space | 75 | The + flag character inserts a + before any positive number, while a space |
| 76 | inserts a space before any positive number; these flags only affect %d, %l, | 76 | inserts a space before any positive number; these flags only affect %d, %o, |
| 77 | %o, %x, %e, %f, and %g sequences. The - and 0 flags affect the width | 77 | %x, %e, %f, and %g sequences. The - and 0 flags affect the width specifier, |
| 78 | specifier, as described below. | 78 | as described below. For signed numerical arguments only, the ` ' (space) |
| 79 | 79 | flag causes the result to be prefixed with a space character if it does not | |
| 80 | The l (lower-case letter ell) flag is a `long' data type modifier: it is | 80 | start with a sign (+ or -). |
| 81 | supported for %d, %o, and %x conversions of integral arguments, and means | 81 | |
| 82 | that the respective argument is to be treated as `long int' or `unsigned | 82 | The l (lower-case letter ell) length modifier is a `long' data type |
| 83 | long int'. The EMACS_INT data type should use this modifier. | 83 | modifier: it is supported for %d, %o, and %x conversions of integral |
| 84 | arguments, must immediately preced the conversion specifier, and means that | ||
| 85 | the respective argument is to be treated as `long int' or `unsigned long | ||
| 86 | int'. The EMACS_INT data type should use this modifier. | ||
| 84 | 87 | ||
| 85 | The width specifier supplies a lower limit for the length of the printed | 88 | The width specifier supplies a lower limit for the length of the printed |
| 86 | representation. The padding, if any, normally goes on the left, but it goes | 89 | representation. The padding, if any, normally goes on the left, but it goes |
| @@ -166,7 +169,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format, | |||
| 166 | bufsize--; | 169 | bufsize--; |
| 167 | 170 | ||
| 168 | /* Loop until end of format string or buffer full. */ | 171 | /* Loop until end of format string or buffer full. */ |
| 169 | while (fmt != format_end && bufsize > 0) | 172 | while (fmt < format_end && bufsize > 0) |
| 170 | { | 173 | { |
| 171 | if (*fmt == '%') /* Check for a '%' character */ | 174 | if (*fmt == '%') /* Check for a '%' character */ |
| 172 | { | 175 | { |
| @@ -178,7 +181,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format, | |||
| 178 | /* Copy this one %-spec into fmtcpy. */ | 181 | /* Copy this one %-spec into fmtcpy. */ |
| 179 | string = fmtcpy; | 182 | string = fmtcpy; |
| 180 | *string++ = '%'; | 183 | *string++ = '%'; |
| 181 | while (1) | 184 | while (fmt < format_end) |
| 182 | { | 185 | { |
| 183 | *string++ = *fmt; | 186 | *string++ = *fmt; |
| 184 | if ('0' <= *fmt && *fmt <= '9') | 187 | if ('0' <= *fmt && *fmt <= '9') |
| @@ -188,7 +191,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format, | |||
| 188 | %1.1000f and %1000.1f both might need 1000+ bytes. | 191 | %1.1000f and %1000.1f both might need 1000+ bytes. |
| 189 | Parse the width or precision, checking for overflow. */ | 192 | Parse the width or precision, checking for overflow. */ |
| 190 | size_t n = *fmt - '0'; | 193 | size_t n = *fmt - '0'; |
| 191 | while ('0' <= fmt[1] && fmt[1] <= '9') | 194 | while (fmt < format_end |
| 195 | && '0' <= fmt[1] && fmt[1] <= '9') | ||
| 192 | { | 196 | { |
| 193 | if (n >= SIZE_MAX / 10 | 197 | if (n >= SIZE_MAX / 10 |
| 194 | || n * 10 > SIZE_MAX - (fmt[1] - '0')) | 198 | || n * 10 > SIZE_MAX - (fmt[1] - '0')) |
| @@ -205,14 +209,15 @@ doprnt (char *buffer, register size_t bufsize, const char *format, | |||
| 205 | else if (*fmt == 'l') | 209 | else if (*fmt == 'l') |
| 206 | { | 210 | { |
| 207 | long_flag = 1; | 211 | long_flag = 1; |
| 208 | if (!strchr ("dox", fmt[1])) | 212 | fmt++; |
| 209 | /* %l as conversion specifier, not as modifier. */ | 213 | break; |
| 210 | break; | ||
| 211 | } | 214 | } |
| 212 | else | 215 | else |
| 213 | break; | 216 | break; |
| 214 | fmt++; | 217 | fmt++; |
| 215 | } | 218 | } |
| 219 | if (fmt > format_end) | ||
| 220 | fmt = format_end; | ||
| 216 | *string = 0; | 221 | *string = 0; |
| 217 | 222 | ||
| 218 | /* Make the size bound large enough to handle floating point formats | 223 | /* Make the size bound large enough to handle floating point formats |
| @@ -225,9 +230,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format, | |||
| 225 | if (size_bound > size_allocated) | 230 | if (size_bound > size_allocated) |
| 226 | { | 231 | { |
| 227 | if (big_buffer) | 232 | if (big_buffer) |
| 228 | big_buffer = (char *) xrealloc (big_buffer, size_bound); | 233 | xfree (big_buffer); |
| 229 | else | 234 | big_buffer = (char *) xmalloc (size_bound); |
| 230 | big_buffer = (char *) xmalloc (size_bound); | ||
| 231 | sprintf_buffer = big_buffer; | 235 | sprintf_buffer = big_buffer; |
| 232 | size_allocated = size_bound; | 236 | size_allocated = size_bound; |
| 233 | } | 237 | } |
| @@ -235,7 +239,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format, | |||
| 235 | switch (*fmt++) | 239 | switch (*fmt++) |
| 236 | { | 240 | { |
| 237 | default: | 241 | default: |
| 238 | error ("Invalid format operation %%%c", fmt[-1]); | 242 | error ("Invalid format operation %%%s%c", |
| 243 | long_flag ? "l" : "", fmt[-1]); | ||
| 239 | 244 | ||
| 240 | /* case 'b': */ | 245 | /* case 'b': */ |
| 241 | case 'l': | 246 | case 'l': |
| @@ -373,7 +378,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format, | |||
| 373 | char *save_bufptr = bufptr; | 378 | char *save_bufptr = bufptr; |
| 374 | 379 | ||
| 375 | do { *bufptr++ = *fmt++; } | 380 | do { *bufptr++ = *fmt++; } |
| 376 | while (--bufsize > 0 && !CHAR_HEAD_P (*fmt)); | 381 | while (fmt < format_end && --bufsize > 0 && !CHAR_HEAD_P (*fmt)); |
| 377 | if (!CHAR_HEAD_P (*fmt)) | 382 | if (!CHAR_HEAD_P (*fmt)) |
| 378 | { | 383 | { |
| 379 | bufptr = save_bufptr; | 384 | bufptr = save_bufptr; |
diff --git a/src/eval.c b/src/eval.c index 8716ad78468..bcbbf740153 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1994,8 +1994,7 @@ verror (const char *m, va_list ap) | |||
| 1994 | { | 1994 | { |
| 1995 | char buf[4000]; | 1995 | char buf[4000]; |
| 1996 | size_t size = sizeof buf; | 1996 | size_t size = sizeof buf; |
| 1997 | size_t size_max = | 1997 | size_t size_max = min (MOST_POSITIVE_FIXNUM, SIZE_MAX); |
| 1998 | min (MOST_POSITIVE_FIXNUM, min (INT_MAX, SIZE_MAX - 1)) + 1; | ||
| 1999 | size_t mlen = strlen (m); | 1998 | size_t mlen = strlen (m); |
| 2000 | char *buffer = buf; | 1999 | char *buffer = buf; |
| 2001 | size_t used; | 2000 | size_t used; |