summaryrefslogtreecommitdiff
path: root/src/character.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2011-05-15 22:08:59 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2011-05-15 22:08:59 -0700
commit2b4560a850d2ea0767d0a3c4db19e4468f61b4eb (patch)
treeca99d199897a9289dfff5a1f492341402d79ae69 /src/character.c
parentcb93f9bef01e95b17b3d7b8786c103505355d98c (diff)
downloademacs-2b4560a850d2ea0767d0a3c4db19e4468f61b4eb.tar.gz
* character.c (lisp_string_width): Check for string overflow.
Use EMACS_INT, not int, for string indexes and lengths; in particular, 2nd arg is now EMACS_INT, not int. Do not crash if the resulting string length overflows an EMACS_INT; instead, report a string overflow if no precision given. When checking for precision exhaustion, use a check that cannot possibly have integer overflow. (Bug#8675) * character.h (lisp_string_width): Adjust to new signature.
Diffstat (limited to 'src/character.c')
-rw-r--r--src/character.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/character.c b/src/character.c
index 6a8b86d5d87..a03c081a716 100644
--- a/src/character.c
+++ b/src/character.c
@@ -35,6 +35,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <sys/types.h>
#include <setjmp.h>
+#include <intprops.h>
#include "lisp.h"
#include "character.h"
#include "buffer.h"
@@ -404,7 +405,7 @@ strwidth (const char *str, EMACS_INT len)
in *NCHARS and *NBYTES respectively. */
EMACS_INT
-lisp_string_width (Lisp_Object string, int precision,
+lisp_string_width (Lisp_Object string, EMACS_INT precision,
EMACS_INT *nchars, EMACS_INT *nbytes)
{
EMACS_INT len = SCHARS (string);
@@ -419,7 +420,7 @@ lisp_string_width (Lisp_Object string, int precision,
while (i < len)
{
- int chars, bytes, thiswidth;
+ EMACS_INT chars, bytes, thiswidth;
Lisp_Object val;
int cmp_id;
EMACS_INT ignore, end;
@@ -437,7 +438,11 @@ lisp_string_width (Lisp_Object string, int precision,
int c;
if (multibyte)
- c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes);
+ {
+ int cbytes;
+ c = STRING_CHAR_AND_LENGTH (str + i_byte, cbytes);
+ bytes = cbytes;
+ }
else
c = str[i_byte], bytes = 1;
chars = 1;
@@ -455,8 +460,14 @@ lisp_string_width (Lisp_Object string, int precision,
}
}
- if (precision > 0
- && (width + thiswidth > precision))
+ if (precision <= 0)
+ {
+#ifdef emacs
+ if (INT_ADD_OVERFLOW (width, thiswidth))
+ string_overflow ();
+#endif
+ }
+ else if (precision - width < thiswidth)
{
*nchars = i;
*nbytes = i_byte;