diff options
| author | Paul Eggert | 2011-04-28 15:06:00 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-04-28 15:06:00 -0700 |
| commit | a8346e4904ebdd046bda23b3e16983279fcb2438 (patch) | |
| tree | ce6e75da6328a4c51cf603643051d55baa5a3d77 /src | |
| parent | aff458c34222850730c60104fe94588ba845ab99 (diff) | |
| parent | f40b429dbf87a57345849472224ac222e805e9e3 (diff) | |
| download | emacs-a8346e4904ebdd046bda23b3e16983279fcb2438.tar.gz emacs-a8346e4904ebdd046bda23b3e16983279fcb2438.zip | |
Merge: doprnt: Omit useless test; int overflow check (Bug#8545).
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/doprnt.c | 24 |
2 files changed, 22 insertions, 7 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 555fb9589f5..832c8abfdcc 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2011-04-28 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * doprnt.c (doprnt): Omit useless test; int overflow check (Bug#8545). | ||
| 4 | (SIZE_MAX): Move defn after all includes, as they might #define it. | ||
| 5 | |||
| 1 | 2011-04-28 Juanma Barranquero <lekktu@gmail.com> | 6 | 2011-04-28 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 7 | ||
| 3 | * w32.c (init_environment): Warn about defaulting HOME to C:\. | 8 | * w32.c (init_environment): Warn about defaulting HOME to C:\. |
diff --git a/src/doprnt.c b/src/doprnt.c index 63dba9f5850..e9a68f9d219 100644 --- a/src/doprnt.c +++ b/src/doprnt.c | |||
| @@ -70,7 +70,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 70 | %<flags><width><precision><length>character | 70 | %<flags><width><precision><length>character |
| 71 | 71 | ||
| 72 | where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length | 72 | where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length |
| 73 | modifier is empty or l or ll. | 73 | is empty or l or ll. Also, %% in a format stands for a single % in the |
| 74 | output. A % that does not introduce a valid %-sequence causes | ||
| 75 | undefined behavior. | ||
| 74 | 76 | ||
| 75 | The + flag character inserts a + before any positive number, while a space | 77 | 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, %o, | 78 | inserts a space before any positive number; these flags only affect %d, %o, |
| @@ -111,9 +113,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 111 | #include <unistd.h> | 113 | #include <unistd.h> |
| 112 | 114 | ||
| 113 | #include <limits.h> | 115 | #include <limits.h> |
| 114 | #ifndef SIZE_MAX | ||
| 115 | # define SIZE_MAX ((size_t) -1) | ||
| 116 | #endif | ||
| 117 | 116 | ||
| 118 | #include "lisp.h" | 117 | #include "lisp.h" |
| 119 | 118 | ||
| @@ -122,14 +121,21 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 122 | another macro. */ | 121 | another macro. */ |
| 123 | #include "character.h" | 122 | #include "character.h" |
| 124 | 123 | ||
| 124 | #ifndef SIZE_MAX | ||
| 125 | # define SIZE_MAX ((size_t) -1) | ||
| 126 | #endif | ||
| 127 | |||
| 125 | #ifndef DBL_MAX_10_EXP | 128 | #ifndef DBL_MAX_10_EXP |
| 126 | #define DBL_MAX_10_EXP 308 /* IEEE double */ | 129 | #define DBL_MAX_10_EXP 308 /* IEEE double */ |
| 127 | #endif | 130 | #endif |
| 128 | 131 | ||
| 129 | /* Generate output from a format-spec FORMAT, | 132 | /* Generate output from a format-spec FORMAT, |
| 130 | terminated at position FORMAT_END. | 133 | terminated at position FORMAT_END. |
| 134 | (*FORMAT_END is not part of the format, but must exist and be readable.) | ||
| 131 | Output goes in BUFFER, which has room for BUFSIZE chars. | 135 | Output goes in BUFFER, which has room for BUFSIZE chars. |
| 132 | If the output does not fit, truncate it to fit. | 136 | BUFSIZE must be positive. If the output does not fit, truncate it |
| 137 | to fit and return BUFSIZE - 1; if this truncates a multibyte | ||
| 138 | sequence, store '\0' into the sequence's first byte. | ||
| 133 | Returns the number of bytes stored into BUFFER, excluding | 139 | Returns the number of bytes stored into BUFFER, excluding |
| 134 | the terminating null byte. Output is always null-terminated. | 140 | the terminating null byte. Output is always null-terminated. |
| 135 | String arguments are passed as C strings. | 141 | String arguments are passed as C strings. |
| @@ -198,8 +204,12 @@ doprnt (char *buffer, register size_t bufsize, const char *format, | |||
| 198 | while (fmt < format_end | 204 | while (fmt < format_end |
| 199 | && '0' <= fmt[1] && fmt[1] <= '9') | 205 | && '0' <= fmt[1] && fmt[1] <= '9') |
| 200 | { | 206 | { |
| 201 | if (n >= SIZE_MAX / 10 | 207 | /* Avoid size_t overflow. Avoid int overflow too, as |
| 202 | || n * 10 > SIZE_MAX - (fmt[1] - '0')) | 208 | many sprintfs mishandle widths greater than INT_MAX. |
| 209 | This test is simple but slightly conservative: e.g., | ||
| 210 | (INT_MAX - INT_MAX % 10) is reported as an overflow | ||
| 211 | even when it's not. */ | ||
| 212 | if (n >= min (INT_MAX, SIZE_MAX) / 10) | ||
| 203 | error ("Format width or precision too large"); | 213 | error ("Format width or precision too large"); |
| 204 | n = n * 10 + fmt[1] - '0'; | 214 | n = n * 10 + fmt[1] - '0'; |
| 205 | *string++ = *++fmt; | 215 | *string++ = *++fmt; |