Index: include/llvm/Support/YAMLParser.h =================================================================== --- include/llvm/Support/YAMLParser.h +++ include/llvm/Support/YAMLParser.h @@ -75,9 +75,9 @@ class Stream { public: /// \brief This keeps a reference to the string referenced by \p Input. - Stream(StringRef Input, SourceMgr &, bool ShowColors = true); + Stream(StringRef Input, SourceMgr &, bool ShowColors = true, std::error_code* EC = nullptr); - Stream(MemoryBufferRef InputBuffer, SourceMgr &, bool ShowColors = true); + Stream(MemoryBufferRef InputBuffer, SourceMgr &, bool ShowColors = true, std::error_code* EC = nullptr); ~Stream(); document_iterator begin(); Index: lib/Support/YAMLParser.cpp =================================================================== --- lib/Support/YAMLParser.cpp +++ lib/Support/YAMLParser.cpp @@ -232,8 +232,8 @@ /// @brief Scans YAML tokens from a MemoryBuffer. class Scanner { public: - Scanner(StringRef Input, SourceMgr &SM, bool ShowColors = true); - Scanner(MemoryBufferRef Buffer, SourceMgr &SM_, bool ShowColors = true); + Scanner(StringRef Input, SourceMgr &SM, bool ShowColors = true, std::error_code *EC = nullptr); + Scanner(MemoryBufferRef Buffer, SourceMgr &SM_, bool ShowColors = true, std::error_code *EC = nullptr); /// @brief Parse the next token and return it without popping it. Token &peekNext(); @@ -250,11 +250,16 @@ if (Current >= End) Current = End - 1; + // propagate the error if possible + if(EC) + *EC = make_error_code(std::errc::invalid_argument); + // Don't print out more errors after the first one we encounter. The rest // are just the result of the first, and have no meaning. if (!Failed) printError(SMLoc::getFromPointer(Current), SourceMgr::DK_Error, Message); Failed = true; + } void setError(const Twine &Message) { @@ -528,6 +533,8 @@ /// @brief Potential simple keys. SmallVector SimpleKeys; + + std::error_code *EC; }; } // end namespace yaml @@ -722,13 +729,13 @@ return EscapedInput; } -Scanner::Scanner(StringRef Input, SourceMgr &sm, bool ShowColors) - : SM(sm), ShowColors(ShowColors) { +Scanner::Scanner(StringRef Input, SourceMgr &sm, bool ShowColors, std::error_code *EC) + : SM(sm), ShowColors(ShowColors), EC(EC) { init(MemoryBufferRef(Input, "YAML")); } -Scanner::Scanner(MemoryBufferRef Buffer, SourceMgr &SM_, bool ShowColors) - : SM(SM_), ShowColors(ShowColors) { +Scanner::Scanner(MemoryBufferRef Buffer, SourceMgr &SM_, bool ShowColors, std::error_code *EC) + : SM(SM_), ShowColors(ShowColors), EC(EC) { init(Buffer); } @@ -1726,11 +1733,11 @@ return false; } -Stream::Stream(StringRef Input, SourceMgr &SM, bool ShowColors) - : scanner(new Scanner(Input, SM, ShowColors)), CurrentDoc() {} +Stream::Stream(StringRef Input, SourceMgr &SM, bool ShowColors, std::error_code *EC) + : scanner(new Scanner(Input, SM, ShowColors, EC)), CurrentDoc() {} -Stream::Stream(MemoryBufferRef InputBuffer, SourceMgr &SM, bool ShowColors) - : scanner(new Scanner(InputBuffer, SM, ShowColors)), CurrentDoc() {} +Stream::Stream(MemoryBufferRef InputBuffer, SourceMgr &SM, bool ShowColors, std::error_code *EC) + : scanner(new Scanner(InputBuffer, SM, ShowColors, EC)), CurrentDoc() {} Stream::~Stream() {} @@ -1741,6 +1748,7 @@ , SourceMgr::DK_Error , Msg , N->getSourceRange()); + } document_iterator Stream::begin() { Index: lib/Support/YAMLTraits.cpp =================================================================== --- lib/Support/YAMLTraits.cpp +++ lib/Support/YAMLTraits.cpp @@ -49,7 +49,7 @@ SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt) : IO(Ctxt), - Strm(new Stream(InputContent, SrcMgr)), + Strm(new Stream(InputContent, SrcMgr, false, &EC)), CurrentNode(nullptr) { if (DiagHandler) SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt); Index: unittests/Support/YAMLIOTest.cpp =================================================================== --- unittests/Support/YAMLIOTest.cpp +++ unittests/Support/YAMLIOTest.cpp @@ -2368,3 +2368,11 @@ out); out.clear(); } + +TEST(YAMLIO, InvalidInput) { + // polluting 1 value in the sequence + Input yin("---\n- foo: 3\n bar: 5\n1\n- foo: 3\n bar: 5\n...\n"); + std::vector Data; + yin >> Data; + EXPECT_TRUE((bool)yin.error()); +}