Skip to content

Commit 9a91306

Browse files
authored
Merge branch 'tafia:master' into derive-implementations
2 parents 8b22cec + 2cedfe1 commit 9a91306

File tree

10 files changed

+1043
-35
lines changed

10 files changed

+1043
-35
lines changed

.github/workflows/cifuzz.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
language: rust
1818
fuzz-seconds: 600
1919
- name: Upload Crash
20-
uses: actions/upload-artifact@v3
20+
uses: actions/upload-artifact@v4
2121
if: failure() && steps.build.outcome == 'success'
2222
with:
2323
name: artifacts

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "quick-xml"
3-
version = "0.37.2"
3+
version = "0.37.3"
44
description = "High performance xml reader and writer"
55
edition = "2021"
66

@@ -231,6 +231,11 @@ name = "serde-de-seq"
231231
required-features = ["serialize"]
232232
path = "tests/serde-de-seq.rs"
233233

234+
[[test]]
235+
name = "serde-de-xsi"
236+
required-features = ["serialize"]
237+
path = "tests/serde-de-xsi.rs"
238+
234239
[[test]]
235240
name = "serde-se"
236241
required-features = ["serialize"]

Changelog.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@
2020
### Misc Changes
2121

2222

23+
## 0.37.3 -- 2025-03-25
24+
25+
### New Features
26+
27+
- [#850]: Add `Attribute::as_bool()` method to get an attribute value as a boolean.
28+
- [#850]: Add `Attributes::has_nil()` method to check if attributes has `xsi:nil` attribute set to `true`.
29+
- [#497]: Handle `xsi:nil` attribute in serde Deserializer to better process optional fields.
30+
31+
[#497]: https://github.com/tafia/quick-xml/issues/497
32+
[#850]: https://github.com/tafia/quick-xml/pull/850
33+
34+
2335
## 0.37.2 -- 2024-12-29
2436

2537
### New Features

src/de/map.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,21 @@ where
215215
has_value_field: fields.contains(&VALUE_KEY),
216216
})
217217
}
218+
219+
/// Determines if subtree started with the specified event shoould be skipped.
220+
///
221+
/// Used to map elements with `xsi:nil` attribute set to true to `None` in optional contexts.
222+
///
223+
/// We need to handle two attributes:
224+
/// - on parent element: <map xsi:nil="true"><foo/></map>
225+
/// - on this element: <map><foo xsi:nil="true"/></map>
226+
///
227+
/// We check parent element too because `xsi:nil` affects only nested elements of the
228+
/// tag where it is defined. We can map structure with fields mapped to attributes to
229+
/// the `<map>` element and set to `None` all its optional elements.
230+
fn should_skip_subtree(&self, start: &BytesStart) -> bool {
231+
self.de.reader.reader.has_nil_attr(&self.start) || self.de.reader.reader.has_nil_attr(start)
232+
}
218233
}
219234

220235
impl<'de, 'd, R, E> MapAccess<'de> for ElementMapAccess<'de, 'd, R, E>
@@ -540,8 +555,14 @@ where
540555
where
541556
V: Visitor<'de>,
542557
{
543-
match self.map.de.peek()? {
558+
// We cannot use result of `peek()` directly because of borrow checker
559+
let _ = self.map.de.peek()?;
560+
match self.map.de.last_peeked() {
544561
DeEvent::Text(t) if t.is_empty() => visitor.visit_none(),
562+
DeEvent::Start(start) if self.map.should_skip_subtree(start) => {
563+
self.map.de.skip_next_tree()?;
564+
visitor.visit_none()
565+
}
545566
_ => visitor.visit_some(self),
546567
}
547568
}

0 commit comments

Comments
 (0)