* charset.c (read_hex): New arg OVERFLOW. All uses changed.
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 18 Jul 2011 06:44:01 +0000 (23:44 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 18 Jul 2011 06:44:01 +0000 (23:44 -0700)
Remove unreachable code.
(read_hex, load_charset_map_from_file): Check for integer overflow.

src/ChangeLog
src/charset.c

index 940beee..869e263 100644 (file)
@@ -1,3 +1,9 @@
+2011-07-18  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * charset.c (read_hex): New arg OVERFLOW.  All uses changed.
+       Remove unreachable code.
+       (read_hex, load_charset_map_from_file): Check for integer overflow.
+
 2011-07-17  Paul Eggert  <eggert@cs.ucla.edu>
 
        * xterm.c: don't go over XClientMessageEvent limit
index 55234aa..e2bfcd0 100644 (file)
@@ -419,7 +419,7 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
    paying attention to comment character '#'.  */
 
 static inline unsigned
-read_hex (FILE *fp, int *eof)
+read_hex (FILE *fp, int *eof, int *overflow)
 {
   int c;
   unsigned n;
@@ -441,15 +441,16 @@ read_hex (FILE *fp, int *eof)
       *eof = 1;
       return 0;
     }
-  *eof = 0;
   n = 0;
-  if (c == 'x')
-    while ((c = getc (fp)) != EOF && isxdigit (c))
+  while (isxdigit (c = getc (fp)))
+    {
+      if (UINT_MAX >> 4 < n)
+       *overflow = 1;
       n = ((n << 4)
-          | (c <= '9' ? c - '0' : c <= 'F' ? c - 'A' + 10 : c - 'a' + 10));
-  else
-    while ((c = getc (fp)) != EOF && isdigit (c))
-      n = (n * 10) + c - '0';
+          | (c - ('0' <= c && c <= '9' ? '0'
+                  : 'A' <= c && c <= 'F' ? 'A' - 10
+                  : 'a' - 10)));
+    }
   if (c != EOF)
     ungetc (c, fp);
   return n;
@@ -479,7 +480,6 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
   unsigned max_code = CHARSET_MAX_CODE (charset);
   int fd;
   FILE *fp;
-  int eof;
   Lisp_Object suffixes;
   struct charset_map_entries *head, *entries;
   int n_entries, count;
@@ -504,22 +504,27 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
   memset (entries, 0, sizeof (struct charset_map_entries));
 
   n_entries = 0;
-  eof = 0;
   while (1)
     {
-      unsigned from, to;
-      int c;
+      unsigned from, to, c;
       int idx;
+      int eof = 0, overflow = 0;
 
-      from = read_hex (fp, &eof);
+      from = read_hex (fp, &eof, &overflow);
       if (eof)
        break;
       if (getc (fp) == '-')
-       to = read_hex (fp, &eof);
+       to = read_hex (fp, &eof, &overflow);
       else
        to = from;
-      c = (int) read_hex (fp, &eof);
+      if (eof)
+       break;
+      c = read_hex (fp, &eof, &overflow);
+      if (eof)
+       break;
 
+      if (overflow)
+       continue;
       if (from < min_code || to > max_code || from > to || c > MAX_CHAR)
        continue;