[clang-tools-extra] r342961 - [clangd] Check that scheme is valid when parsing URI.

Eric Liu via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 25 03:47:46 PDT 2018


Author: ioeric
Date: Tue Sep 25 03:47:46 2018
New Revision: 342961

URL: http://llvm.org/viewvc/llvm-project?rev=342961&view=rev
Log:
[clangd] Check that scheme is valid when parsing URI.

Reviewers: sammccall

Reviewed By: sammccall

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Differential Revision: https://reviews.llvm.org/D52455

Modified:
    clang-tools-extra/trunk/clangd/URI.cpp
    clang-tools-extra/trunk/unittests/clangd/URITests.cpp

Modified: clang-tools-extra/trunk/clangd/URI.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/URI.cpp?rev=342961&r1=342960&r2=342961&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/URI.cpp (original)
+++ clang-tools-extra/trunk/clangd/URI.cpp Tue Sep 25 03:47:46 2018
@@ -11,8 +11,11 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
+#include <algorithm>
 #include <iomanip>
+#include <locale>
 #include <sstream>
 
 LLVM_INSTANTIATE_REGISTRY(clang::clangd::URISchemeRegistry)
@@ -128,6 +131,17 @@ std::string percentDecode(llvm::StringRe
   return Result;
 }
 
+bool isValidScheme(llvm::StringRef Scheme) {
+  if (Scheme.empty())
+    return false;
+  if (!std::isalpha(Scheme[0]))
+    return false;
+  return std::all_of(Scheme.begin() + 1, Scheme.end(), [](char C) {
+    return std::isalpha(C) || std::isdigit(C) || C == '+' || C == '.' ||
+           C == '-';
+  });
+}
+
 } // namespace
 
 URI::URI(llvm::StringRef Scheme, llvm::StringRef Authority,
@@ -158,9 +172,13 @@ llvm::Expected<URI> URI::parse(llvm::Str
   llvm::StringRef Uri = OrigUri;
 
   auto Pos = Uri.find(':');
-  if (Pos == 0 || Pos == llvm::StringRef::npos)
+  if (Pos == llvm::StringRef::npos)
     return make_string_error("Scheme must be provided in URI: " + OrigUri);
-  U.Scheme = percentDecode(Uri.substr(0, Pos));
+  auto SchemeStr = Uri.substr(0, Pos);
+  U.Scheme = percentDecode(SchemeStr);
+  if (!isValidScheme(U.Scheme))
+    return make_string_error(llvm::formatv("Invalid scheme: {0} (decoded: {1})",
+                                           SchemeStr, U.Scheme));
   Uri = Uri.substr(Pos + 1);
   if (Uri.consume_front("//")) {
     Pos = Uri.find('/');

Modified: clang-tools-extra/trunk/unittests/clangd/URITests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/URITests.cpp?rev=342961&r1=342960&r2=342961&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/URITests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/URITests.cpp Tue Sep 25 03:47:46 2018
@@ -51,9 +51,9 @@ TEST(PercentEncodingTest, Encode) {
 TEST(PercentEncodingTest, Decode) {
   EXPECT_EQ(parseOrDie("x:a/b/c").body(), "a/b/c");
 
-  EXPECT_EQ(parseOrDie("%3a://%3a/%3").scheme(), ":");
-  EXPECT_EQ(parseOrDie("%3a://%3a/%3").authority(), ":");
-  EXPECT_EQ(parseOrDie("%3a://%3a/%3").body(), "/%3");
+  EXPECT_EQ(parseOrDie("s%2b://%3a/%3").scheme(), "s+");
+  EXPECT_EQ(parseOrDie("s%2b://%3a/%3").authority(), ":");
+  EXPECT_EQ(parseOrDie("s%2b://%3a/%3").body(), "/%3");
 
   EXPECT_EQ(parseOrDie("x:a%21b%3ac~").body(), "a!b:c~");
 }
@@ -132,6 +132,7 @@ TEST(URITest, ParseFailed) {
   // Empty.
   EXPECT_TRUE(FailedParse(""));
   EXPECT_TRUE(FailedParse(":/a/b/c"));
+  EXPECT_TRUE(FailedParse("\"/a/b/c\" IWYU pragma: abc"));
 }
 
 TEST(URITest, Resolve) {




More information about the cfe-commits mailing list