diff options
| author | Eli Zaretskii | 2011-04-29 14:01:11 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-04-29 14:01:11 +0300 |
| commit | afda1437615ad86d8076e60b999d89097e9c4e8f (patch) | |
| tree | 6b00923b6ac90e05e529da5f80f0cc9d2c81db08 | |
| parent | 6e087a44c58220e2c72b55c52bc01b2f8ded2c82 (diff) | |
| download | emacs-afda1437615ad86d8076e60b999d89097e9c4e8f.tar.gz emacs-afda1437615ad86d8076e60b999d89097e9c4e8f.zip | |
Fix doprnt when buffer is too small for multibyte sequences.
src/doprnt.c (doprnt): Fix the case where a multibyte sequence
produced by %s or %c overflows available buffer space. (Bug#8545)
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/doprnt.c | 18 | ||||
| -rw-r--r-- | src/eval.c | 2 |
3 files changed, 21 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 832c8abfdcc..bb660036c17 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2011-04-29 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * doprnt.c (doprnt): Fix the case where a multibyte sequence | ||
| 4 | produced by %s or %c overflows available buffer space. (Bug#8545) | ||
| 5 | |||
| 1 | 2011-04-28 Paul Eggert <eggert@cs.ucla.edu> | 6 | 2011-04-28 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 7 | ||
| 3 | * doprnt.c (doprnt): Omit useless test; int overflow check (Bug#8545). | 8 | * doprnt.c (doprnt): Omit useless test; int overflow check (Bug#8545). |
diff --git a/src/doprnt.c b/src/doprnt.c index e9a68f9d219..2508ddd831a 100644 --- a/src/doprnt.c +++ b/src/doprnt.c | |||
| @@ -367,9 +367,21 @@ doprnt (char *buffer, register size_t bufsize, const char *format, | |||
| 367 | /* Truncate the string at character boundary. */ | 367 | /* Truncate the string at character boundary. */ |
| 368 | tem = bufsize; | 368 | tem = bufsize; |
| 369 | while (!CHAR_HEAD_P (string[tem - 1])) tem--; | 369 | while (!CHAR_HEAD_P (string[tem - 1])) tem--; |
| 370 | memcpy (bufptr, string, tem); | 370 | /* If the multibyte sequence of this character is |
| 371 | /* We must calculate WIDTH again. */ | 371 | too long for the space we have left in the |
| 372 | width = strwidth (bufptr, tem); | 372 | buffer, truncate before it. */ |
| 373 | if (tem > 0 | ||
| 374 | && BYTES_BY_CHAR_HEAD (string[tem - 1]) > bufsize) | ||
| 375 | tem--; | ||
| 376 | if (tem > 0) | ||
| 377 | memcpy (bufptr, string, tem); | ||
| 378 | bufptr[tem] = 0; | ||
| 379 | /* Trigger exit from the loop, but make sure we | ||
| 380 | return to the caller a value which will indicate | ||
| 381 | that the buffer was too small. */ | ||
| 382 | bufptr += bufsize; | ||
| 383 | bufsize = 0; | ||
| 384 | continue; | ||
| 373 | } | 385 | } |
| 374 | else | 386 | else |
| 375 | memcpy (bufptr, string, tem); | 387 | memcpy (bufptr, string, tem); |
diff --git a/src/eval.c b/src/eval.c index bcbbf740153..ea090644c07 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1994,7 +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 = min (MOST_POSITIVE_FIXNUM, SIZE_MAX); | 1997 | size_t size_max = min (MOST_POSITIVE_FIXNUM, SIZE_MAX); |
| 1998 | size_t mlen = strlen (m); | 1998 | size_t mlen = strlen (m); |
| 1999 | char *buffer = buf; | 1999 | char *buffer = buf; |
| 2000 | size_t used; | 2000 | size_t used; |