aboutsummaryrefslogtreecommitdiffstats
path: root/src/character.c
diff options
context:
space:
mode:
authorPaul Eggert2011-05-15 22:08:59 -0700
committerPaul Eggert2011-05-15 22:08:59 -0700
commit2b4560a850d2ea0767d0a3c4db19e4468f61b4eb (patch)
treeca99d199897a9289dfff5a1f492341402d79ae69 /src/character.c
parentcb93f9bef01e95b17b3d7b8786c103505355d98c (diff)
downloademacs-2b4560a850d2ea0767d0a3c4db19e4468f61b4eb.tar.gz
emacs-2b4560a850d2ea0767d0a3c4db19e4468f61b4eb.zip
* 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/>. */
35 35
36#include <sys/types.h> 36#include <sys/types.h>
37#include <setjmp.h> 37#include <setjmp.h>
38#include <intprops.h>
38#include "lisp.h" 39#include "lisp.h"
39#include "character.h" 40#include "character.h"
40#include "buffer.h" 41#include "buffer.h"
@@ -404,7 +405,7 @@ strwidth (const char *str, EMACS_INT len)
404 in *NCHARS and *NBYTES respectively. */ 405 in *NCHARS and *NBYTES respectively. */
405 406
406EMACS_INT 407EMACS_INT
407lisp_string_width (Lisp_Object string, int precision, 408lisp_string_width (Lisp_Object string, EMACS_INT precision,
408 EMACS_INT *nchars, EMACS_INT *nbytes) 409 EMACS_INT *nchars, EMACS_INT *nbytes)
409{ 410{
410 EMACS_INT len = SCHARS (string); 411 EMACS_INT len = SCHARS (string);
@@ -419,7 +420,7 @@ lisp_string_width (Lisp_Object string, int precision,
419 420
420 while (i < len) 421 while (i < len)
421 { 422 {
422 int chars, bytes, thiswidth; 423 EMACS_INT chars, bytes, thiswidth;
423 Lisp_Object val; 424 Lisp_Object val;
424 int cmp_id; 425 int cmp_id;
425 EMACS_INT ignore, end; 426 EMACS_INT ignore, end;
@@ -437,7 +438,11 @@ lisp_string_width (Lisp_Object string, int precision,
437 int c; 438 int c;
438 439
439 if (multibyte) 440 if (multibyte)
440 c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes); 441 {
442 int cbytes;
443 c = STRING_CHAR_AND_LENGTH (str + i_byte, cbytes);
444 bytes = cbytes;
445 }
441 else 446 else
442 c = str[i_byte], bytes = 1; 447 c = str[i_byte], bytes = 1;
443 chars = 1; 448 chars = 1;
@@ -455,8 +460,14 @@ lisp_string_width (Lisp_Object string, int precision,
455 } 460 }
456 } 461 }
457 462
458 if (precision > 0 463 if (precision <= 0)
459 && (width + thiswidth > precision)) 464 {
465#ifdef emacs
466 if (INT_ADD_OVERFLOW (width, thiswidth))
467 string_overflow ();
468#endif
469 }
470 else if (precision - width < thiswidth)
460 { 471 {
461 *nchars = i; 472 *nchars = i;
462 *nbytes = i_byte; 473 *nbytes = i_byte;