Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XML parse broken after upgrading to 0.27 #531

Closed
Xuanwo opened this issue Dec 26, 2022 · 3 comments
Closed

XML parse broken after upgrading to 0.27 #531

Xuanwo opened this issue Dec 26, 2022 · 3 comments
Labels
arrays Issues related to mapping XML content onto arrays using serde bug serde Issues related to mapping from Rust types to XML

Comments

@Xuanwo
Copy link

Xuanwo commented Dec 26, 2022

In apache/opendal#1101, some XML related test failed after upgrading to 0.27.

Cases

quick-xml = { version = "0.27", features = ["serialize", "overlapped-lists"] }
use quick_xml::de;
use serde::Deserialize;

#[derive(Default, Debug, Deserialize)]
#[serde(default, rename_all = "PascalCase")]
struct Output {
    name: String,
    prefix: String,
    contents: Vec<Content>,
    common_prefixes: Option<Vec<CommonPrefix>>,
    marker: String,
    next_marker: Option<String>,
}

#[derive(Default, Debug, Deserialize)]
#[serde(default, rename_all = "PascalCase")]
struct CommonPrefix {
    prefix: String,
}

#[derive(Default, Debug, Deserialize)]
#[serde(default, rename_all = "PascalCase")]
struct Content {
    key: String,
    size: u64,
}

#[cfg(test)]
mod tests {
    use bytes::Buf;

    use super::*;

    #[test]
    fn test_parse_xml() {
        let bs = bytes::Bytes::from(
            r#"<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ListBucketResult xmlns="http://obs.cn-north-4.myhuaweicloud.com/doc/2015-06-30/">
    <Name>examplebucket</Name>
    <Prefix>obj</Prefix>
    <Marker>obj002</Marker>
    <NextMarker>obj004</NextMarker>
    <MaxKeys>1000</MaxKeys>
    <IsTruncated>false</IsTruncated>
    <Contents>
        <Key>obj002</Key>
        <LastModified>2015-07-01T02:11:19.775Z</LastModified>
        <ETag>"a72e382246ac83e86bd203389849e71d"</ETag>
        <Size>9</Size>
        <Owner>
            <ID>b4bf1b36d9ca43d984fbcb9491b6fce9</ID>
        </Owner>
        <StorageClass>STANDARD</StorageClass>
    </Contents>
    <Contents>
        <Key>obj003</Key>
        <LastModified>2015-07-01T02:11:19.775Z</LastModified>
        <ETag>"a72e382246ac83e86bd203389849e71d"</ETag>
        <Size>10</Size>
        <Owner>
            <ID>b4bf1b36d9ca43d984fbcb9491b6fce9</ID>
        </Owner>
        <StorageClass>STANDARD</StorageClass>
    </Contents>
    <CommonPrefixes>
        <Prefix>hello</Prefix>
    </CommonPrefixes>
    <CommonPrefixes>
        <Prefix>world</Prefix>
    </CommonPrefixes>
</ListBucketResult>"#,
        );
        let out: Output = de::from_reader(bs.reader()).expect("must success");

        assert_eq!(out.name, "examplebucket".to_string());
        assert_eq!(out.prefix, "obj".to_string());
        assert_eq!(out.marker, "obj002".to_string());
        assert_eq!(out.next_marker, Some("obj004".to_string()),);
        assert_eq!(
            out.contents
                .iter()
                .map(|v| v.key.clone())
                .collect::<Vec<String>>(),
            ["obj002", "obj003"],
        );
        assert_eq!(
            out.contents.iter().map(|v| v.size).collect::<Vec<u64>>(),
            [9, 10],
        );
        assert_eq!(
            out.common_prefixes
                .unwrap()
                .iter()
                .map(|v| v.prefix.clone())
                .collect::<Vec<String>>(),
            ["hello", "world"],
        )
    }
}

Errors:

running 1 test
thread 'services::obs::dir_stream::tests::test_parse_xml' panicked at 'must success: UnexpectedEnd([76, 105, 115, 116, 66, 117, 99, 107, 101, 116, 82, 101, 115, 117, 108, 116])', src/services/obs/dir_stream.rs:179:56
stack backtrace:
   0: rust_begin_unwind
             at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/result.rs:1785:5
   3: core::result::Result<T,E>::expect
             at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/result.rs:1064:23
   4: opendal::services::obs::dir_stream::tests::test_parse_xml
             at ./src/services/obs/dir_stream.rs:179:27
   5: opendal::services::obs::dir_stream::tests::test_parse_xml::{{closure}}
             at ./src/services/obs/dir_stream.rs:141:5
   6: core::ops::function::FnOnce::call_once
             at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/ops/function.rs:248:5
   7: core::ops::function::FnOnce::call_once
             at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
test services::obs::dir_stream::tests::test_parse_xml ... FAILED

failures:

failures:
    services::obs::dir_stream::tests::test_parse_xml

Maybe this bug also related to #530?

@Mingun Mingun added bug serde Issues related to mapping from Rust types to XML arrays Issues related to mapping XML content onto arrays using serde labels Dec 26, 2022
@Mingun
Copy link
Collaborator

Mingun commented Dec 26, 2022

No, this is duplicate of #510. As a workaround you could replace

common_prefixes: Option<Vec<CommonPrefix>>,

by

#[serde(default)] // Actually not needed because all your struct is serde(default)
common_prefixes: Vec<CommonPrefix>,

Probably this also would be a more convenient API, but if not, you could use #[serde(deserialize_with = "optional_vec")] (not tested):

fn optional_vec<'de, D, T>(deserializer: D) -> Result<Option<Vec<T>>, D::Error>
where
    D: Deserializer<'de>,
    T: Deserialize<'de>,
{
    let list = Vec::<T>::deserialize(deserializer)?;
    Ok(if list.is_empty() { None } else { Some(list) })
}

So I close this as duplicate.

@Mingun Mingun closed this as not planned Won't fix, can't repro, duplicate, stale Dec 26, 2022
@Xuanwo
Copy link
Author

Xuanwo commented Dec 26, 2022

Ok, please also include this issue in the breaking changes docs. Because this used to work in old versions.

I'm willing to send a PR for this, WDYT?

@Mingun
Copy link
Collaborator

Mingun commented Dec 26, 2022

I would be glad if you do that.

Xuanwo added a commit to Xuanwo/quick-xml that referenced this issue Dec 26, 2022
Signed-off-by: Xuanwo <github@xuanwo.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arrays Issues related to mapping XML content onto arrays using serde bug serde Issues related to mapping from Rust types to XML
Projects
None yet
Development

No branches or pull requests

2 participants