From afda1437615ad86d8076e60b999d89097e9c4e8f Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 29 Apr 2011 14:01:11 +0300 Subject: [PATCH] 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) --- src/ChangeLog | 5 +++++ src/doprnt.c | 18 +++++++++++++++--- 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 @@ +2011-04-29 Eli Zaretskii + + * 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 * 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; -- 2.39.2