summaryrefslogtreecommitdiff
path: root/sys/src/cmd/cc
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2020-04-19 22:59:21 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2020-04-19 22:59:21 +0200
commite24bfa4941679fafc7578f542acc08acd18fff99 (patch)
tree1cb96c81e703d93ba37ed8a1e70e8e33bdf6ae88 /sys/src/cmd/cc
parent3f87ffea44150d233b11a38b1ca3673207fe206e (diff)
?a: catch symb[NSYMB] buffer overflow in lexer, cleanup, assume thechar is a rune
Diffstat (limited to 'sys/src/cmd/cc')
-rw-r--r--sys/src/cmd/cc/lexbody46
1 files changed, 34 insertions, 12 deletions
diff --git a/sys/src/cmd/cc/lexbody b/sys/src/cmd/cc/lexbody
index 471041617..2b3134296 100644
--- a/sys/src/cmd/cc/lexbody
+++ b/sys/src/cmd/cc/lexbody
@@ -111,7 +111,7 @@ newfile(char *s, int f)
if(f < 0)
i->f = open(s, 0);
if(i->f < 0) {
- yyerror("%ca: %r: %s", thechar, s);
+ yyerror("%Ca: %r: %s", thechar, s);
errorexit();
}
fi.c = 0;
@@ -121,8 +121,11 @@ newfile(char *s, int f)
Sym*
slookup(char *s)
{
-
- strcpy(symb, s);
+ strncpy(symb, s, NSYMB);
+ if(symb[NSYMB-1] != '\0'){
+ yyerror("symbol too long: %s", s);
+ errorexit();
+ }
return lookup();
}
@@ -130,31 +133,34 @@ Sym*
lookup(void)
{
Sym *s;
- long h;
+ ulong h;
char *p;
- int c, l;
+ int c, n;
h = 0;
- for(p=symb; c = *p; p++)
- h = h+h+h + c;
- l = (p - symb) + 1;
- if(h < 0)
+ for(p=symb; *p;) {
+ h = h * 3;
+ h += *p++;
+ }
+ n = (p - symb) + 1;
+ if((long)h < 0)
h = ~h;
h %= NHASH;
c = symb[0];
for(s = hash[h]; s != S; s = s->link) {
if(s->name[0] != c)
continue;
- if(memcmp(s->name, symb, l) == 0)
+ if(strcmp(s->name, symb) == 0)
return s;
}
s = alloc(sizeof(*s));
- s->name = alloc(l);
- memmove(s->name, symb, l);
+ s->name = alloc(n);
+ memmove(s->name, symb, n);
s->link = hash[h];
hash[h] = s;
syminit(s);
+
return s;
}
@@ -220,6 +226,8 @@ l1:
cp = symb;
aloop:
+ if(cp >= &symb[NSYMB-1])
+ goto toolong;
*cp++ = c;
c = GETC();
if(isalpha(c) || isdigit(c) || c == '_' || c == '$')
@@ -295,6 +303,8 @@ l1:
for(;;) {
if(!isdigit(c))
break;
+ if(cp >= &symb[NSYMB-1])
+ goto toolong;
*cp++ = c;
c = GETC();
}
@@ -316,6 +326,8 @@ l1:
casedot:
for(;;) {
+ if(cp >= &symb[NSYMB-1])
+ goto toolong;
*cp++ = c;
c = GETC();
if(!isdigit(c))
@@ -326,13 +338,19 @@ l1:
goto caseout;
casee:
+ if(cp >= &symb[NSYMB-1])
+ goto toolong;
*cp++ = 'e';
c = GETC();
if(c == '+' || c == '-') {
+ if(cp >= &symb[NSYMB-1])
+ goto toolong;
*cp++ = c;
c = GETC();
}
while(isdigit(c)) {
+ if(cp >= &symb[NSYMB-1])
+ goto toolong;
*cp++ = c;
c = GETC();
}
@@ -409,6 +427,10 @@ l1:
}
peekc = c1;
return c;
+toolong:
+ yyerror("token too long: %.*s...", utfnlen(symb, cp-symb), symb);
+ errorexit();
+ return -1;
}
int