llvm.org GIT mirror llvm / 6919bec
Recover gracefully when deserializing invalid YAML input. Fixes http://llvm.org/PR16221, http://llvm.org/PR15927 Phabricator: http://llvm-reviews.chandlerc.com/D1236 Patch by Andrew Tulloch! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195016 91177308-0d34-0410-b5e6-96231b3b80d8 Alexander Kornienko 5 years ago
3 changed file(s) with 157 addition(s) and 66 deletion(s). Raw diff Collapse all Expand all
684684 ///
685685 class Input : public IO {
686686 public:
687 // Construct a yaml Input object from a StringRef and optional user-data.
688 Input(StringRef InputContent, void *Ctxt=NULL);
687 // Construct a yaml Input object from a StringRef and optional
688 // user-data. The DiagHandler can be specified to provide
689 // alternative error reporting.
690 Input(StringRef InputContent,
691 void *Ctxt = NULL,
692 SourceMgr::DiagHandlerTy DiagHandler = NULL,
693 void *DiagHandlerCtxt = NULL);
689694 ~Input();
690
695
691696 // Check if there was an syntax or semantic error during parsing.
692697 llvm::error_code error();
693
694 // To set alternate error reporting.
695 void setDiagHandler(llvm::SourceMgr::DiagHandlerTy Handler, void *Ctxt = 0);
696698
697699 static bool classof(const IO *io) { return !io->outputting(); }
698700
967969 inline
968970 typename llvm::enable_if_c::value,Input &>::type
969971 operator>>(Input &yin, T &docSeq) {
970 yin.setCurrentDocument();
971 yamlize(yin, docSeq, true);
972 if (yin.setCurrentDocument())
973 yamlize(yin, docSeq, true);
972974 return yin;
973975 }
974976
4040 // Input
4141 //===----------------------------------------------------------------------===//
4242
43 Input::Input(StringRef InputContent, void *Ctxt)
43 Input::Input(StringRef InputContent,
44 void *Ctxt,
45 SourceMgr::DiagHandlerTy DiagHandler,
46 void *DiagHandlerCtxt)
4447 : IO(Ctxt),
4548 Strm(new Stream(InputContent, SrcMgr)),
4649 CurrentNode(NULL) {
50 if (DiagHandler)
51 SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
4752 DocIterator = Strm->begin();
4853 }
4954
5257
5358 error_code Input::error() {
5459 return EC;
55 }
56
57 void Input::setDiagHandler(SourceMgr::DiagHandlerTy Handler, void *Ctxt) {
58 SrcMgr.setDiagHandler(Handler, Ctxt);
5960 }
6061
6162 bool Input::outputting() const {
6566 bool Input::setCurrentDocument() {
6667 if (DocIterator != Strm->end()) {
6768 Node *N = DocIterator->getRoot();
69 if (!N) {
70 assert(Strm->failed() && "Root is NULL iff parsing failed");
71 EC = make_error_code(errc::invalid_argument);
72 return false;
73 }
74
6875 if (isa(N)) {
6976 // Empty files are allowed and ignored
7077 ++DocIterator;
94101 void Input::beginMapping() {
95102 if (EC)
96103 return;
97 MapHNode *MN = dyn_cast(CurrentNode);
104 // CurrentNode can be null if the document is empty.
105 MapHNode *MN = dyn_cast_or_null(CurrentNode);
98106 if (MN) {
99107 MN->ValidKeys.clear();
100108 }
105113 UseDefault = false;
106114 if (EC)
107115 return false;
116
117 // CurrentNode is null for empty documents, which is an error in case required
118 // nodes are present.
119 if (!CurrentNode) {
120 if (Required)
121 EC = make_error_code(errc::invalid_argument);
122 return false;
123 }
124
108125 MapHNode *MN = dyn_cast(CurrentNode);
109126 if (!MN) {
110127 setError(CurrentNode, "not a mapping");
131148 void Input::endMapping() {
132149 if (EC)
133150 return;
134 MapHNode *MN = dyn_cast(CurrentNode);
151 // CurrentNode can be null if the document is empty.
152 MapHNode *MN = dyn_cast_or_null(CurrentNode);
135153 if (!MN)
136154 return;
137155 for (MapHNode::NameToNode::iterator i = MN->Mapping.begin(),
272290 }
273291
274292 void Input::setError(HNode *hnode, const Twine &message) {
293 assert(hnode && "HNode must not be NULL");
275294 this->setError(hnode->_node, message);
276295 }
277296
5757 //
5858 TEST(YAMLIO, TestMapRead) {
5959 FooBar doc;
60 Input yin("---\nfoo: 3\nbar: 5\n...\n");
61 yin >> doc;
62
63 EXPECT_FALSE(yin.error());
64 EXPECT_EQ(doc.foo, 3);
65 EXPECT_EQ(doc.bar,5);
66 }
67
60 {
61 Input yin("---\nfoo: 3\nbar: 5\n...\n");
62 yin >> doc;
63
64 EXPECT_FALSE(yin.error());
65 EXPECT_EQ(doc.foo, 3);
66 EXPECT_EQ(doc.bar, 5);
67 }
68
69 {
70 Input yin("{foo: 3, bar: 5}");
71 yin >> doc;
72
73 EXPECT_FALSE(yin.error());
74 EXPECT_EQ(doc.foo, 3);
75 EXPECT_EQ(doc.bar, 5);
76 }
77 }
6878
6979 //
7080 // Test the reading of a yaml sequence of mappings
11631173 "c1: blue\n"
11641174 "c2: purple\n"
11651175 "c3: green\n"
1166 "...\n");
1167 yin.setDiagHandler(suppressErrorMessages);
1176 "...\n",
1177 /*Ctxt=*/NULL,
1178 suppressErrorMessages);
11681179 yin >> map;
11691180 EXPECT_TRUE(yin.error());
11701181 }
11791190 "f1: [ big ]\n"
11801191 "f2: [ round, hollow ]\n"
11811192 "f3: []\n"
1182 "...\n");
1183 yin.setDiagHandler(suppressErrorMessages);
1193 "...\n",
1194 /*Ctxt=*/NULL,
1195 suppressErrorMessages);
11841196 yin >> map;
11851197
11861198 EXPECT_TRUE(yin.error());
11971209 "- 255\n"
11981210 "- 0\n"
11991211 "- 257\n"
1200 "...\n");
1201 yin.setDiagHandler(suppressErrorMessages);
1212 "...\n",
1213 /*Ctxt=*/NULL,
1214 suppressErrorMessages);
12021215 yin >> seq;
12031216
12041217 EXPECT_TRUE(yin.error());
12151228 "- 65535\n"
12161229 "- 0\n"
12171230 "- 66000\n"
1218 "...\n");
1219 yin.setDiagHandler(suppressErrorMessages);
1231 "...\n",
1232 /*Ctxt=*/NULL,
1233 suppressErrorMessages);
12201234 yin >> seq;
12211235
12221236 EXPECT_TRUE(yin.error());
12331247 "- 4000000000\n"
12341248 "- 0\n"
12351249 "- 5000000000\n"
1236 "...\n");
1237 yin.setDiagHandler(suppressErrorMessages);
1250 "...\n",
1251 /*Ctxt=*/NULL,
1252 suppressErrorMessages);
12381253 yin >> seq;
12391254
12401255 EXPECT_TRUE(yin.error());
12511266 "- 18446744073709551615\n"
12521267 "- 0\n"
12531268 "- 19446744073709551615\n"
1254 "...\n");
1255 yin.setDiagHandler(suppressErrorMessages);
1269 "...\n",
1270 /*Ctxt=*/NULL,
1271 suppressErrorMessages);
12561272 yin >> seq;
12571273
12581274 EXPECT_TRUE(yin.error());
12701286 "- 0\n"
12711287 "- 127\n"
12721288 "- 128\n"
1273 "...\n");
1274 yin.setDiagHandler(suppressErrorMessages);
1289 "...\n",
1290 /*Ctxt=*/NULL,
1291 suppressErrorMessages);
12751292 yin >> seq;
12761293
12771294 EXPECT_TRUE(yin.error());
12871304 "- 0\n"
12881305 "- 127\n"
12891306 "- -129\n"
1290 "...\n");
1291 yin.setDiagHandler(suppressErrorMessages);
1307 "...\n",
1308 /*Ctxt=*/NULL,
1309 suppressErrorMessages);
12921310 yin >> seq;
12931311
12941312 EXPECT_TRUE(yin.error());
13061324 "- 0\n"
13071325 "- -32768\n"
13081326 "- -32769\n"
1309 "...\n");
1310 yin.setDiagHandler(suppressErrorMessages);
1327 "...\n",
1328 /*Ctxt=*/NULL,
1329 suppressErrorMessages);
13111330 yin >> seq;
13121331
13131332 EXPECT_TRUE(yin.error());
13241343 "- 0\n"
13251344 "- -32768\n"
13261345 "- 32768\n"
1327 "...\n");
1328 yin.setDiagHandler(suppressErrorMessages);
1346 "...\n",
1347 /*Ctxt=*/NULL,
1348 suppressErrorMessages);
13291349 yin >> seq;
13301350
13311351 EXPECT_TRUE(yin.error());
13431363 "- 0\n"
13441364 "- -2147483648\n"
13451365 "- -2147483649\n"
1346 "...\n");
1347 yin.setDiagHandler(suppressErrorMessages);
1366 "...\n",
1367 /*Ctxt=*/NULL,
1368 suppressErrorMessages);
13481369 yin >> seq;
13491370
13501371 EXPECT_TRUE(yin.error());
13601381 "- 0\n"
13611382 "- -2147483648\n"
13621383 "- 2147483649\n"
1363 "...\n");
1364 yin.setDiagHandler(suppressErrorMessages);
1384 "...\n",
1385 /*Ctxt=*/NULL,
1386 suppressErrorMessages);
13651387 yin >> seq;
13661388
13671389 EXPECT_TRUE(yin.error());
13791401 "- 0\n"
13801402 "- 9223372036854775807\n"
13811403 "- -9223372036854775809\n"
1382 "...\n");
1383 yin.setDiagHandler(suppressErrorMessages);
1404 "...\n",
1405 /*Ctxt=*/NULL,
1406 suppressErrorMessages);
13841407 yin >> seq;
13851408
13861409 EXPECT_TRUE(yin.error());
13961419 "- 0\n"
13971420 "- 9223372036854775807\n"
13981421 "- 9223372036854775809\n"
1399 "...\n");
1400 yin.setDiagHandler(suppressErrorMessages);
1422 "...\n",
1423 /*Ctxt=*/NULL,
1424 suppressErrorMessages);
14011425 yin >> seq;
14021426
14031427 EXPECT_TRUE(yin.error());
14141438 "- 1000.1\n"
14151439 "- -123.456\n"
14161440 "- 1.2.3\n"
1417 "...\n");
1418 yin.setDiagHandler(suppressErrorMessages);
1441 "...\n",
1442 /*Ctxt=*/NULL,
1443 suppressErrorMessages);
14191444 yin >> seq;
14201445
14211446 EXPECT_TRUE(yin.error());
14321457 "- 1000.1\n"
14331458 "- -123.456\n"
14341459 "- 1.2.3\n"
1435 "...\n");
1436 yin.setDiagHandler(suppressErrorMessages);
1460 "...\n",
1461 /*Ctxt=*/NULL,
1462 suppressErrorMessages);
14371463 yin >> seq;
14381464
14391465 EXPECT_TRUE(yin.error());
14491475 "- 0x12\n"
14501476 "- 0xFE\n"
14511477 "- 0x123\n"
1452 "...\n");
1453 yin.setDiagHandler(suppressErrorMessages);
1478 "...\n",
1479 /*Ctxt=*/NULL,
1480 suppressErrorMessages);
14541481 yin >> seq;
14551482
14561483 EXPECT_TRUE(yin.error());
14671494 "- 0x0012\n"
14681495 "- 0xFEFF\n"
14691496 "- 0x12345\n"
1470 "...\n");
1471 yin.setDiagHandler(suppressErrorMessages);
1497 "...\n",
1498 /*Ctxt=*/NULL,
1499 suppressErrorMessages);
14721500 yin >> seq;
14731501
14741502 EXPECT_TRUE(yin.error());
14841512 "- 0x0012\n"
14851513 "- 0xFEFF0000\n"
14861514 "- 0x1234556789\n"
1487 "...\n");
1488 yin.setDiagHandler(suppressErrorMessages);
1515 "...\n",
1516 /*Ctxt=*/NULL,
1517 suppressErrorMessages);
14891518 yin >> seq;
14901519
14911520 EXPECT_TRUE(yin.error());
15011530 "- 0x0012\n"
15021531 "- 0xFFEEDDCCBBAA9988\n"
15031532 "- 0x12345567890ABCDEF0\n"
1504 "...\n");
1505 yin.setDiagHandler(suppressErrorMessages);
1506 yin >> seq;
1507
1508 EXPECT_TRUE(yin.error());
1533 "...\n",
1534 /*Ctxt=*/NULL,
1535 suppressErrorMessages);
1536 yin >> seq;
1537
1538 EXPECT_TRUE(yin.error());
1539 }
1540
1541 TEST(YAMLIO, TestMalformedMapFailsGracefully) {
1542 FooBar doc;
1543 {
1544 // We pass the suppressErrorMessages handler to handle the error
1545 // message generated in the constructor of Input.
1546 Input yin("{foo:3, bar: 5}", /*Ctxt=*/NULL, suppressErrorMessages);
1547 yin >> doc;
1548 EXPECT_TRUE(yin.error());
1549 }
1550
1551 {
1552 Input yin("---\nfoo:3\nbar: 5\n...\n", /*Ctxt=*/NULL, suppressErrorMessages);
1553 yin >> doc;
1554 EXPECT_TRUE(yin.error());
1555 }
15091556 }
15101557
15111558 struct OptionalTest {
15711618
15721619 EXPECT_TRUE(Seq2.Tests[3].Numbers.empty());
15731620 }
1621
1622 TEST(YAMLIO, TestEmptyStringFailsForMapWithRequiredFields) {
1623 FooBar doc;
1624 Input yin("");
1625 yin >> doc;
1626 EXPECT_TRUE(yin.error());
1627 }
1628
1629 TEST(YAMLIO, TestEmptyStringSucceedsForMapWithOptionalFields) {
1630 OptionalTest doc;
1631 Input yin("");
1632 yin >> doc;
1633 EXPECT_FALSE(yin.error());
1634 }
1635
1636 TEST(YAMLIO, TestEmptyStringSucceedsForSequence) {
1637 std::vector seq;
1638 Input yin("", /*Ctxt=*/NULL, suppressErrorMessages);
1639 yin >> seq;
1640
1641 EXPECT_FALSE(yin.error());
1642 EXPECT_TRUE(seq.empty());
1643 }