diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2020-04-19 22:59:21 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2020-04-19 22:59:21 +0200 |
commit | e24bfa4941679fafc7578f542acc08acd18fff99 (patch) | |
tree | 1cb96c81e703d93ba37ed8a1e70e8e33bdf6ae88 /sys/src/cmd/cc | |
parent | 3f87ffea44150d233b11a38b1ca3673207fe206e (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/lexbody | 46 |
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 |