[PATCH] [YAML] Recover gracefully when deserializing invalid YAML input.
Andrew Tulloch
andrew at tullo.ch
Thu Aug 1 22:27:27 PDT 2013
Cleaned up control flow somewhat.
Hi gribozavr, kledzik, rsmith, bkramer,
http://llvm-reviews.chandlerc.com/D1236
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1236?vs=3097&id=3142#toc
Files:
include/llvm/Support/YAMLTraits.h
lib/Support/YAMLTraits.cpp
unittests/Support/YAMLIOTest.cpp
Index: include/llvm/Support/YAMLTraits.h
===================================================================
--- include/llvm/Support/YAMLTraits.h
+++ include/llvm/Support/YAMLTraits.h
@@ -956,8 +956,8 @@
inline
typename llvm::enable_if_c<has_MappingTraits<T>::value,Input &>::type
operator>>(Input &yin, T &docMap) {
- yin.setCurrentDocument();
- yamlize(yin, docMap, true);
+ if (yin.setCurrentDocument())
+ yamlize(yin, docMap, true);
return yin;
}
@@ -967,8 +967,8 @@
inline
typename llvm::enable_if_c<has_SequenceTraits<T>::value,Input &>::type
operator>>(Input &yin, T &docSeq) {
- yin.setCurrentDocument();
- yamlize(yin, docSeq, true);
+ if (yin.setCurrentDocument())
+ yamlize(yin, docSeq, true);
return yin;
}
Index: lib/Support/YAMLTraits.cpp
===================================================================
--- lib/Support/YAMLTraits.cpp
+++ lib/Support/YAMLTraits.cpp
@@ -66,6 +66,12 @@
bool Input::setCurrentDocument() {
if (DocIterator != Strm->end()) {
Node *N = DocIterator->getRoot();
+ if (!N) {
+ assert(Strm->failed() && "Root is NULL iff parsing failed");
+ EC = make_error_code(errc::invalid_argument);
+ return false;
+ }
+
if (isa<NullNode>(N)) {
// Empty files are allowed and ignored
++DocIterator;
Index: unittests/Support/YAMLIOTest.cpp
===================================================================
--- unittests/Support/YAMLIOTest.cpp
+++ unittests/Support/YAMLIOTest.cpp
@@ -58,12 +58,23 @@
//
TEST(YAMLIO, TestMapRead) {
FooBar doc;
- Input yin("---\nfoo: 3\nbar: 5\n...\n");
- yin >> doc;
+ {
+ Input yin("---\nfoo: 3\nbar: 5\n...\n");
+ yin >> doc;
- EXPECT_FALSE(yin.error());
- EXPECT_EQ(doc.foo, 3);
- EXPECT_EQ(doc.bar,5);
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(doc.foo, 3);
+ EXPECT_EQ(doc.bar,5);
+ }
+
+ {
+ Input yin("{foo: 3, bar: 5}");
+ yin >> doc;
+
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(doc.foo, 3);
+ EXPECT_EQ(doc.bar,5);
+ }
}
@@ -1297,3 +1308,22 @@
EXPECT_TRUE(yin.error());
}
+//
+// Test error handling with a malformed object
+//
+TEST(YAMLIO, TestMalformedMap) {
+ FooBar doc;
+ {
+ Input yin("{foo:3, bar: 5}");
+ yin.setDiagHandler(suppressErrorMessages);
+ yin >> doc;
+ EXPECT_TRUE(yin.error());
+ }
+
+ {
+ Input yin("---\nfoo:3\nbar: 5\n...\n");
+ yin.setDiagHandler(suppressErrorMessages);
+ yin >> doc;
+ EXPECT_TRUE(yin.error());
+ }
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1236.3.patch
Type: text/x-patch
Size: 2484 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130801/16a2299b/attachment.bin>
More information about the llvm-commits
mailing list