[PATCH] Detect malformed yaml sequence in yaml::Input::beginSequence()
William Fisher
william.w.fisher at gmail.com
Sun Jan 18 16:25:24 PST 2015
Thanks. I've fixed the suggested lines. Here is the new patch.
On Sat, Jan 17, 2015 at 2:15 PM, Justin Bogner <mail at justinbogner.com> wrote:
> William Fisher <william.w.fisher at gmail.com> writes:
>> When reading a yaml::SequenceTraits object, YAMLIO does report an
>> error if the yaml item is not a sequence. Instead, YAMLIO reads an
>> empty sequence. For example:
>>
>> ---
>> seq:
>> foo: 1
>> bar: 2
>> ...
>>
>> If `seq` is a SequenceTraits object, then reading the above yaml will
>> yield `seq` as an empty sequence. The enclosed patch reports an error
>> for the above mapping ("not a sequence")
>
> LGTM with a couple of nits.
>
>> Null and empty nodes are still interpreted as empty sequences:
>>
>> ---
>> seq1: # Empty node okay
>> ---
>> seq2: null # null okay
>> ...
>>
>> Index: lib/Support/YAMLTraits.cpp
>> ===================================================================
>> --- lib/Support/YAMLTraits.cpp (revision 224940)
>> +++ lib/Support/YAMLTraits.cpp (working copy)
>> @@ -170,7 +170,16 @@
>> unsigned Input::beginSequence() {
>> if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
>> return SQ->Entries.size();
>> + } else if (dyn_cast<EmptyHNode>(CurrentNode)) {
>
> This should be isa<EmptyHNode>(CurrentNode), since we don't use the
> result.
>
>> + return 0;
>> }
>> + // Treat case where there's a scalar "null" value as an empty sequence.
>> + if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
>
> Seems odd to use "else if" above and just "if" here. Better to be
> consistent.
>
>> + if (isNull(SN->value()))
>> + return 0;
>> + }
>> + // Any other type of HNode is an error.
>> + setError(CurrentNode, "not a sequence");
>> return 0;
>> }
>>
>> @@ -193,10 +202,7 @@
>> }
>>
>> unsigned Input::beginFlowSequence() {
>> - if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
>> - return SQ->Entries.size();
>> - }
>> - return 0;
>> + return beginSequence();
>> }
>>
>> bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
>> Index: unittests/Support/YAMLIOTest.cpp
>> ===================================================================
>> --- unittests/Support/YAMLIOTest.cpp (revision 224940)
>> +++ unittests/Support/YAMLIOTest.cpp (working copy)
>> @@ -46,6 +46,9 @@
>>
>> LLVM_YAML_IS_SEQUENCE_VECTOR(FooBar)
>>
>> +struct FooBarContainer {
>> + FooBarSequence fbs;
>> +};
>>
>> namespace llvm {
>> namespace yaml {
>> @@ -56,6 +59,13 @@
>> io.mapRequired("bar", fb.bar);
>> }
>> };
>> +
>> + template <>
>> + struct MappingTraits<FooBarContainer> {
>> + static void mapping(IO &io, FooBarContainer& fb) {
>> + io.mapRequired("fbs", fb.fbs);
>> + }
>> + };
>> }
>> }
>>
>> @@ -109,8 +119,85 @@
>> EXPECT_EQ(map2.bar, 9);
>> }
>>
>> +//
>> +// Test the reading of a map containing a yaml sequence of mappings
>> +//
>> +TEST(YAMLIO, TestContainerSequenceMapRead) {
>> + {
>> + FooBarContainer cont;
>> + Input yin2("---\nfbs:\n - foo: 3\n bar: 5\n - foo: 7\n bar: 9\n...\n");
>> + yin2 >> cont;
>> +
>> + EXPECT_FALSE(yin2.error());
>> + EXPECT_EQ(cont.fbs.size(), 2UL);
>> + EXPECT_EQ(cont.fbs[0].foo, 3);
>> + EXPECT_EQ(cont.fbs[0].bar, 5);
>> + EXPECT_EQ(cont.fbs[1].foo, 7);
>> + EXPECT_EQ(cont.fbs[1].bar, 9);
>> + }
>>
>> + {
>> + FooBarContainer cont;
>> + Input yin("---\nfbs:\n...\n");
>> + yin >> cont;
>> + // Okay: Empty node represents an empty array.
>> + EXPECT_FALSE(yin.error());
>> + EXPECT_EQ(cont.fbs.size(), 0UL);
>> + }
>> +
>> + {
>> + FooBarContainer cont;
>> + Input yin("---\nfbs: !!null null\n...\n");
>> + yin >> cont;
>> + // Okay: null represents an empty array.
>> + EXPECT_FALSE(yin.error());
>> + EXPECT_EQ(cont.fbs.size(), 0UL);
>> + }
>> +
>> + {
>> + FooBarContainer cont;
>> + Input yin("---\nfbs: ~\n...\n");
>> + yin >> cont;
>> + // Okay: null represents an empty array.
>> + EXPECT_FALSE(yin.error());
>> + EXPECT_EQ(cont.fbs.size(), 0UL);
>> + }
>> +
>> + {
>> + FooBarContainer cont;
>> + Input yin("---\nfbs: null\n...\n");
>> + yin >> cont;
>> + // Okay: null represents an empty array.
>> + EXPECT_FALSE(yin.error());
>> + EXPECT_EQ(cont.fbs.size(), 0UL);
>> + }
>> +}
>> +
>> //
>> +// Test the reading of a map containing a malformed yaml sequence
>> +//
>> +TEST(YAMLIO, TestMalformedContainerSequenceMapRead) {
>> + {
>> + FooBarContainer cont;
>> + Input yin("---\nfbs:\n foo: 3\n bar: 5\n...\n", nullptr,
>> + suppressErrorMessages);
>> + yin >> cont;
>> + // Error: fbs is not a sequence.
>> + EXPECT_TRUE(!!yin.error());
>> + EXPECT_EQ(cont.fbs.size(), 0UL);
>> + }
>> +
>> + {
>> + FooBarContainer cont;
>> + Input yin("---\nfbs: 'scalar'\n...\n", nullptr, suppressErrorMessages);
>> + yin >> cont;
>> + // This should be an error.
>> + EXPECT_TRUE(!!yin.error());
>> + EXPECT_EQ(cont.fbs.size(), 0UL);
>> + }
>> +}
>> +
>> +//
>> // Test writing then reading back a sequence of mappings
>> //
>> TEST(YAMLIO, TestSequenceMapWriteAndRead) {
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
-------------- next part --------------
A non-text attachment was scrubbed...
Name: yaml-not-a-seq2.patch
Type: application/octet-stream
Size: 3822 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150118/7ec29d3c/attachment.obj>
More information about the llvm-commits
mailing list