aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2012-09-17 05:15:36 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-09-17 05:15:36 +0000
commit5dbeb128d9d33ef23e15b65dad1c7cc28793692d (patch)
tree5324a239d8658af99c9f07bfb4bc67b31c74c90b
parentf0e1e86d226c40d8f13f1abd1f8fac7017075000 (diff)
downloadgcc-5dbeb128d9d33ef23e15b65dad1c7cc28793692d.zip
gcc-5dbeb128d9d33ef23e15b65dad1c7cc28793692d.tar.gz
gcc-5dbeb128d9d33ef23e15b65dad1c7cc28793692d.tar.bz2
compile: Detect invalid and likely-bad import statements.
* Make-lang.in (go/gogo.o): Depend on filenames.h. From-SVN: r191372
-rw-r--r--gcc/go/ChangeLog4
-rw-r--r--gcc/go/Make-lang.in9
-rw-r--r--gcc/go/gofrontend/gogo.cc53
-rw-r--r--gcc/go/gofrontend/lex.cc30
-rw-r--r--gcc/go/gofrontend/lex.h4
-rw-r--r--gcc/go/gofrontend/parse.cc3
6 files changed, 98 insertions, 5 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index d3a6e29..18a9aa6 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -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.
diff --git a/gcc/go/Make-lang.in b/gcc/go/Make-lang.in
index 34e5584..b3cb2bd 100644
--- a/gcc/go/Make-lang.in
+++ b/gcc/go/Make-lang.in
@@ -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) \
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 6e9b8c1..a434c4d 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -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);
diff --git a/gcc/go/gofrontend/lex.cc b/gcc/go/gofrontend/lex.cc
index 5b7ce68..42d444b 100644
--- a/gcc/go/gofrontend/lex.cc
+++ b/gcc/go/gofrontend/lex.cc
@@ -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".
diff --git a/gcc/go/gofrontend/lex.h b/gcc/go/gofrontend/lex.h
index 8858e73..074bbae 100644
--- a/gcc/go/gofrontend/lex.h
+++ b/gcc/go/gofrontend/lex.h
@@ -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();
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index 29323f0..cfcc00f 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -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;
}