compile: Detect invalid and likely-bad import statements.
* Make-lang.in (go/gogo.o): Depend on filenames.h. From-SVN: r191372
This commit is contained in:
parent
f0e1e86d22
commit
5dbeb128d9
6 changed files with 98 additions and 5 deletions
|
@ -1,3 +1,7 @@
|
|||
2012-09-16 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* Make-lang.in (go/gogo.o): Depend on filenames.h.
|
||||
|
||||
2012-08-14 Diego Novillo <dnovillo@google.com>
|
||||
|
||||
Merge from cxx-conversion branch. Configury.
|
||||
|
|
|
@ -289,10 +289,11 @@ go/gogo-tree.o: go/gofrontend/gogo-tree.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
|
|||
convert.h output.h $(DIAGNOSTIC_H) $(GO_TYPES_H) \
|
||||
$(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) $(GO_RUNTIME_H) \
|
||||
go/gofrontend/backend.h $(GO_GOGO_H)
|
||||
go/gogo.o: go/gofrontend/gogo.cc $(GO_SYSTEM_H) $(GO_C_H) \
|
||||
go/gofrontend/go-dump.h $(GO_LEX_H) $(GO_TYPES_H) $(GO_STATEMENTS_H) \
|
||||
$(GO_EXPRESSIONS_H) go/gofrontend/dataflow.h $(GO_RUNTIME_H) \
|
||||
$(GO_IMPORT_H) $(GO_EXPORT_H) go/gofrontend/backend.h $(GO_GOGO_H)
|
||||
go/gogo.o: go/gofrontend/gogo.cc $(GO_SYSTEM_H) \
|
||||
$(srcdir)/../include/filenames.h $(GO_C_H) go/gofrontend/go-dump.h \
|
||||
$(GO_LEX_H) $(GO_TYPES_H) $(GO_STATEMENTS_H) $(GO_EXPRESSIONS_H) \
|
||||
go/gofrontend/dataflow.h $(GO_RUNTIME_H) $(GO_IMPORT_H) \
|
||||
$(GO_EXPORT_H) go/gofrontend/backend.h $(GO_GOGO_H)
|
||||
go/import.o: go/gofrontend/import.cc $(GO_SYSTEM_H) \
|
||||
$(srcdir)/../include/filenames.h $(srcdir)/../include/simple-object.h \
|
||||
$(GO_C_H) $(GO_GOGO_H) $(GO_LEX_H) $(GO_TYPES_H) $(GO_EXPORT_H) \
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "go-system.h"
|
||||
|
||||
#include "filenames.h"
|
||||
|
||||
#include "go-c.h"
|
||||
#include "go-dump.h"
|
||||
#include "lex.h"
|
||||
|
@ -385,6 +387,57 @@ Gogo::import_package(const std::string& filename,
|
|||
bool is_local_name_exported,
|
||||
Location location)
|
||||
{
|
||||
if (filename.empty())
|
||||
{
|
||||
error_at(location, "import path is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
const char *pf = filename.data();
|
||||
const char *pend = pf + filename.length();
|
||||
while (pf < pend)
|
||||
{
|
||||
unsigned int c;
|
||||
int adv = Lex::fetch_char(pf, &c);
|
||||
if (adv == 0)
|
||||
{
|
||||
error_at(location, "import path contains invalid UTF-8 sequence");
|
||||
return;
|
||||
}
|
||||
if (c == '\0')
|
||||
{
|
||||
error_at(location, "import path contains NUL");
|
||||
return;
|
||||
}
|
||||
if (c < 0x20 || c == 0x7f)
|
||||
{
|
||||
error_at(location, "import path contains control character");
|
||||
return;
|
||||
}
|
||||
if (c == '\\')
|
||||
{
|
||||
error_at(location, "import path contains backslash; use slash");
|
||||
return;
|
||||
}
|
||||
if (Lex::is_unicode_space(c))
|
||||
{
|
||||
error_at(location, "import path contains space character");
|
||||
return;
|
||||
}
|
||||
if (c < 0x7f && strchr("!\"#$%&'()*,:;<=>?[]^`{|}", c) != NULL)
|
||||
{
|
||||
error_at(location, "import path contains invalid character '%c'", c);
|
||||
return;
|
||||
}
|
||||
pf += adv;
|
||||
}
|
||||
|
||||
if (IS_ABSOLUTE_PATH(filename.c_str()))
|
||||
{
|
||||
error_at(location, "import path cannot be absolute path");
|
||||
return;
|
||||
}
|
||||
|
||||
if (filename == "unsafe")
|
||||
{
|
||||
this->import_unsafe(local_name, is_local_name_exported, location);
|
||||
|
|
|
@ -1705,6 +1705,27 @@ struct Unicode_range
|
|||
unsigned int stride;
|
||||
};
|
||||
|
||||
// A table of whitespace characters--Unicode code points classified as
|
||||
// "Space", "C" locale whitespace characters, the "next line" control
|
||||
// character (0085), the line separator (2028), the paragraph
|
||||
// separator (2029), and the "zero-width non-break space" (feff).
|
||||
|
||||
static const Unicode_range unicode_space[] =
|
||||
{
|
||||
{ 0x0009, 0x000d, 1 },
|
||||
{ 0x0020, 0x0020, 1 },
|
||||
{ 0x0085, 0x0085, 1 },
|
||||
{ 0x00a0, 0x00a0, 1 },
|
||||
{ 0x1680, 0x1680, 1 },
|
||||
{ 0x180e, 0x180e, 1 },
|
||||
{ 0x2000, 0x200a, 1 },
|
||||
{ 0x2028, 0x2029, 1 },
|
||||
{ 0x202f, 0x202f, 1 },
|
||||
{ 0x205f, 0x205f, 1 },
|
||||
{ 0x3000, 0x3000, 1 },
|
||||
{ 0xfeff, 0xfeff, 1 },
|
||||
};
|
||||
|
||||
// A table of Unicode digits--Unicode code points classified as
|
||||
// "Digit".
|
||||
|
||||
|
@ -2294,6 +2315,15 @@ Lex::is_in_unicode_range(unsigned int c, const Unicode_range* ranges,
|
|||
}
|
||||
}
|
||||
|
||||
// Return whether C is a space character.
|
||||
|
||||
bool
|
||||
Lex::is_unicode_space(unsigned int c)
|
||||
{
|
||||
return Lex::is_in_unicode_range(c, unicode_space,
|
||||
ARRAY_SIZE(unicode_space));
|
||||
}
|
||||
|
||||
// Return whether C is a Unicode digit--a Unicode code point
|
||||
// classified as "Digit".
|
||||
|
||||
|
|
|
@ -375,6 +375,10 @@ class Lex
|
|||
static int
|
||||
fetch_char(const char* str, unsigned int *value);
|
||||
|
||||
// Return whether C is a Unicode or "C" locale space character.
|
||||
static bool
|
||||
is_unicode_space(unsigned int c);
|
||||
|
||||
private:
|
||||
ssize_t
|
||||
get_line();
|
||||
|
|
|
@ -5337,7 +5337,8 @@ Parse::import_spec(void*)
|
|||
|
||||
if (!token->is_string())
|
||||
{
|
||||
error_at(this->location(), "missing import package name");
|
||||
error_at(this->location(), "import statement not a string");
|
||||
this->advance_token();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue