summaryrefslogtreecommitdiff
path: root/src/charset.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2011-07-17 23:44:01 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2011-07-17 23:44:01 -0700
commitcaeeedc1afd7205303a99ef8ce7e4ce7d2055042 (patch)
treea7d77fb5203b1f2b1ed0d3d79fda29587e0540d2 /src/charset.c
parent50849c52f8cf342b81c1db12b13f866ec6c049fc (diff)
downloademacs-caeeedc1afd7205303a99ef8ce7e4ce7d2055042.tar.gz
* charset.c (read_hex): New arg OVERFLOW. All uses changed.
Remove unreachable code. (read_hex, load_charset_map_from_file): Check for integer overflow.
Diffstat (limited to 'src/charset.c')
-rw-r--r--src/charset.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/src/charset.c b/src/charset.c
index 55234aa76aa..e2bfcd08671 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -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;