diff options
| author | Russ Cox <rsc@golang.org> | 2010-06-09 11:00:55 -0700 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2010-06-09 11:00:55 -0700 |
| commit | f067c34934cac10bb85820bc236efcf416176daa (patch) | |
| tree | d99738fe4769bf42cf63cc85900866a1c2eb5e4a /src/cmd/gc/lex.c | |
| parent | cc5336b66c854904f622f322aba5f522c6e04f3c (diff) | |
| download | golang-f067c34934cac10bb85820bc236efcf416176daa.tar.gz | |
gc: more cleanup
* disallow surrogate pair runes.
* diagnose impossible type assertions
* eliminate another static buffer.
* do not overflow lexbuf.
* add -u flag to disable package unsafe.
R=ken2
CC=golang-dev
http://codereview.appspot.com/1619042
Diffstat (limited to 'src/cmd/gc/lex.c')
| -rw-r--r-- | src/cmd/gc/lex.c | 90 |
1 files changed, 68 insertions, 22 deletions
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c index 7f8527174..5dc6d78cf 100644 --- a/src/cmd/gc/lex.c +++ b/src/cmd/gc/lex.c @@ -21,6 +21,26 @@ enum EOF = -1, }; +void +usage(void) +{ + print("usage: %cg [flags] file.go...\n"); + print("flags:\n"); + // -A is allow use of "any" type, for bootstrapping + print(" -I DIR search for packages in DIR\n"); + print(" -d print declarations\n"); + print(" -e no limit on number of errors printed\n"); + print(" -f print stack frame structure\n"); + print(" -h panic on an error\n"); + print(" -o file specify output file\n"); + print(" -S print the assembly language\n"); + print(" -V print the compiler version\n"); + print(" -u disable package unsafe\n"); + print(" -w print the parse tree after typing\n"); + print(" -x print lex tokens\n"); + exit(0); +} + int main(int argc, char *argv[]) { @@ -62,19 +82,24 @@ main(int argc, char *argv[]) break; case 'o': - outfile = ARGF(); + outfile = EARGF(usage()); break; case 'I': - addidir(ARGF()); + addidir(EARGF(usage())); + break; + + case 'u': + safemode = 1; break; + case 'V': print("%cg version %s\n", thechar, getgoversion()); - errorexit(); + exit(0); } ARGEND if(argc < 1) - goto usage; + usage(); // special flag to detect compilation of package runtime compiling_runtime = debug['+']; @@ -188,22 +213,6 @@ main(int argc, char *argv[]) flusherrors(); exit(0); return 0; - -usage: - print("flags:\n"); - // -A is allow use of "any" type, for bootstrapping - print(" -I DIR search for packages in DIR\n"); - print(" -d print declarations\n"); - print(" -e no limit on number of errors printed\n"); - print(" -f print stack frame structure\n"); - print(" -h panic on an error\n"); - print(" -o file specify output file\n"); - print(" -S print the assembly language\n"); - print(" -V print the compiler version\n"); - print(" -w print the parse tree after typing\n"); - print(" -x print lex tokens\n"); - exit(0); - return 0; } int @@ -336,6 +345,10 @@ importfile(Val *f, int line) } if(strcmp(f->u.sval->s, "unsafe") == 0) { + if(safemode) { + yyerror("cannot import package unsafe"); + errorexit(); + } importpkg = mkpkg(f->u.sval); cannedimports("unsafe.6", unsafeimport); return; @@ -461,7 +474,7 @@ _yylex(void) { int c, c1, clen, escflag, ncp; vlong v; - char *cp; + char *cp, *ep; Rune rune; Sym *s; static Loophack *lstk; @@ -485,11 +498,13 @@ l0: if(c >= Runeself) { /* all multibyte runes are alpha */ cp = lexbuf; + ep = lexbuf+sizeof lexbuf; goto talph; } if(isalpha(c)) { cp = lexbuf; + ep = lexbuf+sizeof lexbuf; goto talph; } @@ -504,12 +519,14 @@ l0: case '_': cp = lexbuf; + ep = lexbuf+sizeof lexbuf; goto talph; case '.': c1 = getc(); if(isdigit(c1)) { cp = lexbuf; + ep = lexbuf+sizeof lexbuf; *cp++ = c; c = c1; c1 = 0; @@ -862,6 +879,10 @@ talph: * prefix has been stored */ for(;;) { + if(cp+10 >= ep) { + yyerror("identifier too long"); + errorexit(); + } if(c >= Runeself) { ungetc(c); rune = getr(); @@ -898,8 +919,13 @@ talph: tnum: c1 = 0; cp = lexbuf; + ep = lexbuf+sizeof lexbuf; if(c != '0') { for(;;) { + if(cp+10 >= ep) { + yyerror("identifier too long"); + errorexit(); + } *cp++ = c; c = getc(); if(isdigit(c)) @@ -911,6 +937,10 @@ tnum: c = getc(); if(c == 'x' || c == 'X') { for(;;) { + if(cp+10 >= ep) { + yyerror("identifier too long"); + errorexit(); + } *cp++ = c; c = getc(); if(isdigit(c)) @@ -930,6 +960,10 @@ tnum: c1 = 0; for(;;) { + if(cp+10 >= ep) { + yyerror("identifier too long"); + errorexit(); + } if(!isdigit(c)) break; if(c < '0' || c > '7') @@ -973,6 +1007,10 @@ ncu: casedot: for(;;) { + if(cp+10 >= ep) { + yyerror("identifier too long"); + errorexit(); + } *cp++ = c; c = getc(); if(!isdigit(c)) @@ -993,6 +1031,10 @@ casee: if(!isdigit(c)) yyerror("malformed fp constant exponent"); while(isdigit(c)) { + if(cp+10 >= ep) { + yyerror("identifier too long"); + errorexit(); + } *cp++ = c; c = getc(); } @@ -1010,6 +1052,10 @@ casep: if(!isdigit(c)) yyerror("malformed fp constant exponent"); while(isdigit(c)) { + if(cp+10 >= ep) { + yyerror("identifier too long"); + errorexit(); + } *cp++ = c; c = getc(); } @@ -1254,7 +1300,7 @@ hex: ungetc(c); break; } - if(u && l > Runemax) { + if(u && (l > Runemax || (0xd800 <= l && l < 0xe000))) { yyerror("invalid Unicode code point in escape sequence: %#llx", l); l = Runeerror; } |
