mirror of
https://github.com/golang/go
synced 2024-11-21 23:14:40 -07:00
gc: reject import paths containing special characters
Also allow multiple invalid import statements in a single file. Fixes #3021. The changes to go/parser and the language specifcation have already been committed. R=rsc, gri CC=golang-dev https://golang.org/cl/5672084
This commit is contained in:
parent
490c3d4a42
commit
dc38756ce1
@ -1171,6 +1171,7 @@ Type* getthisx(Type *t);
|
||||
int implements(Type *t, Type *iface, Type **missing, Type **have, int *ptr);
|
||||
void importdot(Pkg *opkg, Node *pack);
|
||||
int is64(Type *t);
|
||||
int isbadimport(Strlit *s);
|
||||
int isblank(Node *n);
|
||||
int isblanksym(Sym *s);
|
||||
int isfixedarray(Type *t);
|
||||
|
@ -205,7 +205,15 @@ import_stmt:
|
||||
my->lastlineno = $1;
|
||||
my->block = 1; // at top level
|
||||
}
|
||||
|
||||
| import_here import_there
|
||||
{
|
||||
// When an invalid import path is passed to importfile,
|
||||
// it calls yyerror and then sets up a fake import with
|
||||
// no package statement. This allows us to test more
|
||||
// than one invalid import statement in a single file.
|
||||
if(nerrors == 0)
|
||||
fatal("phase error in import");
|
||||
}
|
||||
|
||||
import_stmt_list:
|
||||
import_stmt
|
||||
|
@ -573,6 +573,13 @@ findpkg(Strlit *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
fakeimport(void)
|
||||
{
|
||||
importpkg = mkpkg(strlit("fake"));
|
||||
cannedimports("fake.6", "$$\n");
|
||||
}
|
||||
|
||||
void
|
||||
importfile(Val *f, int line)
|
||||
{
|
||||
@ -589,17 +596,19 @@ importfile(Val *f, int line)
|
||||
|
||||
if(f->ctype != CTSTR) {
|
||||
yyerror("import statement not a string");
|
||||
fakeimport();
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(f->u.sval->s) != f->u.sval->len) {
|
||||
yyerror("import path contains NUL");
|
||||
errorexit();
|
||||
if(f->u.sval->len == 0) {
|
||||
yyerror("import path is empty");
|
||||
fakeimport();
|
||||
return;
|
||||
}
|
||||
|
||||
if(strchr(f->u.sval->s, '\\')) {
|
||||
yyerror("import path contains backslash; use slash");
|
||||
errorexit();
|
||||
|
||||
if(isbadimport(f->u.sval)) {
|
||||
fakeimport();
|
||||
return;
|
||||
}
|
||||
|
||||
// The package name main is no longer reserved,
|
||||
|
@ -3559,11 +3559,9 @@ mkpkg(Strlit *path)
|
||||
{
|
||||
Pkg *p;
|
||||
int h;
|
||||
|
||||
if(strlen(path->s) != path->len) {
|
||||
yyerror("import path contains NUL byte");
|
||||
|
||||
if(isbadimport(path))
|
||||
errorexit();
|
||||
}
|
||||
|
||||
h = stringhash(path->s) & (nelem(phash)-1);
|
||||
for(p=phash[h]; p; p=p->link)
|
||||
@ -3612,3 +3610,41 @@ addinit(Node **np, NodeList *init)
|
||||
n->ninit = concat(init, n->ninit);
|
||||
n->ullman = UINF;
|
||||
}
|
||||
|
||||
int
|
||||
isbadimport(Strlit *path)
|
||||
{
|
||||
char *s;
|
||||
Rune r;
|
||||
|
||||
if(strlen(path->s) != path->len) {
|
||||
yyerror("import path contains NUL");
|
||||
return 1;
|
||||
}
|
||||
|
||||
s = path->s;
|
||||
while(*s) {
|
||||
s += chartorune(&r, s);
|
||||
if(r == Runeerror) {
|
||||
yyerror("import path contains invalid UTF-8 sequence");
|
||||
return 1;
|
||||
}
|
||||
if(r < 0x20 || r == 0x7f) {
|
||||
yyerror("import path contains control character");
|
||||
return 1;
|
||||
}
|
||||
if(r == '\\') {
|
||||
yyerror("import path contains backslash; use slash");
|
||||
return 1;
|
||||
}
|
||||
if(isspacerune(r)) {
|
||||
yyerror("import path contains space character");
|
||||
return 1;
|
||||
}
|
||||
if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}~", r)) {
|
||||
yyerror("import path contains invalid character '%C'", r);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
3899
src/cmd/gc/y.tab.c
3899
src/cmd/gc/y.tab.c
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,8 @@
|
||||
/* A Bison parser, made by GNU Bison 2.5. */
|
||||
|
||||
/* A Bison parser, made by GNU Bison 2.4.1. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -148,7 +146,7 @@
|
||||
typedef union YYSTYPE
|
||||
{
|
||||
|
||||
/* Line 1676 of yacc.c */
|
||||
/* Line 2068 of yacc.c */
|
||||
#line 28 "go.y"
|
||||
|
||||
Node* node;
|
||||
@ -160,8 +158,8 @@ typedef union YYSTYPE
|
||||
|
||||
|
||||
|
||||
/* Line 1676 of yacc.c */
|
||||
#line 165 "y.tab.h"
|
||||
/* Line 2068 of yacc.c */
|
||||
#line 163 "y.tab.h"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
|
@ -14,25 +14,25 @@ static struct {
|
||||
// is converted by bisonerrors into the yystate and yychar caused
|
||||
// by that token list.
|
||||
|
||||
220, ',',
|
||||
221, ',',
|
||||
"unexpected comma during import block",
|
||||
|
||||
376, ';',
|
||||
377, ';',
|
||||
"unexpected semicolon or newline before {",
|
||||
|
||||
397, ';',
|
||||
398, ';',
|
||||
"unexpected semicolon or newline before {",
|
||||
|
||||
236, ';',
|
||||
237, ';',
|
||||
"unexpected semicolon or newline before {",
|
||||
|
||||
473, LBODY,
|
||||
474, LBODY,
|
||||
"unexpected semicolon or newline before {",
|
||||
|
||||
22, '{',
|
||||
"unexpected semicolon or newline before {",
|
||||
|
||||
143, ';',
|
||||
144, ';',
|
||||
"unexpected semicolon or newline in type declaration",
|
||||
|
||||
37, '}',
|
||||
@ -44,30 +44,30 @@ static struct {
|
||||
37, ',',
|
||||
"unexpected comma in channel type",
|
||||
|
||||
436, LELSE,
|
||||
437, LELSE,
|
||||
"unexpected semicolon or newline before else",
|
||||
|
||||
256, ',',
|
||||
257, ',',
|
||||
"name list not allowed in interface type",
|
||||
|
||||
236, LVAR,
|
||||
237, LVAR,
|
||||
"var declaration not allowed in for initializer",
|
||||
|
||||
65, '{',
|
||||
"unexpected { at end of statement",
|
||||
|
||||
375, '{',
|
||||
376, '{',
|
||||
"unexpected { at end of statement",
|
||||
|
||||
124, ';',
|
||||
125, ';',
|
||||
"argument to go/defer must be function call",
|
||||
|
||||
424, ';',
|
||||
425, ';',
|
||||
"need trailing comma before newline in composite literal",
|
||||
|
||||
111, LNAME,
|
||||
112, LNAME,
|
||||
"nested func not allowed",
|
||||
|
||||
614, ';',
|
||||
615, ';',
|
||||
"else must be followed by if or statement block"
|
||||
};
|
||||
|
@ -4,10 +4,48 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Verify that imports with backslashes are rejected by the compiler.
|
||||
// Verify that invalid imports are rejected by the compiler.
|
||||
// Does not compile.
|
||||
// TODO: make more thorough.
|
||||
|
||||
package main
|
||||
|
||||
import `net\http` // ERROR "backslash"
|
||||
// Correct import paths.
|
||||
import _ "fmt"
|
||||
import _ `time`
|
||||
import _ "m\x61th"
|
||||
import _ "go/parser"
|
||||
|
||||
// Correct import paths, but the packages don't exist.
|
||||
// Don't test.
|
||||
//import "a.b"
|
||||
//import "greek/αβ"
|
||||
|
||||
// Import paths must be strings.
|
||||
import 42 // ERROR "import statement"
|
||||
import 'a' // ERROR "import statement"
|
||||
import 3.14 // ERROR "import statement"
|
||||
import 0.25i // ERROR "import statement"
|
||||
|
||||
// Each of these pairs tests both `` vs "" strings
|
||||
// and also use of invalid characters spelled out as
|
||||
// escape sequences and written directly.
|
||||
// For example `"\x00"` tests import "\x00"
|
||||
// while "`\x00`" tests import `<actual-NUL-byte>`.
|
||||
import "" // ERROR "import path"
|
||||
import `` // ERROR "import path"
|
||||
import "\x00" // ERROR "import path"
|
||||
import `\x00` // ERROR "import path"
|
||||
import "\x7f" // ERROR "import path"
|
||||
import `\x7f` // ERROR "import path"
|
||||
import "a!" // ERROR "import path"
|
||||
import `a!` // ERROR "import path"
|
||||
import "a b" // ERROR "import path"
|
||||
import `a b` // ERROR "import path"
|
||||
import "a\\b" // ERROR "import path"
|
||||
import `a\\b` // ERROR "import path"
|
||||
import "\"`a`\"" // ERROR "import path"
|
||||
import `\"a\"` // ERROR "import path"
|
||||
import "\x80\x80" // ERROR "import path"
|
||||
import `\x80\x80` // ERROR "import path"
|
||||
import "\xFFFD" // ERROR "import path"
|
||||
import `\xFFFD` // ERROR "import path"
|
||||
|
Loading…
Reference in New Issue
Block a user