diff options
author | Mehdi Amini <mehdi.amini@apple.com> | 2016-11-28 04:44:13 +0000 |
---|---|---|
committer | Mehdi Amini <mehdi.amini@apple.com> | 2016-11-28 04:44:13 +0000 |
commit | c54281be4f5d948504be604d8b2368e2f495c469 (patch) | |
tree | 6a5ae891c56f010a52c640eab66e637cd7221c85 | |
parent | 4cf2c89883717c481619946c68e14709c9613e90 (diff) | |
download | bcm5719-llvm-c54281be4f5d948504be604d8b2368e2f495c469.tar.gz bcm5719-llvm-c54281be4f5d948504be604d8b2368e2f495c469.zip |
Improve error handling in YAML parsing
Some scanner errors were not checked and reported by the parser.
Fix PR30934
Patch by: Serge Guelton <serge.guelton@telecom-bretagne.eu>
Differential Revision: https://reviews.llvm.org/D26419
llvm-svn: 288014
-rw-r--r-- | llvm/include/llvm/Support/YAMLTraits.h | 1 | ||||
-rw-r--r-- | llvm/lib/Support/YAMLTraits.cpp | 20 | ||||
-rw-r--r-- | llvm/unittests/Support/YAMLIOTest.cpp | 8 |
3 files changed, 20 insertions, 9 deletions
diff --git a/llvm/include/llvm/Support/YAMLTraits.h b/llvm/include/llvm/Support/YAMLTraits.h index f38c85af75f..d1dd34aef68 100644 --- a/llvm/include/llvm/Support/YAMLTraits.h +++ b/llvm/include/llvm/Support/YAMLTraits.h @@ -1085,6 +1085,7 @@ private: void scalarString(StringRef &, bool) override; void blockScalarString(StringRef &) override; void setError(const Twine &message) override; + bool hasError() const; bool canElideEmptySequence() override; class HNode { diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp index 75fac20a8ed..ccd0f45a514 100644 --- a/llvm/lib/Support/YAMLTraits.cpp +++ b/llvm/lib/Support/YAMLTraits.cpp @@ -112,7 +112,7 @@ bool Input::mapTag(StringRef Tag, bool Default) { } void Input::beginMapping() { - if (EC) + if (hasError()) return; // CurrentNode can be null if the document is empty. MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode); @@ -124,7 +124,7 @@ void Input::beginMapping() { bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault, void *&SaveInfo) { UseDefault = false; - if (EC) + if (hasError()) return false; // CurrentNode is null for empty documents, which is an error in case required @@ -159,7 +159,7 @@ void Input::postflightKey(void *saveInfo) { } void Input::endMapping() { - if (EC) + if (hasError()) return; // CurrentNode can be null if the document is empty. MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode); @@ -196,7 +196,7 @@ void Input::endSequence() { } bool Input::preflightElement(unsigned Index, void *&SaveInfo) { - if (EC) + if (hasError()) return false; if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { SaveInfo = CurrentNode; @@ -213,7 +213,7 @@ void Input::postflightElement(void *SaveInfo) { unsigned Input::beginFlowSequence() { return beginSequence(); } bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) { - if (EC) + if (hasError()) return false; if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { SaveInfo = CurrentNode; @@ -271,7 +271,7 @@ bool Input::beginBitSetScalar(bool &DoClear) { } bool Input::bitSetMatch(const char *Str, bool) { - if (EC) + if (hasError()) return false; if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { unsigned Index = 0; @@ -293,7 +293,7 @@ bool Input::bitSetMatch(const char *Str, bool) { } void Input::endBitSetScalar() { - if (EC) + if (hasError()) return; if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { assert(BitValuesUsed.size() == SQ->Entries.size()); @@ -321,6 +321,8 @@ void Input::setError(HNode *hnode, const Twine &message) { this->setError(hnode->_node, message); } +bool Input::hasError() const { return EC || Strm->failed(); } + void Input::setError(Node *node, const Twine &message) { Strm->printError(node, message); EC = make_error_code(errc::invalid_argument); @@ -342,7 +344,7 @@ std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) { auto SQHNode = llvm::make_unique<SequenceHNode>(N); for (Node &SN : *SQ) { auto Entry = this->createHNodes(&SN); - if (EC) + if (hasError()) break; SQHNode->Entries.push_back(std::move(Entry)); } @@ -363,7 +365,7 @@ std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) { KeyStr = StringStorage.str().copy(StringAllocator); } auto ValueHNode = this->createHNodes(KVN.getValue()); - if (EC) + if (hasError()) break; mapHNode->Mapping[KeyStr] = std::move(ValueHNode); } diff --git a/llvm/unittests/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp index bf70e749b4f..c3e18d33235 100644 --- a/llvm/unittests/Support/YAMLIOTest.cpp +++ b/llvm/unittests/Support/YAMLIOTest.cpp @@ -2368,3 +2368,11 @@ TEST(YAMLIO, TestMapWithContext) { 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<FooBar> Data; + yin >> Data; + EXPECT_TRUE((bool)yin.error()); +} |