Skip to content
This repository has been archived by the owner on May 6, 2020. It is now read-only.

Deserialization fails on ignored tags with attributes #37

Open
marcusball opened this issue Feb 10, 2017 · 1 comment
Open

Deserialization fails on ignored tags with attributes #37

marcusball opened this issue Feb 10, 2017 · 1 comment
Labels

Comments

@marcusball
Copy link

marcusball commented Feb 10, 2017

Deserialization appears to fail for ignored tags that contain attributes.

Here's a full example:

[dependencies]
serde = "0.8"
serde_derive = "0.8"
serde_xml = "0.9.1"
#![feature(proc_macro)]

extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_xml;
#[derive(Deserialize, Debug)]
struct Project {
    #[serde(rename = "ItemGroup")]
    groups: Vec<ItemGroup>,
}

#[derive(Deserialize, Debug)]
struct ItemGroup {
    #[serde(rename = "ClCompile")]
    source_files: Vec<ClCompile>,
}

#[derive(Deserialize, Debug)]
struct ClCompile {
    #[serde(rename = "Include")]
    include: String,
}


fn main() {}

#[cfg(test)]
mod tests {
    use super::*;
    use serde;
    use serde_xml;


    #[test]
    fn read_with_project_configurations() {
        #[cfg_attr(rustfmt, rustfmt_skip)]
        let basic_project = " \
            <?xml version=\"1.0\" encoding=\"utf-8\"?> \
            <Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"> \
                <ItemGroup Label=\"ProjectConfigurations\"> \
                    <ProjectConfiguration> \
                    </ProjectConfiguration> \
                </ItemGroup> \
                <ItemGroup> \
                    <ClCompile Include=\"..\\my_src\\example.cpp\" /> \
                </ItemGroup> \
            </Project>";

        let project: Project = serde_xml::from_str(basic_project).unwrap();

        assert!(project.groups.len() == 2);
    }

    #[test]
    fn read_with_project_configurations_attribute() {
        #[cfg_attr(rustfmt, rustfmt_skip)]
        let basic_project = " \
            <?xml version=\"1.0\" encoding=\"utf-8\"?> \
            <Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"> \
                <ItemGroup Label=\"ProjectConfigurations\"> \
                    <ProjectConfiguration Include=\"Debug|Win32\"> \
                    </ProjectConfiguration> \
                </ItemGroup> \
                <ItemGroup> \
                    <ClCompile Include=\"..\\my_src\\example.cpp\" /> \
                </ItemGroup> \
            </Project>";

        let project: Project = serde_xml::from_str(basic_project).unwrap();

        assert!(project.groups.len() == 2);
    }
}

The first test will pass; the second will fail to parse. The only difference between the two is <ProjectConfiguration> in the first, and <ProjectConfiguration Include=\"Debug|Win32\"> in the latter. Note that in this example, I'm ignoring ProjectConfiguration elements anyway and only trying to parse ClCompile.

The error produced is:

thread 'tests::read_with_project_configurations_attribute' panicked at 'called Result::unwrap() on an Err value: SyntaxError(expected tags or text, 1, 238)', C:\bot\slave\nightly-dist-rustc-win-msvc-64\build\src\libcore\result.rs:868

