Author: ek.kato
Date: Mon Jul  9 05:54:04 2007
New Revision: 4670

Modified:
   trunk/gtk/compose.c

Log:
* gtk/compose.c
  - (nextch)
  - (nexttoken)
  - (parse_compose_line)
    - Check buffer size (bug #11411).
  - (ParseComposeStringFile)
    - Check st_size of a compose file properly (bug #11411,
      Christian Biere).


Modified: trunk/gtk/compose.c
==============================================================================
--- trunk/gtk/compose.c (original)
+++ trunk/gtk/compose.c Mon Jul  9 05:54:04 2007
@@ -134,10 +134,13 @@
 }
 
 static int
-nextch(FILE *fp, int *lastch)
+nextch(FILE *fp, int *lastch, size_t *remain)
 {
     int c;
 
+    if (*remain <= 1)
+       return EOF;
+
     if (*lastch != 0) {
        c = *lastch;
        *lastch = 0;
@@ -183,14 +186,14 @@
 #endif
 
 static int
-nexttoken(FILE *fp, char *tokenbuf, int *lastch)
+nexttoken(FILE *fp, char *tokenbuf, int *lastch, size_t *remain)
 {
     int c;
     int token;
     char *p;
     int i, j;
 
-    while ((c = nextch(fp, lastch)) == ' ' || c == '\t') {
+    while ((c = nextch(fp, lastch, remain)) == ' ' || c == '\t') {
     }
     switch (c) {
     case EOF:
@@ -216,26 +219,30 @@
        break;
     case '"':
        p = tokenbuf;
-       while ((c = nextch(fp, lastch)) != '"') {
+       while ((c = nextch(fp, lastch, remain)) != '"') {
            if (c == '\n' || c == EOF) {
                putbackch(c, lastch);
                token = ERROR;
                goto string_error;
            } else if (c == '\\') {
-               c = nextch(fp, lastch);
+               c = nextch(fp, lastch, remain);
                switch (c) {
                case '\\':
                case '"':
                    *p++ = c;
+                   (*remain)--;
                    break;
                case 'n':
                    *p++ = '\n';
+                   (*remain)--;
                    break;
                case 'r':
                    *p++ = '\r';
+                   (*remain)--;
                    break;
                case 't':
                    *p++ = '\t';
+                   (*remain)--;
                    break;
                case '0':
                case '1':
@@ -246,20 +253,21 @@
                case '6':
                case '7':
                    i = c - '0';
-                   c = nextch(fp, lastch);
+                   c = nextch(fp, lastch, remain);
                    for (j = 0; j < 2 && c >= '0' && c <= '7'; j++) {
                        i <<= 3;
                        i += c - '0';
-                       c = nextch(fp, lastch);
+                       c = nextch(fp, lastch, remain);
                    }
                    putbackch(c, lastch);
                    *p++ = (char)i;
+                   (*remain)--;
                    break;
                case 'X':
                case 'x':
                    i = 0;
                    for (j = 0; j < 2; j++) {
-                       c = nextch(fp, lastch);
+                       c = nextch(fp, lastch, remain);
                        i <<= 4;
                        if (c >= '0' && c <= '9') {
                            i += c - '0';
@@ -278,6 +286,7 @@
                        goto string_error;
                    }
                    *p++ = (char)i;
+                   (*remain)--;
                    break;
                case EOF:
                    putbackch(c, lastch);
@@ -285,17 +294,19 @@
                    goto string_error;
                default:
                    *p++ = c;
+                   (*remain)--;
                    break;
                }
            } else {
                *p++ = c;
+               (*remain)--;
            }
        }
        *p = '\0';
        token = STRING;
        break;
     case '#':
-       while ((c = nextch(fp, lastch)) != '\n' && c != EOF) {
+       while ((c = nextch(fp, lastch, remain)) != '\n' && c != EOF) {
        }
        if (c == '\n') {
            token = ENDOFLINE;
@@ -307,10 +318,17 @@
        if (isalnum(c) || c == '_' || c == '-') {
            p = tokenbuf;
            *p++ = c;
-           c = nextch(fp, lastch);
+           (*remain)--;
+           c = nextch(fp, lastch, remain);
            while (isalnum(c) || c == '_' || c == '-') {
                *p++ = c;
-               c = nextch(fp, lastch);
+               (*remain)--;
+               c = nextch(fp, lastch, remain);
+           }
+           if (c == '\n' || c == EOF) {
+               putbackch(c, lastch);
+               token = ERROR;
+               goto string_error;
            }
            *p = '\0';
            putbackch(c, lastch);
@@ -450,7 +468,7 @@
 #define SEQUENCE_MAX    10
 
 static int
-parse_compose_line(FILE *fp, char* tokenbuf)
+parse_compose_line(FILE *fp, char* tokenbuf, size_t *remain)
 {
     int token;
     unsigned modifier_mask;
@@ -479,7 +497,7 @@
     g_get_charset(&encoding);
 
     do {
-       token = nexttoken(fp, tokenbuf, &lastch);
+       token = nexttoken(fp, tokenbuf, &lastch, remain);
     } while (token == ENDOFLINE);
 
     if (token == ENDOFFILE) {
@@ -491,7 +509,7 @@
        if ((token == KEY) && (strcmp("include", tokenbuf) == 0)) {
            char *filename;
            FILE *infp;
-           token = nexttoken(fp, tokenbuf, &lastch);
+           token = nexttoken(fp, tokenbuf, &lastch, remain);
            if (token != KEY && token != STRING)
                goto error;
 
@@ -506,19 +524,19 @@
        } else if ((token == KEY) && (strcmp("None", tokenbuf) == 0)) {
            modifier = 0;
            modifier_mask = AllMask;
-           token = nexttoken(fp, tokenbuf, &lastch);
+           token = nexttoken(fp, tokenbuf, &lastch, remain);
        } else {
            modifier_mask = modifier = 0;
            exclam = False;
            if (token == EXCLAM) {
                exclam = True;
-               token = nexttoken(fp, tokenbuf, &lastch);
+               token = nexttoken(fp, tokenbuf, &lastch, remain);
            }
            while (token == TILDE || token == KEY) {
                tilde = False;
                if (token == TILDE) {
                    tilde = True;
-                   token = nexttoken(fp, tokenbuf, &lastch);
+                   token = nexttoken(fp, tokenbuf, &lastch, remain);
                    if (token != KEY)
                        goto error;
                }
@@ -532,7 +550,7 @@
                } else {
                    modifier |= tmp;
                }
-               token = nexttoken(fp, tokenbuf, &lastch);
+               token = nexttoken(fp, tokenbuf, &lastch, remain);
            }
            if (exclam) {
                modifier_mask = AllMask;
@@ -544,12 +562,12 @@
            goto error;
        }
 
-       token = nexttoken(fp, tokenbuf, &lastch);
+       token = nexttoken(fp, tokenbuf, &lastch, remain);
        if (token != KEY) {
            goto error;
        }
 
-       token = nexttoken(fp, tokenbuf, &lastch);
+       token = nexttoken(fp, tokenbuf, &lastch, remain);
        if (token != GREATER) {
            goto error;
        }
@@ -565,22 +583,22 @@
        n++;
        if (n >= SEQUENCE_MAX)
            goto error;
-       token = nexttoken(fp, tokenbuf, &lastch);
+       token = nexttoken(fp, tokenbuf, &lastch, remain);
     } while (token != COLON);
 
-    token = nexttoken(fp, tokenbuf, &lastch);
+    token = nexttoken(fp, tokenbuf, &lastch, remain);
     if (token == STRING) {
        if ((rhs_string_mb = (char *)malloc(strlen(tokenbuf) + 1)) == NULL)
            goto error;
        strcpy(rhs_string_mb, tokenbuf);
-       token = nexttoken(fp, tokenbuf, &lastch);
+       token = nexttoken(fp, tokenbuf, &lastch, remain);
        if (token == KEY) {
            rhs_keysym = XStringToKeysym(tokenbuf);
            if (rhs_keysym == NoSymbol) {
                free(rhs_string_mb);
                goto error;
            }
-           token = nexttoken(fp, tokenbuf, &lastch);
+           token = nexttoken(fp, tokenbuf, &lastch, remain);
        }
        if (token != ENDOFLINE && token != ENDOFFILE) {
            free(rhs_string_mb);
@@ -591,7 +609,7 @@
        if (rhs_keysym == NoSymbol) {
            goto error;
        }
-       token = nexttoken(fp, tokenbuf, &lastch);
+       token = nexttoken(fp, tokenbuf, &lastch, remain);
        if (token != ENDOFLINE && token != ENDOFFILE) {
            goto error;
        }
@@ -611,12 +629,12 @@
        goto error;
     }
 
-       {
-               char *result;
-               result = g_locale_to_utf8(rhs_string_mb, -1, NULL, NULL, NULL);
-               rhs_string_utf8 = strdup(result);
-               g_free(result);
-       }
+    {
+       char *result;
+       result = g_locale_to_utf8(rhs_string_mb, -1, NULL, NULL, NULL);
+       rhs_string_utf8 = strdup(result);
+       g_free(result);
+    }
 
     for (i = 0; i < n; i++) {
        for (p = *top; p; p = p->next) {
@@ -656,7 +674,7 @@
     return n;
 error:
     while (token != ENDOFLINE && token != ENDOFFILE) {
-       token = nexttoken(fp, tokenbuf, &lastch);
+       token = nexttoken(fp, tokenbuf, &lastch, remain);
     }
     return 0;
 }
@@ -664,22 +682,21 @@
 static void
 ParseComposeStringFile(FILE *fp)
 {
-    char tb[8192];
     char* tbp;
     struct stat st;
+    size_t tb_remain;
 
-    if (fstat(fileno(fp), &st) != -1) {
-       unsigned long size = (unsigned long)st.st_size;
-       if (size <= sizeof tb)
-           tbp = tb;
-       else
-           tbp = (char *)malloc(size);
+    if (fstat(fileno(fp), &st) != -1 &&
+       S_ISREG(st.st_mode) &&
+       st.st_size > 0 &&
+       st.st_size + (size_t)0 < (off_t)0 + (size_t)-1) {
 
+       tbp = (char *)malloc(st.st_size);
+       tb_remain = st.st_size;
        if (tbp != NULL) {
-           while (parse_compose_line(fp, tbp) >= 0) {
+           while (parse_compose_line(fp, tbp, &tb_remain) >= 0) {
            }
-           if (tbp != tb)
-               free (tbp);
+           free (tbp);
        }
     }
 }

Reply via email to