summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2011-04-29 14:01:11 +0300
committerEli Zaretskii <eliz@gnu.org>2011-04-29 14:01:11 +0300
commitafda1437615ad86d8076e60b999d89097e9c4e8f (patch)
tree6b00923b6ac90e05e529da5f80f0cc9d2c81db08 /src
parent6e087a44c58220e2c72b55c52bc01b2f8ded2c82 (diff)
downloademacs-afda1437615ad86d8076e60b999d89097e9c4e8f.tar.gz
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)
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog5
-rw-r--r--src/doprnt.c18
-rw-r--r--src/eval.c2
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 @@
+2011-04-29 Eli Zaretskii <eliz@gnu.org>
+
+ * doprnt.c (doprnt): Fix the case where a multibyte sequence
+ produced by %s or %c overflows available buffer space. (Bug#8545)
+
2011-04-28 Paul Eggert <eggert@cs.ucla.edu>
* 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,
/* Truncate the string at character boundary. */
tem = bufsize;
while (!CHAR_HEAD_P (string[tem - 1])) tem--;
- memcpy (bufptr, string, tem);
- /* We must calculate WIDTH again. */
- width = strwidth (bufptr, tem);
+ /* If the multibyte sequence of this character is
+ too long for the space we have left in the
+ buffer, truncate before it. */
+ if (tem > 0
+ && BYTES_BY_CHAR_HEAD (string[tem - 1]) > bufsize)
+ tem--;
+ if (tem > 0)
+ memcpy (bufptr, string, tem);
+ bufptr[tem] = 0;
+ /* Trigger exit from the loop, but make sure we
+ return to the caller a value which will indicate
+ that the buffer was too small. */
+ bufptr += bufsize;
+ bufsize = 0;
+ continue;
}
else
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)
{
char buf[4000];
size_t size = sizeof buf;
- size_t size_max = min (MOST_POSITIVE_FIXNUM, SIZE_MAX);
+ size_t size_max = min (MOST_POSITIVE_FIXNUM, SIZE_MAX);
size_t mlen = strlen (m);
char *buffer = buf;
size_t used;