Correct `NSecTypeMask::contains_type` and add `from_types` builder
authorMatt Corallo <git@bluematt.me>
Wed, 28 Feb 2024 02:23:52 +0000 (02:23 +0000)
committerMatt Corallo <git@bluematt.me>
Sat, 2 Mar 2024 16:41:07 +0000 (16:41 +0000)
The low-bit-masking in `NSecTypeMask::contains_type` was incorrect,
leading to spuriously looking at the wrong bit position within the
correct byte.

While we're at it, we also add a new constructor which allows for
bits to be set.

src/rr.rs

index 253c412481cd6db8b8059413c340f05b0ba84e3a..fbe8f65a5223b76e75b8a37e379256c36485ee69 100644 (file)
--- a/src/rr.rs
+++ b/src/rr.rs
@@ -632,12 +632,24 @@ pub struct NSecTypeMask([u8; 8192]);
 impl NSecTypeMask {
        /// Constructs a new, empty, type mask.
        pub fn new() -> Self { Self([0; 8192]) }
+       /// Builds a new type mask with the given types set
+       pub fn from_types(types: &[u16]) -> Self {
+               let mut flags = [0; 8192];
+               for t in types {
+                       flags[*t as usize >> 3] |= 1 << (7 - (*t as usize % 8));
+               }
+               let res = Self(flags);
+               for t in types {
+                       debug_assert!(res.contains_type(*t));
+               }
+               res
+       }
        /// Checks if the given type (from [`Record::ty`]) is set, indicating a record of this type
        /// exists.
        pub fn contains_type(&self, ty: u16) -> bool {
                let f = self.0[(ty >> 3) as usize];
                // DNSSEC's bit fields are in wire order, so the high bit is type 0, etc.
-               f & (1 << (7 - (ty & 3))) != 0
+               f & (1 << (7 - (ty % 8))) != 0
        }
        fn write_json(&self, s: &mut String) {
                *s += "[";