Skip to content

Commit 5d39f4b

Browse files
committed
ns: Fix bug when not declared prefix resolved to a not bound namespace
Add `ResolveResult` with results of namespace resolution and replace two-state `Option<Namespace>` with three-state `ResolveResult`. Since now in that cases `ResolveResult::Unknown` is returned, which can be converted to an `Error::UnknownPrefix` using `TryInto<Option<Namespace>>`
1 parent 14a8ce0 commit 5d39f4b

File tree

7 files changed

+197
-94
lines changed

7 files changed

+197
-94
lines changed

Changelog.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
- [#387]: Allow overlapping between elements of sequence and other elements
1616
(using new feature `overlapped-lists`)
1717
- [#393]: New module `name` with `QName`, `LocalName`, `Namespace`, and `Prefix`
18-
wrappers around byte arrays
18+
wrappers around byte arrays and `ResolveResult` with the result of prefix
19+
resolution to namespace
1920

2021
### Bug Fixes
2122

@@ -25,6 +26,8 @@
2526
- [#387]: Internal deserializer state can be broken when deserializing a map with
2627
a sequence field (such as `Vec<T>`), where elements of this sequence contains
2728
another sequence. This error affects only users with the `serialize` feature enabled
29+
- [#393]: Now `event_namespace`, `attribute_namespace` and `read_event_namespaced`
30+
returns `ResolveResult::Unknown` if prefix was not registered in namespace buffer
2831

2932
### Misc Changes
3033

@@ -45,7 +48,8 @@
4548
- [#391]: Added code coverage
4649

4750
- [#393]: `event_namespace` and `attribute_namespace` now accept `QName`
48-
and returns `Namespace` and `LocalName`
51+
and returns `ResolveResult` and `LocalName`, `read_event_namespaced` now
52+
returns `ResolveResult` instead of `Option<[u8]>`
4953

5054
### New Tests
5155

examples/issue68.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use quick_xml::events::Event;
44
use quick_xml::name::Namespace;
55
use quick_xml::Reader;
6+
use std::convert::TryFrom;
67
use std::io::Read;
78

89
struct Resource {
@@ -83,7 +84,9 @@ fn parse_report(xml_data: &str) -> Vec<Resource> {
8384
loop {
8485
match reader.read_namespaced_event(&mut buf, &mut ns_buffer) {
8586
Ok((namespace_value, Event::Start(e))) => {
86-
let namespace_value = namespace_value.unwrap_or(Namespace(b""));
87+
let namespace_value = Option::<Namespace>::try_from(namespace_value)
88+
.unwrap_or_default() // Treat unknown prefixes as not bound to any namespace
89+
.unwrap_or(Namespace(b""));
8790
match (depth, state, namespace_value.as_ref(), e.local_name()) {
8891
(0, State::Root, b"DAV:", b"multistatus") => state = State::MultiStatus,
8992
(1, State::MultiStatus, b"DAV:", b"response") => {
@@ -98,7 +101,9 @@ fn parse_report(xml_data: &str) -> Vec<Resource> {
98101
depth += 1;
99102
}
100103
Ok((namespace_value, Event::End(e))) => {
101-
let namespace_value = namespace_value.unwrap_or(Namespace(b""));
104+
let namespace_value = Option::<Namespace>::try_from(namespace_value)
105+
.unwrap_or_default() // Treat unknown prefixes as not bound to any namespace
106+
.unwrap_or(Namespace(b""));
102107
let local_name = e.local_name();
103108
match (depth, state, namespace_value.as_ref(), local_name) {
104109
(1, State::MultiStatus, b"DAV:", b"multistatus") => state = State::Root,

src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use crate::escape::EscapeError;
44
use crate::events::attributes::AttrError;
5+
use crate::utils::write_byte_string;
56
use std::str::Utf8Error;
67

78
/// The error type used by this crate.
@@ -32,6 +33,8 @@ pub enum Error {
3233
InvalidAttr(AttrError),
3334
/// Escape error
3435
EscapeError(EscapeError),
36+
/// Specified namespace prefix is unknown, cannot resolve namespace for it
37+
UnknownPrefix(Vec<u8>),
3538
}
3639

3740
impl From<::std::io::Error> for Error {
@@ -93,6 +96,11 @@ impl std::fmt::Display for Error {
9396
),
9497
Error::InvalidAttr(e) => write!(f, "error while parsing attribute: {}", e),
9598
Error::EscapeError(e) => write!(f, "{}", e),
99+
Error::UnknownPrefix(prefix) => {
100+
f.write_str("Unknown namespace prefix '")?;
101+
write_byte_string(f, &prefix)?;
102+
f.write_str("'")
103+
}
96104
}
97105
}
98106
}

0 commit comments

Comments
 (0)