forked from lavina/lavina
xmpp: fix parsing of unknown elements in messages
This commit is contained in:
parent
4621470bde
commit
887fd95194
|
@ -103,14 +103,22 @@ impl<T: FromXml> Parser for MessageParser<T> {
|
|||
Continuation::Final(Err(ffail!("Expected start")))
|
||||
}
|
||||
}
|
||||
Outer(state) => match event {
|
||||
Outer(mut state) => match event {
|
||||
Event::Start(ref bytes) => {
|
||||
if bytes.name().0 == b"subject" {
|
||||
Continuation::Continue(InSubject(state).into())
|
||||
} else if bytes.name().0 == b"body" {
|
||||
Continuation::Continue(InBody(state).into())
|
||||
} else {
|
||||
Continuation::Continue(InCustom(state, T::parse()).into())
|
||||
let parser = T::parse();
|
||||
match parser.consume(namespace, event) {
|
||||
Continuation::Final(Ok(e)) => {
|
||||
state.custom.push(e);
|
||||
Continuation::Continue(Outer(state).into())
|
||||
}
|
||||
Continuation::Final(Err(e)) => Continuation::Final(Err(e)),
|
||||
Continuation::Continue(p) => Continuation::Continue(InCustom(state, p).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::End(_) => {
|
||||
|
@ -129,6 +137,17 @@ impl<T: FromXml> Parser for MessageParser<T> {
|
|||
Continuation::Final(Err(ffail!("Body not found")))
|
||||
}
|
||||
}
|
||||
Event::Empty(_) => {
|
||||
let parser = T::parse();
|
||||
match parser.consume(namespace, event) {
|
||||
Continuation::Final(Ok(e)) => {
|
||||
state.custom.push(e);
|
||||
Continuation::Continue(Outer(state).into())
|
||||
}
|
||||
Continuation::Final(Err(e)) => Continuation::Final(Err(e)),
|
||||
Continuation::Continue(p) => Continuation::Continue(InCustom(state, p).into()),
|
||||
}
|
||||
}
|
||||
_ => Continuation::Final(Err(ffail!("Unexpected XML event: {event:?}"))),
|
||||
},
|
||||
InSubject(mut state) => match event {
|
||||
|
@ -151,7 +170,7 @@ impl<T: FromXml> Parser for MessageParser<T> {
|
|||
Event::End(_) => Continuation::Continue(Outer(state).into()),
|
||||
_ => Continuation::Final(Err(ffail!("Unexpected XML event: {event:?}"))),
|
||||
},
|
||||
InCustom(mut state, mut custom) => match custom.consume(namespace, event) {
|
||||
InCustom(mut state, custom) => match custom.consume(namespace, event) {
|
||||
Continuation::Final(Ok(e)) => {
|
||||
state.custom.push(e);
|
||||
Continuation::Continue(Outer(state).into())
|
||||
|
@ -594,25 +613,34 @@ mod tests {
|
|||
use crate::bind::{BindRequest, Name, Resource, Server};
|
||||
|
||||
use super::*;
|
||||
use quick_xml::NsReader;
|
||||
|
||||
#[tokio::test]
|
||||
async fn parse_message() {
|
||||
let input = r#"<message id="aacea" type="chat" to="nikita@vlnv.dev"><subject>daa</subject><body>bbb</body><unknown-stuff></unknown-stuff></message>"#;
|
||||
let mut reader = NsReader::from_reader(input.as_bytes());
|
||||
let mut buf = vec![];
|
||||
let (ns, event) = reader.read_resolved_event_into_async(&mut buf).await.unwrap();
|
||||
let mut parser = Message::parse().consume(ns, &event);
|
||||
let result = loop {
|
||||
match parser {
|
||||
Continuation::Final(res) => break res,
|
||||
Continuation::Continue(next) => {
|
||||
let (ns, event) = reader.read_resolved_event_into_async(&mut buf).await.unwrap();
|
||||
parser = next.consume(ns, &event);
|
||||
let result: Message<Ignore> = crate::xml::parse(input).unwrap();
|
||||
assert_eq!(
|
||||
result,
|
||||
Message::<Ignore> {
|
||||
from: None,
|
||||
id: Some("aacea".to_string()),
|
||||
to: Some(Jid {
|
||||
name: Some(Name("nikita".into())),
|
||||
server: Server("vlnv.dev".into()),
|
||||
resource: None
|
||||
}),
|
||||
r#type: MessageType::Chat,
|
||||
lang: None,
|
||||
subject: Some("daa".into()),
|
||||
body: "bbb".into(),
|
||||
custom: vec![Ignore],
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
.unwrap();
|
||||
|
||||
#[tokio::test]
|
||||
async fn parse_message_empty_custom() {
|
||||
let input = r#"<message id="aacea" type="chat" to="nikita@vlnv.dev"><subject>daa</subject><body>bbb</body><unknown-stuff/></message>"#;
|
||||
let result: Message<Ignore> = crate::xml::parse(input).unwrap();
|
||||
assert_eq!(
|
||||
result,
|
||||
Message::<Ignore> {
|
||||
|
@ -635,20 +663,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn parse_iq() {
|
||||
let input = r#"<iq id="bind_1" type="set"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource>mobile</resource></bind></iq>"#;
|
||||
let mut reader = NsReader::from_reader(input.as_bytes());
|
||||
let mut buf = vec![];
|
||||
let (ns, event) = reader.read_resolved_event_into_async(&mut buf).await.unwrap();
|
||||
let mut parser = Iq::<BindRequest>::parse().consume(ns, &event);
|
||||
let result = loop {
|
||||
match parser {
|
||||
Continuation::Final(res) => break res,
|
||||
Continuation::Continue(next) => {
|
||||
let (ns, event) = reader.read_resolved_event_into_async(&mut buf).await.unwrap();
|
||||
parser = next.consume(ns, &event);
|
||||
}
|
||||
}
|
||||
}
|
||||
.unwrap();
|
||||
let result: Iq<BindRequest> = crate::xml::parse(input).unwrap();
|
||||
assert_eq!(
|
||||
result,
|
||||
Iq {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use std::ops::Generator;
|
||||
use std::pin::Pin;
|
||||
|
||||
use quick_xml::NsReader;
|
||||
use quick_xml::events::Event;
|
||||
use quick_xml::name::ResolveResult;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use anyhow::Result;
|
||||
|
||||
mod ignore;
|
||||
pub use ignore::Ignore;
|
||||
|
@ -63,6 +64,22 @@ pub enum Continuation<Parser, Res> {
|
|||
Continue(Parser),
|
||||
}
|
||||
|
||||
pub fn parse<T: FromXml>(input: &str) -> Result<T> {
|
||||
let mut reader = NsReader::from_reader(input.as_bytes());
|
||||
let mut buf = vec![];
|
||||
let (ns, event) = reader.read_resolved_event_into(&mut buf)?;
|
||||
let mut parser: Continuation<_, std::result::Result<T, anyhow::Error>> = T::parse().consume(ns, &event);
|
||||
loop {
|
||||
match parser {
|
||||
Continuation::Final(res) => break res,
|
||||
Continuation::Continue(next) => {
|
||||
let (ns, event) = reader.read_resolved_event_into(&mut buf)?;
|
||||
parser = next.consume(ns, &event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! fail_fast {
|
||||
($errorable: expr) => {
|
||||
match $errorable {
|
||||
|
|
Loading…
Reference in New Issue