Explorar o código

More record parsing tests

This gets us down to 0 surviving mutants, which means that mutation testing can now run in CI.
Benjamin Sago %!s(int64=4) %!d(string=hai) anos
pai
achega
40181f9453

+ 20 - 1
dns/src/record/caa.rs

@@ -31,7 +31,8 @@ impl Wire for CAA {
         let flags = c.read_u8()?;
         trace!("Parsed flags -> {:#08b}", flags);
 
-        let critical = flags & 0b_1000_0000 == 0b_1000_0000;
+        let has_bit = |bit| { flags & bit == bit };
+        let critical = has_bit(0b_1000_0000);
         trace!("Parsed critical flag -> {:?}", critical);
 
         let tag_length = c.read_u8()?;
@@ -69,6 +70,7 @@ impl Wire for CAA {
     }
 }
 
+
 #[cfg(test)]
 mod test {
     use super::*;
@@ -107,6 +109,23 @@ mod test {
                    });
     }
 
+    #[test]
+    fn ignores_other_flags() {
+        let buf = &[
+            0x7F,  // flags (all except critical bit set)
+            0x01,  // tag length
+            0x65,  // tag
+            0x45,  // value
+        ];
+
+        assert_eq!(CAA::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
+                   CAA {
+                       critical: false,
+                       tag: String::from("e"),
+                       value: String::from("E"),
+                   });
+    }
+
     #[test]
     fn record_empty() {
         assert_eq!(CAA::read(0, &mut Cursor::new(&[])),

+ 11 - 0
dns/src/record/cname.rs

@@ -54,6 +54,17 @@ mod test {
                    });
     }
 
+    #[test]
+    fn incorrect_record_length() {
+        let buf = &[
+            0x03, 0x65, 0x66, 0x67,  // domain
+            0x00,  // domain terminator
+        ];
+
+        assert_eq!(CNAME::read(6, &mut Cursor::new(buf)),
+                   Err(WireError::WrongLabelLength { expected: 6, got: 5 }));
+    }
+
     #[test]
     fn record_empty() {
         assert_eq!(CNAME::read(0, &mut Cursor::new(&[])),

+ 12 - 0
dns/src/record/mx.rs

@@ -65,6 +65,18 @@ mod test {
                    });
     }
 
+    #[test]
+    fn incorrect_record_length() {
+        let buf = &[
+            0x00, 0x0A,  // preference
+            0x03, 0x65, 0x66, 0x67,  // domain
+            0x00,  // domain terminator
+        ];
+
+        assert_eq!(MX::read(6, &mut Cursor::new(buf)),
+                   Err(WireError::WrongLabelLength { expected: 6, got: 7 }));
+    }
+
     #[test]
     fn record_empty() {
         assert_eq!(MX::read(0, &mut Cursor::new(&[])),

+ 11 - 0
dns/src/record/ns.rs

@@ -56,6 +56,17 @@ mod test {
                    });
     }
 
+    #[test]
+    fn incorrect_record_length() {
+        let buf = &[
+            0x03, 0x65, 0x66, 0x67,  // nameserver
+            0x00,  // nameserver terminator
+        ];
+
+        assert_eq!(NS::read(66, &mut Cursor::new(buf)),
+                   Err(WireError::WrongLabelLength { expected: 66, got: 5 }));
+    }
+
     #[test]
     fn record_empty() {
         assert_eq!(NS::read(0, &mut Cursor::new(&[])),

+ 11 - 0
dns/src/record/ptr.rs

@@ -60,6 +60,17 @@ mod test {
                    });
     }
 
+    #[test]
+    fn incorrect_record_length() {
+        let buf = &[
+            0x03, 0x65, 0x66, 0x67,  // cname
+            0x00,  // cname terminator
+        ];
+
+        assert_eq!(PTR::read(6, &mut Cursor::new(buf)),
+                   Err(WireError::WrongLabelLength { expected: 6, got: 5 }));
+    }
+
     #[test]
     fn record_empty() {
         assert_eq!(PTR::read(0, &mut Cursor::new(&[])),

+ 18 - 0
dns/src/record/soa.rs

@@ -115,6 +115,24 @@ mod test {
                    });
     }
 
+    #[test]
+    fn incorrect_record_length() {
+        let buf = &[
+            0x03, 0x65, 0x66, 0x67,  // mname
+            0x00,  // mname terminator
+            0x03, 0x65, 0x66, 0x67,  // rname
+            0x00,  // rname terminator
+            0x5d, 0x3c, 0xef, 0x02,  // Serial
+            0x00, 0x01, 0x51, 0x80,  // Refresh interval
+            0x00, 0x00, 0x1c, 0x20,  // Retry interval
+            0x00, 0x09, 0x3a, 0x80,  // Expire limit
+            0x00, 0x00, 0x01, 0x2c,  // Minimum TTL
+        ];
+
+        assert_eq!(SOA::read(89, &mut Cursor::new(buf)),
+                   Err(WireError::WrongLabelLength { expected: 89, got: 30 }));
+    }
+
     #[test]
     fn record_empty() {
         assert_eq!(SOA::read(0, &mut Cursor::new(&[])),

+ 14 - 0
dns/src/record/srv.rs

@@ -84,6 +84,20 @@ mod test {
                    });
     }
 
+    #[test]
+    fn incorrect_record_length() {
+        let buf = &[
+            0x00, 0x01,  // priority
+            0x00, 0x01,  // weight
+            0x92, 0x7c,  // port
+            0x03, 0x61, 0x74, 0x61,  // target
+            0x00,  // target terminator
+        ];
+
+        assert_eq!(SRV::read(16, &mut Cursor::new(buf)),
+                   Err(WireError::WrongLabelLength { expected: 16, got: 11 }));
+    }
+
     #[test]
     fn record_empty() {
         assert_eq!(SRV::read(0, &mut Cursor::new(&[])),

+ 55 - 7
dns/src/record/txt.rs

@@ -46,13 +46,6 @@ impl Wire for TXT {
             }
         }
 
-        if len == total_len {
-            debug!("Length matches expected");
-        }
-        else {
-            warn!("Expected length {} but read {} bytes", len, buf.len());
-        }
-
         let message = String::from_utf8_lossy(&buf).to_string();
         trace!("Parsed message -> {:?}", message);
 
@@ -132,6 +125,61 @@ mod test {
         // did you know you can just _write_ code like this, and nobody will stop you?
     }
 
+    #[test]
+    fn right_at_the_limit() {
+        let buf = &[
+            0xFE,  // message chunk length
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
+            0x42,  // exactly two hundred and fifty four ‘B’s (a hive)
+        ];
+
+        assert_eq!(TXT::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
+                   TXT {
+                       message: String::from("BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+                                              BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+                                              BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+                                              BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+                                              BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+                                              BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+                                              BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+                                              BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+                                              BBBBBBBBBBBBBBBBBBBBBB"),
+                   });
+    }
+
+    #[test]
+    fn incorrect_length() {
+        let buf = &[
+            0x06,  // message chunk length
+            0x74, 0x78, 0x74, 0x20, 0x6d, 0x65,  // message chunk
+        ];
+
+        assert_eq!(TXT::read(123, &mut Cursor::new(buf)),
+                   Err(WireError::WrongLabelLength { expected: 123, got: 7 }));
+    }
+
     #[test]
     fn record_empty() {
         assert_eq!(TXT::read(0, &mut Cursor::new(&[])),