]> git.eshelyaron.com Git - emacs.git/commitdiff
* character.c (lisp_string_width): Check for string overflow.
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 16 May 2011 05:08:59 +0000 (22:08 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 16 May 2011 05:08:59 +0000 (22:08 -0700)
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.

src/ChangeLog
src/character.c
src/character.h

index 178ebf78932becb8765c74a6faa91cc56395126c..944a5dfbecbc4443cda806308264f3fade780da1 100644 (file)
@@ -1,5 +1,14 @@
 2011-05-16  Paul Eggert  <eggert@cs.ucla.edu>
 
+       * 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.
+
        * alloc.c (string_overflow): New function.
        (Fmake_string): Use it.  This doesn't change behavior, but saves
        a few bytes and will simplify future changes.
index 6a8b86d5d879fa523f7f516335df10bce211a3fe..a03c081a71637a8118315944be01f3752dd1d97a 100644 (file)
@@ -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;
index 864882db7f6aa70aa75c49a6ebf2acc1c9e1589e..5877d145d9ed5d78d16eb16dc782a78785f45f24 100644 (file)
@@ -612,7 +612,7 @@ extern EMACS_INT str_to_unibyte (const unsigned char *, unsigned char *,
 extern EMACS_INT strwidth (const char *, EMACS_INT);
 extern EMACS_INT c_string_width (const unsigned char *, EMACS_INT, int,
                                 EMACS_INT *, EMACS_INT *);
-extern EMACS_INT lisp_string_width (Lisp_Object, int,
+extern EMACS_INT lisp_string_width (Lisp_Object, EMACS_INT,
                                    EMACS_INT *, EMACS_INT *);
 
 extern Lisp_Object Qcharacterp;