I added a panic!() to this crate to try to determine the cause; here is the backtrace to the error:

   4:     0x7ff7f5590559 - serde_xml::de::lexer::XmlIterator<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>::error<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>
                        at C:\Users\Marcus\Source\vsproj_parser\<panic macros>:3
   5:     0x7ff7f559078f - serde_xml::de::lexer::XmlIterator<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>::expected<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>
                        at C:\Users\Marcus\Source\serde_xml\src\de\lexer.rs:70
   6:     0x7ff7f55922f7 - serde_xml::de::InnerDeserializer<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>::eat<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:105
   7:     0x7ff7f5582cd0 - serde_xml::de::{{impl}}::deserialize_ignored_any<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,serde::de::impls::{{impl}}::deserialize::IgnoredAnyVisitor>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:141
   8:     0x7ff7f5592f8d - serde::de::impls::{{impl}}::deserialize<serde_xml::de::InnerDeserializer<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>>
                        at C:\Users\Marcus\.cargo\registry\src\github.com-1ecc6299db9ec823\serde-0.8.23\src\de\impls.rs:1304
   9:     0x7ff7f55926c1 - serde_xml::de::InnerDeserializer<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>::decode<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,serde::de::impls::IgnoredAny>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:95
  10:     0x7ff7f55a1054 - serde_xml::de::{{impl}}::visit_value<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,serde::de::impls::IgnoredAny>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:707
  11:     0x7ff7f55ae79f - vsproj_parser::_IMPL_DESERIALIZE_FOR_ItemGroup::{{impl}}::deserialize::{{impl}}::visit_map<serde_xml::de::ContentVisitor<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>>
                        at C:\Users\Marcus\Source\vsproj_parser\src\main.rs:13
  12:     0x7ff7f55824fa - serde_xml::de::{{impl}}::deserialize_map<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,vsproj_parser::_IMPL_DESERIALIZE_FOR_ItemGroup::{{impl}}::deserialize::__Visitor>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:190
  13:     0x7ff7f5582b61 - serde_xml::de::{{impl}}::deserialize_struct<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,vsproj_parser::_IMPL_DESERIALIZE_FOR_ItemGroup::{{impl}}::deserialize::__Visitor>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:45
  14:     0x7ff7f55ae3ea - vsproj_parser::_IMPL_DESERIALIZE_FOR_ItemGroup::{{impl}}::deserialize<serde_xml::de::InnerDeserializer<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>>
                        at C:\Users\Marcus\Source\vsproj_parser\src\main.rs:13
  15:     0x7ff7f5592961 - serde_xml::de::InnerDeserializer<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>::decode<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,vsproj_parser::ItemGroup>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:95
  16:     0x7ff7f5598467 - serde_xml::de::{{impl}}::visit<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,vsproj_parser::ItemGroup>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:775
  17:     0x7ff7f5593740 - serde::de::impls::{{impl}}::visit_seq<vsproj_parser::ItemGroup,serde_xml::de::SeqVisitor<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>>
                        at C:\Users\Marcus\.cargo\registry\src\github.com-1ecc6299db9ec823\serde-0.8.23\src\de\impls.rs:505
  18:     0x7ff7f5582845 - serde_xml::de::{{impl}}::deserialize_seq<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,serde::de::impls::VecVisitor<vsproj_parser::ItemGroup>>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:183
  19:     0x7ff7f55913da - serde::de::impls::{{impl}}::deserialize<vsproj_parser::ItemGroup,serde_xml::de::InnerDeserializer<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>>
                        at C:\Users\Marcus\.cargo\registry\src\github.com-1ecc6299db9ec823\serde-0.8.23\src\de\impls.rs:449
  20:     0x7ff7f55927a1 - serde_xml::de::InnerDeserializer<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>::decode<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,collections::vec::Vec<vsproj_parser::ItemGroup>>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:95
  21:     0x7ff7f559e7d7 - serde_xml::de::{{impl}}::visit_value<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,collections::vec::Vec<vsproj_parser::ItemGroup>>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:707
  22:     0x7ff7f55ad6d8 - vsproj_parser::_IMPL_DESERIALIZE_FOR_Project::{{impl}}::deserialize::{{impl}}::visit_map<serde_xml::de::ContentVisitor<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>>
                        at C:\Users\Marcus\Source\vsproj_parser\src\main.rs:7
  23:     0x7ff7f558235a - serde_xml::de::{{impl}}::deserialize_map<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,vsproj_parser::_IMPL_DESERIALIZE_FOR_Project::{{impl}}::deserialize::__Visitor>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:190
  24:     0x7ff7f5595f11 - serde_xml::de::{{impl}}::deserialize_map<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,vsproj_parser::_IMPL_DESERIALIZE_FOR_Project::{{impl}}::deserialize::__Visitor>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:398
  25:     0x7ff7f5596a11 - serde_xml::de::{{impl}}::deserialize_struct<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,vsproj_parser::_IMPL_DESERIALIZE_FOR_Project::{{impl}}::deserialize::__Visitor>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:45
  26:     0x7ff7f55ad2ca - vsproj_parser::_IMPL_DESERIALIZE_FOR_Project::{{impl}}::deserialize<serde_xml::de::Deserializer<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>>>
                        at C:\Users\Marcus\Source\vsproj_parser\src\main.rs:7
  27:     0x7ff7f55acaa1 - serde_xml::de::from_iter<core::iter::Map<core::str::Bytes, fn(u8) -> core::result::Result<u8, std::io::error::Error>>,vsproj_parser::Project>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:820
  28:     0x7ff7f55ac9f7 - serde_xml::de::from_str<vsproj_parser::Project>
                        at C:\Users\Marcus\Source\serde_xml\src\de\mod.rs:831
  29:     0x7ff7f55ad193 - vsproj_parser::tests::read_with_project_configurations_attribute
                        at C:\Users\Marcus\Source\vsproj_parser\src\main.rs:70
@oli-obk oli-obk added the bug label Feb 11, 2017
@RReverser
Copy link

@marcusball You likely need #[serde(default)]on your collections so that, when tag are not found, it can generate an empty collection instead. At least with that attribute your example parses well with https://github.com/RReverser/serde-xml-rs, and I guess serde-xml uses similar technique.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

No branches or pull requests

3 participants