chiark / gitweb /
fix slip mimeification
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 1 Aug 2021 19:18:00 +0000 (20:18 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 1 Aug 2021 19:18:00 +0000 (20:18 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/slip.rs

index acd863d8d599a8eec7edc23cb05171fdd5185b1f..817357ba5c7cd9bb2b506a818d362106d64d2619 100644 (file)
@@ -14,19 +14,27 @@ pub fn check_checkmtu_mimeswap<const TO_MIME: bool>
 
   for mut packet in data.split_mut(|&c| c == SLIP_END) {
     if packet.len() > mtu.sat() {
-      throw!(anyhow!("mtu exceeded ({} > {})", packet.len(), mtu));
+      throw!(anyhow!("MTU exceeded ({} > {})", packet.len(), mtu));
     }
 
-    while let Some((i, _)) = packet.iter().enumerate().find(
-      |(_,&c)| c == if TO_MIME { SLIP_ESC } else { SLIP_MIME_ESC }
+    while let Some((i, was_mime)) = packet.iter().enumerate().find_map(
+      |(i,&c)| match c {
+        SLIP_MIME_ESC => Some((i,true)),
+        SLIP_ESC      => Some((i,false)),
+        _ => None,
+      }
     ) {
-      packet[i] = if TO_MIME { SLIP_MIME_ESC } else { SLIP_ESC };
-      match packet.get(i+1) {
-        Some(&SLIP_ESC_END) |
-        Some(&SLIP_ESC_ESC) => Ok(()),
-        _ => Err(anyhow!("SLIP escape not followed by ESC_END or ESC_ESC")),
-      }?;
-      packet = &mut packet[i+2 ..];
+      packet[i] = if was_mime { SLIP_ESC } else { SLIP_MIME_ESC };
+      if was_mime != TO_MIME {
+        match packet.get(i+1) {
+          Some(&SLIP_ESC_END) |
+          Some(&SLIP_ESC_ESC) => Ok(()),
+          _ => Err(anyhow!("SLIP escape not followed by ESC_END or ESC_ESC")),
+        }?;
+        packet = &mut packet[i+2 ..];
+      } else {
+        packet = &mut packet[i+1 ..];
+      }
     }
   }
 
@@ -64,6 +72,7 @@ impl From<Frames> for FramesData {
   fn from(frames: Frames) -> FramesData { frames.frames }
 }
 
+#[derive(Copy,Clone,Eq,PartialEq,Ord,PartialOrd,Hash)]
 pub struct DumpHex<'b>(pub &'b [u8]);
 impl Debug for DumpHex<'_> {
   #[throws(fmt::Error)]
@@ -77,7 +86,7 @@ fn mime_slip_to_mime() {
   fn chk(i: &[u8], exp: Result<&[u8], &str>) {
     let mut p = i.to_owned();
     match (exp, check_checkmtu_mimeswap::<true>(10, p.as_mut())) {
-      (Ok(exp), Ok(())) => assert_eq!( exp, &p ),
+      (Ok(exp), Ok(())) => assert_eq!( DumpHex(exp), DumpHex(&p) ),
       (Err(exp), Err(got)) => assert!( got.to_string().contains(exp) ),
       x => panic!("? {:?}", x),
     }
@@ -87,4 +96,9 @@ fn mime_slip_to_mime() {
     Ok(&[ SLIP_END, b'-',     SLIP_ESC_END, SLIP_ESC, b'X' ]) );
 
   chk( &[ SLIP_END, SLIP_ESC, b'y' ], Err("SLIP escape") );
+
+  chk( &[ SLIP_END, b'-',     b'y' ],
+    Ok(&[ SLIP_END, SLIP_ESC, b'y' ]) );
+
+  chk( &[b'x'; 20], Err("MTU"));
 }