Fix crash in attempting to canonicalize paths longer than _MAX_PATH
authorScott Graham <scottmg@chromium.org>
Mon, 8 Jun 2015 20:21:55 +0000 (13:21 -0700)
committerScott Graham <scottmg@chromium.org>
Mon, 8 Jun 2015 20:21:55 +0000 (13:21 -0700)
src/includes_normalize-win32.cc
src/includes_normalize_test.cc

index 1e88a0a..066f512 100644 (file)
@@ -96,8 +96,12 @@ string IncludesNormalize::Relativize(StringPiece path, const string& start) {
 
 string IncludesNormalize::Normalize(const string& input,
                                     const char* relative_to) {
-  char copy[_MAX_PATH];
+  char copy[_MAX_PATH + 1];
   size_t len = input.size();
+  if (len > _MAX_PATH) {
+    Warning("path too long '%s'\n", input.c_str());
+    return input;
+  }
   strncpy(copy, input.c_str(), input.size() + 1);
   string err;
   unsigned int slash_bits;
index c4c2476..b3519e2 100644 (file)
@@ -14,6 +14,8 @@
 
 #include "includes_normalize.h"
 
+#include <algorithm>
+
 #include <direct.h>
 
 #include "test.h"
@@ -102,3 +104,48 @@ TEST(IncludesNormalize, DifferentDrive) {
             IncludesNormalize::Normalize("P:/vs08\\../wee\\stuff.h",
                                          "D:\\stuff/things"));
 }
+
+TEST(IncludesNormalize, LongInvalidPath) {
+  const char kLongInputString[] =
+      "C:\\Program Files (x86)\\Microsoft Visual Studio "
+      "12.0\\VC\\INCLUDEwarning #31001: The dll for reading and writing the "
+      "pdb (for example, mspdb110.dll) could not be found on your path. This "
+      "is usually a configuration error. Compilation will continue using /Z7 "
+      "instead of /Zi, but expect a similar error when you link your program.";
+  // Too long, won't be canonicalized, but just don't crash.
+  EXPECT_EQ(kLongInputString,
+            IncludesNormalize::Normalize(kLongInputString, NULL));
+
+  const char kExactlyMaxPath[] =
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "012345678\\"
+      "0123456789";
+  std::string forward_slashes(kExactlyMaxPath);
+  std::replace(forward_slashes.begin(), forward_slashes.end(), '\\', '/');
+  // Make sure a path that's exactly _MAX_PATH long is canonicalized.
+  EXPECT_EQ(forward_slashes,
+            IncludesNormalize::Normalize(kExactlyMaxPath, NULL));
+}