]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compile: Detect invalid and likely-bad import statements.
authorIan Lance Taylor <iant@google.com>
Mon, 17 Sep 2012 05:15:36 +0000 (05:15 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 17 Sep 2012 05:15:36 +0000 (05:15 +0000)
* Make-lang.in (go/gogo.o): Depend on filenames.h.

From-SVN: r191372

gcc/go/ChangeLog
gcc/go/Make-lang.in
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/lex.cc
gcc/go/gofrontend/lex.h
gcc/go/gofrontend/parse.cc

index d3a6e29a9ec5439d0f8457e59e6ba0df28d4cd98..18a9aa663f9721cf9db90383145f53e456309b78 100644 (file)
@@ -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.
index 34e5584cc09153fd2fe0f0763b0e9b7e82166265..b3cb2bdbc195d9c4c99ccd172d77d1ac10f3cdf4 100644 (file)
@@ -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) \
index 6e9b8c124aa34ce6612e0cab666e84d6febed944..a434c4df6bb53afd9359ac4316236c2f8716db32 100644 (file)
@@ -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);
index 5b7ce6869e6c641284983d3505c1f247d985040d..42d444b5fbc6a9b31ad459bac05241ddd1ef6d41 100644 (file)
@@ -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".
 
index 8858e73d97a006edba4a5e614db7c8ea044d35cd..074bbaea4ed463445e1e66a32f0e833c51ca8796 100644 (file)
@@ -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();
index 29323f05c6c3010af06498da138787b2ae4455b0..cfcc00f99ee4b01efa9a821a40503a9c993e4944 100644 (file)
@@ -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;
     }