chatstates, ping, presence: Check for extraneous attributes.

Emmanuel Gil Peyrot created

Change summary

Cargo.toml        |  2 +-
src/chatstates.rs |  4 +++-
src/ping.rs       |  4 +++-
src/presence.rs   | 17 +++++++++++++----
4 files changed, 20 insertions(+), 7 deletions(-)

Detailed changes

Cargo.toml 🔗

@@ -10,7 +10,7 @@ categories = ["parsing", "network-programming"]
 license = "MPL-2.0"
 
 [dependencies]
-minidom = "0.3.0"
+minidom = "0.3.1"
 jid = "0.2.0"
 base64 = "0.5.0"
 digest = "0.5.0"

src/chatstates.rs 🔗

@@ -28,6 +28,9 @@ impl<'a> TryFrom<&'a Element> for ChatState {
         for _ in elem.children() {
             return Err(Error::ParseError("Unknown child in chatstate element."));
         }
+        for _ in elem.attrs() {
+            return Err(Error::ParseError("Unknown attribute in chatstate element."));
+        }
         if elem.is("active", ns::CHATSTATES) {
             Ok(ChatState::Active)
         } else if elem.is("composing", ns::CHATSTATES) {
@@ -90,7 +93,6 @@ mod tests {
     }
 
     #[test]
-    #[ignore]
     fn test_invalid_attribute() {
         let elem: Element = "<inactive xmlns='http://jabber.org/protocol/chatstates' coucou=''/>".parse().unwrap();
         let error = ChatState::try_from(&elem).unwrap_err();

src/ping.rs 🔗

@@ -26,6 +26,9 @@ impl<'a> TryFrom<&'a Element> for Ping {
         for _ in elem.children() {
             return Err(Error::ParseError("Unknown child in ping element."));
         }
+        for _ in elem.attrs() {
+            return Err(Error::ParseError("Unknown attribute in ping element."));
+        }
         Ok(Ping)
     }
 }
@@ -60,7 +63,6 @@ mod tests {
     }
 
     #[test]
-    #[ignore]
     fn test_invalid_attribute() {
         let elem: Element = "<ping xmlns='urn:xmpp:ping' coucou=''/>".parse().unwrap();
         let error = Ping::try_from(&elem).unwrap_err();

src/presence.rs 🔗

@@ -180,6 +180,9 @@ impl<'a> TryFrom<&'a Element> for Presence {
                 for _ in elem.children() {
                     return Err(Error::ParseError("Unknown child in show element."));
                 }
+                for _ in elem.attrs() {
+                    return Err(Error::ParseError("Unknown attribute in show element."));
+                }
                 show = Some(match elem.text().as_ref() {
                     "away" => Show::Away,
                     "chat" => Show::Chat,
@@ -192,6 +195,11 @@ impl<'a> TryFrom<&'a Element> for Presence {
                 for _ in elem.children() {
                     return Err(Error::ParseError("Unknown child in status element."));
                 }
+                for (attr, _) in elem.attrs() {
+                    if attr != "xml:lang" {
+                        return Err(Error::ParseError("Unknown attribute in status element."));
+                    }
+                }
                 let lang = elem.attr("xml:lang").unwrap_or("").to_owned();
                 if statuses.insert(lang, elem.text()).is_some() {
                     return Err(Error::ParseError("Status element present twice for the same xml:lang."));
@@ -203,6 +211,9 @@ impl<'a> TryFrom<&'a Element> for Presence {
                 for _ in elem.children() {
                     return Err(Error::ParseError("Unknown child in priority element."));
                 }
+                for _ in elem.attrs() {
+                    return Err(Error::ParseError("Unknown attribute in priority element."));
+                }
                 priority = Some(Priority::from_str(elem.text().as_ref())?);
             } else {
                 payloads.push(elem.clone());
@@ -379,9 +390,8 @@ mod tests {
     }
 
     #[test]
-    #[ignore]
     fn test_invalid_status_child() {
-        let elem: Element = "<presence xmlns='jabber:client'><status xmlns='jabber:client'><coucou/></status></presence>".parse().unwrap();
+        let elem: Element = "<presence xmlns='jabber:client'><status><coucou/></status></presence>".parse().unwrap();
         let error = Presence::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
@@ -391,9 +401,8 @@ mod tests {
     }
 
     #[test]
-    #[ignore]
     fn test_invalid_attribute() {
-        let elem: Element = "<status xmlns='jabber:client' coucou=''/>".parse().unwrap();
+        let elem: Element = "<presence xmlns='jabber:client'><status coucou=''/></presence>".parse().unwrap();
         let error = Presence::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,