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);
}
}
}