summaryrefslogtreecommitdiff
path: root/src/cmd/gc/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/lex.c')
-rw-r--r--src/cmd/gc/lex.c90
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;
}