From a69e6b4ba22d1ab32a423389473eab14793ba77c Mon Sep 17 00:00:00 2001
From: David Raila <raila@illinois.edu>
Date: Wed, 16 Jul 2008 20:57:56 +0000
Subject: [PATCH] Allow trailing slashes in --proto_path mappings.

Patch by Kevin Ko <kevin.s.ko@gmail.com>.
---
 CONTRIBUTORS.txt                                  |  3 +++
 src/google/protobuf/compiler/importer.cc          | 10 +++++++++-
 src/google/protobuf/compiler/importer_unittest.cc |  7 +++++++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 6aeea57..4738f51 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -33,3 +33,6 @@ Documentation:
 
 Maven packaging:
   Gregory Kick <gak@google.com>
+
+Non-Google patch contributors:
+  Kevin Ko <kevin.s.ko@gmail.com>
diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc
index 6118293..62089cd 100644
--- a/src/google/protobuf/compiler/importer.cc
+++ b/src/google/protobuf/compiler/importer.cc
@@ -280,10 +280,18 @@ static bool ApplyMapping(const string& filename,
       // Not an exact match.  Is the next character a '/'?  Otherwise,
       // this isn't actually a match at all.  E.g. the prefix "foo/bar"
       // does not match the filename "foo/barbaz".
+      int after_prefix_start = -1;
       if (filename[old_prefix.size()] == '/') {
+        after_prefix_start = old_prefix.size() + 1;
+      } else if (filename[old_prefix.size() - 1] == '/') {
+        // old_prefix is never empty, and canonicalized paths never have
+        // consecutive '/' characters.
+        after_prefix_start = old_prefix.size();
+      }
+      if (after_prefix_start != -1) {
         // Yep.  So the prefixes are directories and the filename is a file
         // inside them.
-        string after_prefix = filename.substr(old_prefix.size() + 1);
+        string after_prefix = filename.substr(after_prefix_start);
         if (ContainsParentReference(after_prefix)) {
           // We do not allow the file name to use "..".
           return false;
diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc
index 5b5d283..55c52e4 100644
--- a/src/google/protobuf/compiler/importer_unittest.cc
+++ b/src/google/protobuf/compiler/importer_unittest.cc
@@ -492,6 +492,7 @@ TEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) {
   source_tree_.MapPath("dir3", "./foo/bar/.");
   source_tree_.MapPath("dir4", ".");
   source_tree_.MapPath("", "/qux");
+  source_tree_.MapPath("dir5", "/quux/");
 
   string virtual_file;
   string shadowing_disk_file;
@@ -530,6 +531,12 @@ TEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) {
     source_tree_.DiskFileToVirtualFile(
       "/qux/baz", &virtual_file, &shadowing_disk_file));
   EXPECT_EQ("baz", virtual_file);
+
+  // "/quux/bar" is under "/quux".
+  EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+    source_tree_.DiskFileToVirtualFile(
+      "/quux/bar", &virtual_file, &shadowing_disk_file));
+  EXPECT_EQ("dir5/bar", virtual_file);
 }
 
 }  // namespace
-- 
GitLab