aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/character.c21
-rw-r--r--src/character.h2
3 files changed, 26 insertions, 6 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 178ebf78932..944a5dfbecb 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,14 @@
12011-05-16 Paul Eggert <eggert@cs.ucla.edu> 12011-05-16 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 * character.c (lisp_string_width): Check for string overflow.
4 Use EMACS_INT, not int, for string indexes and lengths; in
5 particular, 2nd arg is now EMACS_INT, not int. Do not crash if
6 the resulting string length overflows an EMACS_INT; instead,
7 report a string overflow if no precision given. When checking for
8 precision exhaustion, use a check that cannot possibly have
9 integer overflow. (Bug#8675)
10 * character.h (lisp_string_width): Adjust to new signature.
11
3 * alloc.c (string_overflow): New function. 12 * alloc.c (string_overflow): New function.
4 (Fmake_string): Use it. This doesn't change behavior, but saves 13 (Fmake_string): Use it. This doesn't change behavior, but saves
5 a few bytes and will simplify future changes. 14 a few bytes and will simplify future changes.
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;
diff --git a/src/character.h b/src/character.h
index 864882db7f6..5877d145d9e 100644
--- a/src/character.h
+++ b/src/character.h
@@ -612,7 +612,7 @@ extern EMACS_INT str_to_unibyte (const unsigned char *, unsigned char *,
612extern EMACS_INT strwidth (const char *, EMACS_INT); 612extern EMACS_INT strwidth (const char *, EMACS_INT);
613extern EMACS_INT c_string_width (const unsigned char *, EMACS_INT, int, 613extern EMACS_INT c_string_width (const unsigned char *, EMACS_INT, int,
614 EMACS_INT *, EMACS_INT *); 614 EMACS_INT *, EMACS_INT *);
615extern EMACS_INT lisp_string_width (Lisp_Object, int, 615extern EMACS_INT lisp_string_width (Lisp_Object, EMACS_INT,
616 EMACS_INT *, EMACS_INT *); 616 EMACS_INT *, EMACS_INT *);
617 617
618extern Lisp_Object Qcharacterp; 618extern Lisp_Object Qcharacterp;