changeset 2:cabc4aafdd85

Added length check and a few tests Systemd socket names must not exceed 255 chars, so this change satity checks the limit.
author Martin Habovstiak <martin.habovstiak@gmail.com>
date Fri, 27 Nov 2020 10:21:07 +0100
parents ef8bf41097ac
children 0edcde404b02
files src/error.rs src/lib.rs
diffstat 2 files changed, 30 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/error.rs	Fri Nov 27 10:07:35 2020 +0100
+++ b/src/error.rs	Fri Nov 27 10:21:07 2020 +0100
@@ -20,7 +20,9 @@
     #[error("failed to parse socket address")]
     SocketAddr(std::net::AddrParseError),
     #[error("invalid character '{c}' in systemd socket name {string} at position {pos}")]
-    InvalidCharacter { string: String, c: char, pos: usize, }
+    InvalidCharacter { string: String, c: char, pos: usize, },
+    #[error("systemd socket name {string} is {len} characters long which is more than the limit 255")]
+    LongSocketName { string: String, len: usize, },
 }
 
 /// Error that can occur during parsing of `SocketAddr` from a `OsStr`/`OsString`
--- a/src/lib.rs	Fri Nov 27 10:07:35 2020 +0100
+++ b/src/lib.rs	Fri Nov 27 10:21:07 2020 +0100
@@ -163,8 +163,10 @@
     // rules.
     fn try_from_generic<'a, T>(string: T) -> Result<Self, ParseError> where T: 'a + std::ops::Deref<Target=str> + Into<String> {
         if string.starts_with(SYSTEMD_PREFIX) {
+            let name_len = string.len() - SYSTEMD_PREFIX.len();
             match string[SYSTEMD_PREFIX.len()..].chars().enumerate().find(|(_, c)| !c.is_ascii() || *c < ' ' || *c == ':') {
-                None => Ok(SocketAddr(SocketAddrInner::Systemd(string.into()))),
+                None if name_len <= 255 => Ok(SocketAddr(SocketAddrInner::Systemd(string.into()))),
+                None => Err(ParseErrorInner::LongSocketName { string: string.into(), len: name_len }.into()),
                 Some((pos, c)) => Err(ParseErrorInner::InvalidCharacter { string: string.into(), c, pos, }.into()),
             }
         } else {
@@ -307,4 +309,28 @@
     fn parse_systemd() {
         assert_eq!("systemd://foo".parse::<SocketAddr>().unwrap().0, SocketAddrInner::Systemd("systemd://foo".to_owned()));
     }
+
+    #[test]
+    #[should_panic]
+    fn parse_systemd_fail_control() {
+        "systemd://foo\n".parse::<SocketAddr>().unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn parse_systemd_fail_colon() {
+        "systemd://foo:".parse::<SocketAddr>().unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn parse_systemd_fail_non_ascii() {
+        "systemd://fooĆ”".parse::<SocketAddr>().unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn parse_systemd_fail_too_long() {
+        "systemd://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".parse::<SocketAddr>().unwrap();
+    }
 }