forked from OSchip/llvm-project
[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 llvm-svn: 342961
This commit is contained in:
parent
cba939a74b
commit
e631d09fc5
|
@ -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::StringRef Content) {
|
|||
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::StringRef OrigUri) {
|
|||
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('/');
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue