From e79d0e0250977640c9a888797a391da3a8f39d03 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 8 Jan 2019 15:24:47 +0000 Subject: [clangd] Fix a crash when reading an empty index file. Summary: Unfortunately, yaml::Input::setCurrentDocument() and yaml::Input::nextDocument() are internal APIs, the way we use them may cause a nullptr accessing when processing an empty YAML file. Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D56442 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@350633 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/YAMLSerialization.cpp | 9 ++++++--- unittests/clangd/SerializationTests.cpp | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/clangd/index/YAMLSerialization.cpp b/clangd/index/YAMLSerialization.cpp index 27ed299e..7eb5b4cf 100644 --- a/clangd/index/YAMLSerialization.cpp +++ b/clangd/index/YAMLSerialization.cpp @@ -314,17 +314,20 @@ llvm::Expected readYAML(llvm::StringRef Data) { Arena; // store the underlying data of Position::FileURI. llvm::UniqueStringSaver Strings(Arena); llvm::yaml::Input Yin(Data, &Strings); - do { + while (Yin.setCurrentDocument()) { + llvm::yaml::EmptyContext Ctx; VariantEntry Variant; - Yin >> Variant; + yamlize(Yin, Variant, true, Ctx); if (Yin.error()) return llvm::errorCodeToError(Yin.error()); + if (Variant.Symbol) Symbols.insert(*Variant.Symbol); if (Variant.Refs) for (const auto &Ref : Variant.Refs->second) Refs.insert(Variant.Refs->first, Ref); - } while (Yin.nextDocument()); + Yin.nextDocument(); + } IndexFileIn Result; Result.Symbols.emplace(std::move(Symbols).build()); diff --git a/unittests/clangd/SerializationTests.cpp b/unittests/clangd/SerializationTests.cpp index fe571c4a..a8ffaa1c 100644 --- a/unittests/clangd/SerializationTests.cpp +++ b/unittests/clangd/SerializationTests.cpp @@ -91,6 +91,10 @@ MATCHER_P2(IncludeHeaderWithRef, IncludeHeader, References, "") { return (arg.IncludeHeader == IncludeHeader) && (arg.References == References); } +TEST(SerializationTest, NoCrashOnEmptyYAML) { + EXPECT_TRUE(bool(readIndexFile(""))); +} + TEST(SerializationTest, YAMLConversions) { auto In = readIndexFile(YAML); EXPECT_TRUE(bool(In)) << In.takeError(); -- cgit v1.2.3