1use alloc::string::ToString;
11use alloc::{string::String, vec::Vec};
12use core::char;
13use core::cmp::{Ordering, PartialEq};
14use core::fmt::{self, Write};
15use core::hash::{Hash, Hasher};
16use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
17use core::str::FromStr;
18
19use ipnet::{IpNet, Ipv4Net, Ipv6Net};
20#[cfg(feature = "serde")]
21use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
22use tinyvec::TinyVec;
23
24use crate::error::{ProtoError, ProtoResult};
25use crate::rr::domain::label::{CaseInsensitive, CaseSensitive, IntoLabel, Label, LabelCmp};
26use crate::rr::domain::usage::LOCALHOST as LOCALHOST_usage;
27use crate::serialize::binary::{
28 BinDecodable, BinDecoder, BinEncodable, BinEncoder, DecodeError, NameEncoding, Restrict,
29};
30use crate::serialize::txt::ParseError;
31
32#[derive(Clone, Default, Eq)]
34pub struct Name {
35 is_fqdn: bool,
36 label_data: TinyVec<[u8; 32]>,
37 label_ends: TinyVec<[u8; 24]>,
40}
41
42impl Name {
43 pub const MAX_LENGTH: usize = 255;
45
46 pub fn new() -> Self {
48 Self::default()
49 }
50
51 pub fn root() -> Self {
53 let mut this = Self::new();
54 this.is_fqdn = true;
55 this
56 }
57
58 fn extend_name(&mut self, label: &[u8]) -> Result<(), DecodeError> {
60 let new_len = self.encoded_len() + label.len() + 1;
61
62 if new_len > Self::MAX_LENGTH {
63 return Err(DecodeError::DomainNameTooLong(new_len));
64 };
65
66 self.label_data.extend_from_slice(label);
67 self.label_ends.push(self.label_data.len() as u8);
68
69 Ok(())
70 }
71
72 #[cfg(feature = "std")]
74 pub fn randomize_label_case(&mut self) {
75 let mut rand_bits: u32 = 0;
78
79 for (i, b) in self.label_data.iter_mut().enumerate() {
80 if i % 32 == 0 {
82 rand_bits = rand::random();
83 }
84
85 let flip_case = rand_bits & 1 == 1;
86
87 if b.is_ascii_alphabetic() && flip_case {
88 *b ^= 0x20; }
90
91 rand_bits >>= 1;
92 }
93 }
94
95 pub fn is_root(&self) -> bool {
108 self.label_ends.is_empty() && self.is_fqdn()
109 }
110
111 pub fn is_fqdn(&self) -> bool {
134 self.is_fqdn
135 }
136
137 pub fn set_fqdn(&mut self, val: bool) {
141 self.is_fqdn = val
142 }
143
144 pub fn iter(&self) -> LabelIter<'_> {
146 LabelIter {
147 name: self,
148 start: 0,
149 end: self.label_ends.len() as u8,
150 }
151 }
152
153 pub fn append_label<L: IntoLabel>(mut self, label: L) -> ProtoResult<Self> {
166 self.extend_name(label.into_label()?.as_bytes())?;
167 Ok(self)
168 }
169
170 pub fn prepend_label<L: IntoLabel>(&self, label: L) -> ProtoResult<Self> {
183 let mut name = Self::new().append_label(label)?;
184
185 for label in self.into_iter() {
186 name.extend_name(label)?;
187 }
188
189 name.set_fqdn(self.is_fqdn);
190
191 Ok(name)
192 }
193
194 pub fn from_labels<I, L>(labels: I) -> ProtoResult<Self>
218 where
219 I: IntoIterator<Item = L>,
220 L: IntoLabel,
221 {
222 let (labels, errors): (Vec<_>, Vec<_>) = labels
223 .into_iter()
224 .map(IntoLabel::into_label)
225 .partition(Result::is_ok);
226 let labels: Vec<_> = labels.into_iter().map(Result::unwrap).collect();
227 let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect();
228
229 if labels.len() > 255 {
230 return Err(DecodeError::DomainNameTooLong(labels.len()).into());
231 };
232 if !errors.is_empty() {
233 return Err(format!("error converting some labels: {errors:?}").into());
234 };
235
236 let mut name = Self {
237 is_fqdn: true,
238 ..Self::default()
239 };
240 for label in labels {
241 name = name.append_label(label)?;
242 }
243
244 Ok(name)
245 }
246
247 pub fn append_name(mut self, other: &Self) -> Result<Self, ProtoError> {
273 for label in other.iter() {
274 self.extend_name(label)?;
275 }
276
277 self.is_fqdn = other.is_fqdn;
278 Ok(self)
279 }
280
281 pub fn append_domain(self, domain: &Self) -> Result<Self, ProtoError> {
299 let mut this = self.append_name(domain)?;
300 this.set_fqdn(true);
301 Ok(this)
302 }
303
304 pub fn to_lowercase(&self) -> Self {
319 let new_label_data = self
320 .label_data
321 .iter()
322 .map(|c| c.to_ascii_lowercase())
323 .collect();
324 Self {
325 is_fqdn: self.is_fqdn,
326 label_data: new_label_data,
327 label_ends: self.label_ends.clone(),
328 }
329 }
330
331 pub fn base_name(&self) -> Self {
345 let length = self.label_ends.len();
346 if length > 0 {
347 return self.trim_to(length - 1);
348 }
349 self.clone()
350 }
351
352 pub fn trim_to(&self, num_labels: usize) -> Self {
367 if num_labels > self.label_ends.len() {
368 self.clone()
369 } else {
370 Self::from_labels(self.iter().skip(self.label_ends.len() - num_labels)).unwrap()
371 }
372 }
373
374 pub fn zone_of_case(&self, name: &Self) -> bool {
376 self.zone_of_with(name, <[u8]>::eq)
377 }
378
379 pub fn zone_of(&self, name: &Self) -> bool {
395 self.zone_of_with(name, <[u8]>::eq_ignore_ascii_case)
396 }
397
398 fn zone_of_with(&self, name: &Self, label_eq: fn(&[u8], &[u8]) -> bool) -> bool {
399 let self_len = self.label_ends.len();
400 let name_len = name.label_ends.len();
401 match (self_len, name_len) {
402 (0, _) => return true,
403 (_, 0) => return false,
404 _ if self_len > name_len => return false,
405 _ => {}
406 }
407
408 self.iter()
409 .rev()
410 .zip(name.iter().rev())
411 .all(|(a, b)| label_eq(a, b))
412 }
413
414 pub fn num_labels(&self) -> u8 {
432 let num = self.label_ends.len() as u8;
435
436 self.iter()
437 .next()
438 .map(|l| if l == b"*" { num - 1 } else { num })
439 .unwrap_or(num)
440 }
441
442 pub fn len(&self) -> usize {
458 let dots = if !self.label_ends.is_empty() {
459 self.label_ends.len()
460 } else {
461 1
462 };
463 dots + self.label_data.len()
464 }
465
466 fn encoded_len(&self) -> usize {
471 self.label_ends.len() + self.label_data.len() + 1
472 }
473
474 pub fn is_empty(&self) -> bool {
477 false
478 }
479
480 pub(crate) fn from_tokens<'i, I: Iterator<Item = &'i str>>(
482 mut tokens: I,
483 origin: Option<&Self>,
484 ) -> Result<Self, ParseError> {
485 let name = tokens
486 .next()
487 .ok_or_else(|| ParseError::MissingToken("name".to_string()))
488 .and_then(|s| Self::parse(s, origin).map_err(ParseError::from))?;
489 Ok(name)
490 }
491
492 pub fn parse(local: &str, origin: Option<&Self>) -> ProtoResult<Self> {
505 Self::from_encoded_str::<LabelEncUtf8>(local, origin)
506 }
507
508 pub fn from_ascii<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
536 Self::from_encoded_str::<LabelEncAscii>(name.as_ref(), None)
537 }
538
539 pub fn from_utf8<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
560 Self::from_encoded_str::<LabelEncUtf8>(name.as_ref(), None)
561 }
562
563 pub fn from_str_relaxed<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
582 let name = name.as_ref();
583 Self::from_utf8(name).or_else(|_| Self::from_ascii(name))
584 }
585
586 fn from_encoded_str<E: LabelEnc>(local: &str, origin: Option<&Self>) -> ProtoResult<Self> {
587 let mut name = Self::new();
588 let mut label = String::new();
589
590 let mut state = ParseState::Label;
591
592 if local == "." {
594 name.set_fqdn(true);
595 return Ok(name);
596 }
597
598 for ch in local.chars() {
601 match state {
602 ParseState::Label => match ch {
603 '.' => {
604 name = name.append_label(E::to_label(&label)?)?;
605 label.clear();
606 }
607 '\\' => state = ParseState::Escape1,
608 ch if !ch.is_control() && !ch.is_whitespace() => label.push(ch),
609 _ => return Err(format!("unrecognized char: {ch}").into()),
610 },
611 ParseState::Escape1 => {
612 if ch.is_numeric() {
613 state = ParseState::Escape2(
614 ch.to_digit(8)
615 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?,
616 );
617 } else {
618 label.push(ch);
620 state = ParseState::Label;
621 }
622 }
623 ParseState::Escape2(i) => {
624 if ch.is_numeric() {
625 state = ParseState::Escape3(
626 i,
627 ch.to_digit(8)
628 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?,
629 );
630 } else {
631 return Err(ProtoError::from(format!("unrecognized char: {ch}")));
632 }
633 }
634 ParseState::Escape3(i, ii) => {
635 if ch.is_numeric() {
636 let val: u32 = (i * 8 * 8)
638 + (ii * 8)
639 + ch.to_digit(8)
640 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?;
641 let new: char = char::from_u32(val)
642 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?;
643 label.push(new);
644 state = ParseState::Label;
645 } else {
646 return Err(format!("unrecognized char: {ch}").into());
647 }
648 }
649 }
650 }
651
652 if !label.is_empty() {
653 name = name.append_label(E::to_label(&label)?)?;
654 }
655
656 if label.is_empty() && !local.is_empty() {
658 name.set_fqdn(true);
659 } else if let Some(other) = origin {
660 return name.append_domain(other);
661 }
662
663 Ok(name)
664 }
665
666 fn cmp_with_f<F: LabelCmp>(&self, other: &Self) -> Ordering {
668 match (self.is_fqdn(), other.is_fqdn()) {
669 (false, true) => Ordering::Less,
670 (true, false) => Ordering::Greater,
671 _ => self.cmp_labels::<F>(other),
672 }
673 }
674
675 fn cmp_labels<F: LabelCmp>(&self, other: &Self) -> Ordering {
677 for (l, r) in self.iter().rev().zip(other.iter().rev()) {
679 for (&a, &b) in l.iter().zip(r.iter()) {
680 match F::cmp_u8(a, b) {
681 Ordering::Equal => {}
682 ord => return ord,
683 }
684 }
685 match l.len().cmp(&r.len()) {
686 Ordering::Equal => {}
687 ord => return ord,
688 }
689 }
690 self.label_ends.len().cmp(&other.label_ends.len())
691 }
692
693 pub fn cmp_case(&self, other: &Self) -> Ordering {
695 self.cmp_with_f::<CaseSensitive>(other)
696 }
697
698 pub fn eq_case(&self, other: &Self) -> bool {
700 self.cmp_with_f::<CaseSensitive>(other) == Ordering::Equal
701 }
702
703 pub fn eq_ignore_root(&self, other: &Self) -> bool {
737 self.cmp_labels::<CaseInsensitive>(other) == Ordering::Equal
738 }
739
740 pub fn eq_ignore_root_case(&self, other: &Self) -> bool {
762 self.cmp_labels::<CaseSensitive>(other) == Ordering::Equal
763 }
764
765 pub fn to_ascii(&self) -> String {
770 let mut s = String::with_capacity(self.len());
771 self.write_labels::<String, LabelEncAscii>(&mut s)
772 .expect("string conversion of name should not fail");
773 s
774 }
775
776 pub fn to_utf8(&self) -> String {
782 format!("{self}")
783 }
784
785 pub fn parse_arpa_name(&self) -> Result<IpNet, ProtoError> {
787 if !self.is_fqdn() {
788 return Err("PQDN cannot be valid arpa name".into());
789 }
790 let mut iter = self.iter().rev();
791 let first = iter
792 .next()
793 .ok_or_else(|| ProtoError::from("not an arpa address"))?;
794 if !"arpa".eq_ignore_ascii_case(core::str::from_utf8(first)?) {
795 return Err("not an arpa address".into());
796 }
797 let second = iter
798 .next()
799 .ok_or_else(|| ProtoError::from("invalid arpa address"))?;
800 let mut prefix_len: u8 = 0;
801 match &core::str::from_utf8(second)?.to_ascii_lowercase()[..] {
802 "in-addr" => {
803 let mut octets: [u8; 4] = [0; 4];
804 for octet in octets.iter_mut() {
805 match iter.next() {
806 Some(label) => *octet = core::str::from_utf8(label)?.parse()?,
807 None => break,
808 }
809 prefix_len += 8;
810 }
811 if iter.next().is_some() {
812 return Err("unrecognized in-addr.arpa.".into());
813 }
814 Ok(IpNet::V4(
815 Ipv4Net::new(octets.into(), prefix_len).expect("Ipv4Net::new"),
816 ))
817 }
818 "ip6" => {
819 let mut address: u128 = 0;
820 while prefix_len < 128 {
821 match iter.next() {
822 Some(label) => {
823 if label.len() == 1 {
824 prefix_len += 4;
825 let hex = u8::from_str_radix(core::str::from_utf8(label)?, 16)?;
826 address |= u128::from(hex) << (128 - prefix_len);
827 } else {
828 return Err("invalid label length for ip6.arpa".into());
829 }
830 }
831 None => break,
832 }
833 }
834 if iter.next().is_some() {
835 return Err("unrecognized ip6.arpa.".into());
836 }
837 Ok(IpNet::V6(
838 Ipv6Net::new(address.into(), prefix_len).expect("Ipv6Net::new"),
839 ))
840 }
841 _ => Err("unrecognized arpa address".into()),
842 }
843 }
844
845 fn write_labels<W: Write, E: LabelEnc>(&self, f: &mut W) -> Result<(), fmt::Error> {
846 let mut iter = self.iter().map(|b| Label::from_raw_bytes(b).unwrap());
847 if let Some(label) = iter.next() {
848 E::write_label(f, &label)?;
849 }
850
851 for label in iter {
852 write!(f, ".")?;
853 E::write_label(f, &label)?;
854 }
855
856 if self.is_root() || self.is_fqdn() {
858 write!(f, ".")?;
859 }
860 Ok(())
861 }
862
863 pub fn is_localhost(&self) -> bool {
881 LOCALHOST_usage.zone_of(self)
882 }
883
884 pub fn is_wildcard(&self) -> bool {
902 self.iter().next().is_some_and(|l| l == b"*")
903 }
904
905 pub fn into_wildcard(self) -> Self {
921 if self.label_ends.is_empty() {
922 return Self::root();
923 }
924 let mut label_data = TinyVec::new();
925 label_data.push(b'*');
926 let mut label_ends = TinyVec::new();
927 label_ends.push(1);
928
929 for label in self.iter().skip(1) {
931 label_data.extend_from_slice(label);
932 label_ends.push(label_data.len() as u8);
933 }
934 Self {
935 label_data,
936 label_ends,
937 is_fqdn: self.is_fqdn,
938 }
939 }
940}
941
942impl fmt::Debug for Name {
943 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
944 f.write_str("Name(\"")?;
945 self.write_labels::<_, LabelEncUtf8>(f)?;
946 f.write_str("\")")
947 }
948}
949
950trait LabelEnc {
951 fn to_label(name: &str) -> ProtoResult<Label>;
952 fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error>;
953}
954
955struct LabelEncAscii;
956
957impl LabelEnc for LabelEncAscii {
958 fn to_label(name: &str) -> ProtoResult<Label> {
959 Label::from_ascii(name)
960 }
961
962 fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error> {
963 label.write_ascii(f)
964 }
965}
966
967struct LabelEncUtf8;
968
969impl LabelEnc for LabelEncUtf8 {
970 fn to_label(name: &str) -> ProtoResult<Label> {
971 Label::from_utf8(name)
972 }
973
974 fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error> {
975 write!(f, "{label}")
976 }
977}
978
979pub struct LabelIter<'a> {
981 name: &'a Name,
982 start: u8,
983 end: u8,
984}
985
986impl<'a> Iterator for LabelIter<'a> {
987 type Item = &'a [u8];
988
989 fn next(&mut self) -> Option<Self::Item> {
990 if self.start >= self.end {
991 return None;
992 }
993
994 let end = *self.name.label_ends.get(self.start as usize)?;
995 let start = match self.start {
996 0 => 0,
997 _ => self.name.label_ends[(self.start - 1) as usize],
998 };
999 self.start += 1;
1000 Some(&self.name.label_data[start as usize..end as usize])
1001 }
1002
1003 fn size_hint(&self) -> (usize, Option<usize>) {
1004 let len = self.end.saturating_sub(self.start) as usize;
1005 (len, Some(len))
1006 }
1007}
1008
1009impl ExactSizeIterator for LabelIter<'_> {}
1010
1011impl DoubleEndedIterator for LabelIter<'_> {
1012 fn next_back(&mut self) -> Option<Self::Item> {
1013 if self.end <= self.start {
1014 return None;
1015 }
1016
1017 self.end -= 1;
1018
1019 let end = *self.name.label_ends.get(self.end as usize)?;
1020 let start = match self.end {
1021 0 => 0,
1022 _ => self.name.label_ends[(self.end - 1) as usize],
1023 };
1024
1025 Some(&self.name.label_data[start as usize..end as usize])
1026 }
1027}
1028
1029impl<'a> IntoIterator for &'a Name {
1030 type Item = &'a [u8];
1031 type IntoIter = LabelIter<'a>;
1032
1033 fn into_iter(self) -> Self::IntoIter {
1034 self.iter()
1035 }
1036}
1037
1038impl From<IpAddr> for Name {
1039 fn from(addr: IpAddr) -> Self {
1040 match addr {
1041 IpAddr::V4(ip) => ip.into(),
1042 IpAddr::V6(ip) => ip.into(),
1043 }
1044 }
1045}
1046
1047impl From<Ipv4Addr> for Name {
1048 fn from(addr: Ipv4Addr) -> Self {
1049 let octets = addr.octets();
1050
1051 let mut labels =
1052 octets
1053 .iter()
1054 .rev()
1055 .fold(Vec::<Label>::with_capacity(6), |mut labels, o| {
1056 let label: Label = format!("{o}")
1057 .as_bytes()
1058 .into_label()
1059 .expect("IP octet to label should never fail");
1060 labels.push(label);
1061 labels
1062 });
1063
1064 labels.push(
1065 b"in-addr"
1066 .into_label()
1067 .expect("simple name should never fail"),
1068 );
1069 labels.push(b"arpa".into_label().expect("simple name should never fail"));
1070
1071 Self::from_labels(labels).expect("a translation of Ipv4Addr should never fail")
1072 }
1073}
1074
1075impl From<Ipv6Addr> for Name {
1076 fn from(addr: Ipv6Addr) -> Self {
1077 let segments = addr.segments();
1078
1079 let mut labels =
1080 segments
1081 .iter()
1082 .rev()
1083 .fold(Vec::<Label>::with_capacity(34), |mut labels, o| {
1084 labels.push(
1085 format!("{:x}", (*o & 0x000F) as u8)
1086 .as_bytes()
1087 .into_label()
1088 .expect("IP octet to label should never fail"),
1089 );
1090 labels.push(
1091 format!("{:x}", ((*o >> 4) & 0x000F) as u8)
1092 .as_bytes()
1093 .into_label()
1094 .expect("IP octet to label should never fail"),
1095 );
1096 labels.push(
1097 format!("{:x}", ((*o >> 8) & 0x000F) as u8)
1098 .as_bytes()
1099 .into_label()
1100 .expect("IP octet to label should never fail"),
1101 );
1102 labels.push(
1103 format!("{:x}", ((*o >> 12) & 0x000F) as u8)
1104 .as_bytes()
1105 .into_label()
1106 .expect("IP octet to label should never fail"),
1107 );
1108 labels
1109 });
1110
1111 labels.push(b"ip6".into_label().expect("simple name should never fail"));
1112 labels.push(b"arpa".into_label().expect("simple name should never fail"));
1113
1114 Self::from_labels(labels).expect("a translation of Ipv6Addr should never fail")
1115 }
1116}
1117
1118impl PartialEq<Self> for Name {
1119 fn eq(&self, other: &Self) -> bool {
1120 match self.is_fqdn == other.is_fqdn {
1121 true => self.cmp_with_f::<CaseInsensitive>(other) == Ordering::Equal,
1122 false => false,
1123 }
1124 }
1125}
1126
1127impl Hash for Name {
1128 fn hash<H: Hasher>(&self, state: &mut H) {
1129 self.is_fqdn.hash(state);
1130 self.iter()
1132 .flatten()
1133 .for_each(|&b| state.write_u8(b.to_ascii_lowercase()));
1134 }
1135}
1136
1137enum ParseState {
1138 Label,
1139 Escape1,
1140 Escape2(u32),
1141 Escape3(u32, u32),
1142}
1143
1144impl BinEncodable for Name {
1145 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
1146 let name;
1147 let name_ref = if matches!(encoder.name_encoding(), NameEncoding::UncompressedLowercase) {
1148 name = self.to_lowercase();
1149 &name
1150 } else {
1151 self
1152 };
1153 let compression = matches!(encoder.name_encoding(), NameEncoding::Compressed)
1154 && encoder.compressed_name_count < COMPRESSED_NAME_LIMIT;
1155
1156 let buf_len = encoder.len(); let labels = name_ref.iter();
1160
1161 let mut labels_written = Vec::with_capacity(name_ref.label_ends.len());
1163 for label in labels {
1166 if label.len() > 63 {
1167 return Err(DecodeError::LabelBytesTooLong(label.len()).into());
1168 }
1169
1170 labels_written.push(encoder.offset());
1171 encoder.emit_character_data(label)?;
1172 }
1173 let last_index = encoder.offset();
1174 if compression {
1177 encoder.compressed_name_count += 1;
1178 for label_idx in &labels_written {
1179 match encoder.get_label_pointer(*label_idx, last_index) {
1180 Some(loc) if loc & 0xC000 == 0 => {
1181 encoder.set_offset(*label_idx);
1183 encoder.trim();
1184
1185 encoder.emit_u16(0xC000u16 | loc)?;
1188
1189 return Ok(());
1191 }
1192 _ => {
1193 encoder.store_label_pointer(*label_idx, last_index);
1195 }
1196 }
1197 }
1198 } else {
1199 for label_idx in &labels_written {
1202 encoder.store_label_pointer(*label_idx, last_index);
1203 }
1204 }
1205
1206 encoder.emit(0)?;
1209
1210 let length = encoder.len() - buf_len;
1212 if length > 255 {
1213 return Err(DecodeError::DomainNameTooLong(length).into());
1214 }
1215
1216 Ok(())
1217 }
1218}
1219
1220const COMPRESSED_NAME_LIMIT: usize = 120;
1225
1226impl<'r> BinDecodable<'r> for Name {
1227 fn read(decoder: &mut BinDecoder<'r>) -> Result<Self, DecodeError> {
1232 let mut name = Self::default();
1233 read_inner(decoder, &mut name, None)?;
1234 Ok(name)
1235 }
1236}
1237
1238fn read_inner(
1239 decoder: &mut BinDecoder<'_>,
1240 name: &mut Name,
1241 max_idx: Option<usize>,
1242) -> Result<(), DecodeError> {
1243 let mut state: LabelParseState = LabelParseState::LabelLengthOrPointer;
1244 let name_start = decoder.index();
1245
1246 loop {
1252 if let Some(max_idx) = max_idx {
1254 if decoder.index() >= max_idx {
1255 return Err(DecodeError::LabelOverlapsWithOther {
1256 label: name_start,
1257 other: max_idx,
1258 });
1259 }
1260 }
1261
1262 state = match state {
1263 LabelParseState::LabelLengthOrPointer => {
1264 match decoder
1266 .peek()
1267 .map(Restrict::unverified )
1268 {
1269 Some(0) => {
1270 name.set_fqdn(true);
1280 LabelParseState::Root
1281 }
1282 None => {
1283 return Err(DecodeError::InsufficientBytes);
1286 }
1287 Some(byte) if byte & 0b1100_0000 == 0b1100_0000 => LabelParseState::Pointer,
1288 Some(byte) if byte & 0b1100_0000 == 0b0000_0000 => LabelParseState::Label,
1289 Some(byte) => return Err(DecodeError::UnrecognizedLabelCode(byte)),
1290 }
1291 }
1292 LabelParseState::Label => {
1294 let label = decoder
1295 .read_character_data()?
1296 .verify_unwrap(|l| l.len() <= 63)
1297 .map_err(|l| DecodeError::LabelBytesTooLong(l.len()))?;
1298
1299 name.extend_name(label)
1300 .map_err(|_| DecodeError::DomainNameTooLong(label.len()))?;
1301
1302 LabelParseState::LabelLengthOrPointer
1304 }
1305 LabelParseState::Pointer => {
1327 let pointer_location = decoder.index();
1328 let location = decoder
1329 .read_u16()?
1330 .map(|u| {
1331 u & 0x3FFF
1333 })
1334 .verify_unwrap(|ptr| {
1335 (*ptr as usize) < name_start
1337 })
1338 .map_err(|e| DecodeError::PointerNotPriorToLabel {
1339 idx: pointer_location,
1340 ptr: e,
1341 })?;
1342
1343 let mut pointer = decoder.clone(location);
1344 read_inner(&mut pointer, name, Some(name_start))?;
1345
1346 break;
1348 }
1349 LabelParseState::Root => {
1350 decoder.pop()?;
1352 break;
1353 }
1354 }
1355 }
1356
1357 let len = name.len();
1359 if len >= 255 {
1360 return Err(DecodeError::DomainNameTooLong(len));
1361 }
1362
1363 Ok(())
1364}
1365
1366impl fmt::Display for Name {
1367 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1368 self.write_labels::<fmt::Formatter<'_>, LabelEncUtf8>(f)
1369 }
1370}
1371
1372impl PartialOrd<Self> for Name {
1373 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1374 Some(self.cmp(other))
1375 }
1376}
1377
1378impl Ord for Name {
1379 fn cmp(&self, other: &Self) -> Ordering {
1415 self.cmp_with_f::<CaseInsensitive>(other)
1416 }
1417}
1418
1419enum LabelParseState {
1421 LabelLengthOrPointer, Label, Pointer, Root, }
1426
1427impl FromStr for Name {
1428 type Err = ProtoError;
1429
1430 fn from_str(s: &str) -> Result<Self, Self::Err> {
1432 Self::from_str_relaxed(s)
1433 }
1434}
1435
1436pub trait IntoName: Sized {
1438 fn into_name(self) -> ProtoResult<Name>;
1440
1441 fn to_ip(&self) -> Option<IpAddr>;
1443}
1444
1445impl IntoName for &str {
1446 fn into_name(self) -> ProtoResult<Name> {
1448 Name::from_utf8(self)
1449 }
1450
1451 fn to_ip(&self) -> Option<IpAddr> {
1452 IpAddr::from_str(self).ok()
1453 }
1454}
1455
1456impl IntoName for String {
1457 fn into_name(self) -> ProtoResult<Name> {
1459 Name::from_utf8(self)
1460 }
1461
1462 fn to_ip(&self) -> Option<IpAddr> {
1463 IpAddr::from_str(self).ok()
1464 }
1465}
1466
1467impl IntoName for &String {
1468 fn into_name(self) -> ProtoResult<Name> {
1470 Name::from_utf8(self)
1471 }
1472
1473 fn to_ip(&self) -> Option<IpAddr> {
1474 IpAddr::from_str(self).ok()
1475 }
1476}
1477
1478impl<T> IntoName for T
1479where
1480 T: Into<Name>,
1481{
1482 fn into_name(self) -> ProtoResult<Name> {
1483 Ok(self.into())
1484 }
1485
1486 fn to_ip(&self) -> Option<IpAddr> {
1487 None
1488 }
1489}
1490
1491#[cfg(feature = "serde")]
1492impl Serialize for Name {
1493 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1494 where
1495 S: Serializer,
1496 {
1497 serializer.serialize_str(&self.to_string())
1498 }
1499}
1500
1501#[cfg(feature = "serde")]
1502impl<'de> Deserialize<'de> for Name {
1503 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1504 where
1505 D: Deserializer<'de>,
1506 {
1507 let s = String::deserialize(deserializer)?;
1508 FromStr::from_str(&s).map_err(de::Error::custom)
1509 }
1510}
1511
1512#[cfg(test)]
1513mod tests {
1514 #![allow(clippy::dbg_macro, clippy::print_stdout)]
1515
1516 use alloc::string::ToString;
1517 use core::cmp::Ordering;
1518 #[cfg(feature = "std")]
1519 use std::{collections::hash_map::DefaultHasher, println};
1520
1521 use super::*;
1522 use crate::error::ProtoError;
1523 use crate::serialize::binary::bin_tests::{test_emit_data_set, test_read_data_set};
1524
1525 fn get_data() -> Vec<(Name, Vec<u8>)> {
1526 vec![
1527 (Name::from_str(".").unwrap(), vec![0]), (Name::from_str("a.").unwrap(), vec![1, b'a', 0]), (
1530 Name::from_str("a.bc.").unwrap(),
1531 vec![1, b'a', 2, b'b', b'c', 0],
1532 ), (
1534 Name::from_str("a.♥.").unwrap(),
1535 vec![1, b'a', 7, b'x', b'n', b'-', b'-', b'g', b'6', b'h', 0],
1536 ), ]
1538 }
1539
1540 #[test]
1541 fn test_num_labels() {
1542 assert_eq!(Name::from_str("*").unwrap().num_labels(), 0);
1543 assert_eq!(Name::from_str("a").unwrap().num_labels(), 1);
1544 assert_eq!(Name::from_str("*.b").unwrap().num_labels(), 1);
1545 assert_eq!(Name::from_str("a.b").unwrap().num_labels(), 2);
1546 assert_eq!(Name::from_str("*.b.c").unwrap().num_labels(), 2);
1547 assert_eq!(Name::from_str("a.b.c").unwrap().num_labels(), 3);
1548 }
1549
1550 #[test]
1551 fn test_read() {
1552 test_read_data_set(get_data(), |mut d| Name::read(&mut d));
1553 }
1554
1555 #[test]
1556 fn test_write_to() {
1557 test_emit_data_set(get_data(), |e, n| n.emit(e));
1558 }
1559
1560 #[test]
1561 fn test_pointer() {
1562 let mut bytes = Vec::with_capacity(512);
1563
1564 let first = Name::from_str("ra.rb.rc.").unwrap();
1565 let second = Name::from_str("rb.rc.").unwrap();
1566 let third = Name::from_str("rc.").unwrap();
1567 let fourth = Name::from_str("z.ra.rb.rc.").unwrap();
1568
1569 {
1570 let mut e = BinEncoder::new(&mut bytes);
1571
1572 first.emit(&mut e).unwrap();
1573 assert_eq!(e.len(), 10); second.emit(&mut e).unwrap();
1576 assert_eq!(e.len(), 12);
1578
1579 third.emit(&mut e).unwrap();
1580 assert_eq!(e.len(), 14);
1581
1582 fourth.emit(&mut e).unwrap();
1583 assert_eq!(e.len(), 18);
1584 }
1585
1586 let mut d = BinDecoder::new(&bytes);
1588
1589 let r_test = Name::read(&mut d).unwrap();
1590 assert_eq!(first, r_test);
1591
1592 let r_test = Name::read(&mut d).unwrap();
1593 assert_eq!(second, r_test);
1594
1595 let r_test = Name::read(&mut d).unwrap();
1596 assert_eq!(third, r_test);
1597
1598 let r_test = Name::read(&mut d).unwrap();
1599 assert_eq!(fourth, r_test);
1600 }
1601
1602 #[test]
1603 fn test_pointer_with_pointer_ending_labels() {
1604 let mut bytes: Vec<u8> = Vec::with_capacity(512);
1605
1606 let first = Name::from_str("ra.rb.rc.").unwrap();
1607 let second = Name::from_str("ra.rc.").unwrap();
1608 let third = Name::from_str("ra.rc.").unwrap();
1609
1610 {
1611 let mut e = BinEncoder::new(&mut bytes);
1612
1613 first.emit(&mut e).unwrap();
1614 assert_eq!(e.len(), 10);
1615
1616 second.emit(&mut e).unwrap();
1617 assert_eq!(e.len(), 15);
1619
1620 third.emit(&mut e).unwrap();
1622 assert_eq!(e.len(), 17);
1623 }
1624
1625 let mut d = BinDecoder::new(&bytes);
1627
1628 let r_test = Name::read(&mut d).unwrap();
1629 assert_eq!(first, r_test);
1630
1631 let r_test = Name::read(&mut d).unwrap();
1632 assert_eq!(second, r_test);
1633
1634 let r_test = Name::read(&mut d).unwrap();
1635 assert_eq!(third, r_test);
1636 }
1637
1638 #[test]
1639 fn test_recursive_pointer() {
1640 let bytes = vec![0xC0, 0x01];
1642 let mut d = BinDecoder::new(&bytes);
1643
1644 assert!(Name::read(&mut d).is_err());
1645
1646 let bytes = vec![0xC0, 0x00];
1648 let mut d = BinDecoder::new(&bytes);
1649
1650 assert!(Name::read(&mut d).is_err());
1651
1652 let bytes = vec![0x01, 0x41, 0xC0, 0x00];
1654 let mut d = BinDecoder::new(&bytes);
1655
1656 assert!(Name::read(&mut d).is_err());
1657
1658 let bytes = vec![0xC0, 0x02, 0xC0, 0x00];
1661 let mut d = BinDecoder::new(&bytes);
1662
1663 assert!(Name::read(&mut d).is_err());
1664 }
1665
1666 #[test]
1667 fn test_bin_overlap_enforced() {
1668 let mut bytes: Vec<u8> = Vec::with_capacity(512);
1669 let n: u8 = 31;
1670 for _ in 0..=5 {
1671 bytes.extend(core::iter::repeat_n(n, n as usize));
1672 }
1673 bytes.push(n + 1);
1674 for b in 0..n {
1675 bytes.push(1 + n + b);
1676 }
1677 bytes.extend_from_slice(&[1, 0]);
1678 for b in 0..n {
1679 bytes.extend_from_slice(&[0xC0, b]);
1680 }
1681 let mut d = BinDecoder::new(&bytes);
1682 d.read_slice(n as usize).unwrap();
1683 assert!(Name::read(&mut d).is_err());
1684 }
1685
1686 #[test]
1687 fn test_bin_max_octets() {
1688 let mut bytes = Vec::with_capacity(512);
1689 for _ in 0..256 {
1690 bytes.extend_from_slice(&[1, b'a']);
1691 }
1692 bytes.push(0);
1693
1694 let mut d = BinDecoder::new(&bytes);
1695 assert!(Name::read(&mut d).is_err());
1696 }
1697
1698 #[test]
1699 fn test_base_name() {
1700 let zone = Name::from_str("example.com.").unwrap();
1701
1702 assert_eq!(zone.base_name(), Name::from_str("com.").unwrap());
1703 assert!(zone.base_name().base_name().is_root());
1704 assert!(zone.base_name().base_name().base_name().is_root());
1705 }
1706
1707 #[test]
1708 fn test_zone_of() {
1709 let zone = Name::from_str("example.com").unwrap();
1710 let www = Name::from_str("www.example.com").unwrap();
1711 let none = Name::from_str("none.com").unwrap();
1712 let root = Name::root();
1713
1714 assert!(zone.zone_of(&zone));
1715 assert!(zone.zone_of(&www));
1716 assert!(!zone.zone_of(&none));
1717 assert!(root.zone_of(&zone));
1718 assert!(!zone.zone_of(&root));
1719 }
1720
1721 #[test]
1722 fn test_zone_of_case() {
1723 let zone = Name::from_ascii("examplE.cOm").unwrap();
1724 let www = Name::from_str("www.example.com").unwrap();
1725 let none = Name::from_str("none.com").unwrap();
1726
1727 assert!(zone.zone_of(&zone));
1728 assert!(zone.zone_of(&www));
1729 assert!(!zone.zone_of(&none))
1730 }
1731
1732 #[test]
1733 fn test_partial_cmp_eq() {
1734 let root = Some(Name::from_labels(Vec::<&str>::new()).unwrap());
1735 let comparisons: Vec<(Name, Name)> = vec![
1736 (root.clone().unwrap(), root.clone().unwrap()),
1737 (
1738 Name::parse("example.", root.as_ref()).unwrap(),
1739 Name::parse("example", root.as_ref()).unwrap(),
1740 ),
1741 ];
1742
1743 for (left, right) in comparisons {
1744 #[cfg(feature = "std")]
1745 println!("left: {left}, right: {right}");
1746 assert_eq!(left.partial_cmp(&right), Some(Ordering::Equal));
1747 }
1748 }
1749
1750 #[test]
1751 fn test_partial_cmp() {
1752 let comparisons: Vec<(Name, Name)> = vec![
1753 (
1754 Name::from_str("example.").unwrap(),
1755 Name::from_str("a.example.").unwrap(),
1756 ),
1757 (
1758 Name::from_str("a.example.").unwrap(),
1759 Name::from_str("yljkjljk.a.example.").unwrap(),
1760 ),
1761 (
1762 Name::from_str("yljkjljk.a.example.").unwrap(),
1763 Name::from_ascii("Z.a.example.").unwrap(),
1764 ),
1765 (
1766 Name::from_ascii("Z.a.example").unwrap(),
1767 Name::from_ascii("zABC.a.EXAMPLE.").unwrap(),
1768 ),
1769 (
1770 Name::from_ascii("zABC.a.EXAMPLE.").unwrap(),
1771 Name::from_str("z.example.").unwrap(),
1772 ),
1773 (
1774 Name::from_str("z.example").unwrap(),
1775 Name::from_labels(vec![&[1u8] as &[u8], b"z", b"example."]).unwrap(),
1776 ),
1777 (
1778 Name::from_labels(vec![&[1u8] as &[u8], b"z", b"example"]).unwrap(),
1779 Name::from_str("*.z.example.").unwrap(),
1780 ),
1781 (
1782 Name::from_str("*.z.example").unwrap(),
1783 Name::from_labels(vec![&[200u8] as &[u8], b"z", b"example."]).unwrap(),
1784 ),
1785 ];
1786
1787 for (left, right) in comparisons {
1788 #[cfg(feature = "std")]
1789 println!("left: {left}, right: {right}");
1790 assert_eq!(left.cmp(&right), Ordering::Less);
1791 }
1792 }
1793
1794 #[test]
1795 fn test_cmp_ignore_case() {
1796 let comparisons: Vec<(Name, Name)> = vec![
1797 (
1798 Name::from_ascii("ExAmPle.").unwrap(),
1799 Name::from_ascii("example.").unwrap(),
1800 ),
1801 (
1802 Name::from_ascii("A.example.").unwrap(),
1803 Name::from_ascii("a.example.").unwrap(),
1804 ),
1805 ];
1806
1807 for (left, right) in comparisons {
1808 #[cfg(feature = "std")]
1809 println!("left: {left}, right: {right}");
1810 assert_eq!(left, right);
1811 }
1812 }
1813
1814 #[test]
1815 fn test_from_ipv4() {
1816 let ip = IpAddr::V4(Ipv4Addr::new(26, 3, 0, 103));
1817 let name = Name::from_str("103.0.3.26.in-addr.arpa.").unwrap();
1818
1819 assert_eq!(Into::<Name>::into(ip), name);
1820 }
1821
1822 #[test]
1823 fn test_from_ipv6() {
1824 let ip = IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x1));
1825 let name = Name::from_str(
1826 "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.",
1827 )
1828 .unwrap();
1829
1830 assert_eq!(Into::<Name>::into(ip), name);
1831 }
1832
1833 #[test]
1834 fn test_from_str() {
1835 assert_eq!(
1836 Name::from_str("www.example.com.").unwrap(),
1837 Name::from_labels(vec![b"www" as &[u8], b"example", b"com"]).unwrap()
1838 );
1839 assert_eq!(
1840 Name::from_str(".").unwrap(),
1841 Name::from_labels(Vec::<&str>::new()).unwrap()
1842 );
1843 }
1844
1845 #[test]
1846 fn test_fqdn() {
1847 assert!(Name::root().is_fqdn());
1848 assert!(Name::from_str(".").unwrap().is_fqdn());
1849 assert!(Name::from_str("www.example.com.").unwrap().is_fqdn());
1850 assert!(
1851 Name::from_labels(vec![b"www" as &[u8], b"example", b"com"])
1852 .unwrap()
1853 .is_fqdn()
1854 );
1855
1856 assert!(!Name::new().is_fqdn());
1857 assert!(!Name::from_str("www.example.com").unwrap().is_fqdn());
1858 assert!(!Name::from_str("www.example").unwrap().is_fqdn());
1859 assert!(!Name::from_str("www").unwrap().is_fqdn());
1860 }
1861
1862 #[test]
1863 fn test_to_string() {
1864 assert_eq!(
1865 Name::from_str("www.example.com.").unwrap().to_string(),
1866 "www.example.com."
1867 );
1868 assert_eq!(
1869 Name::from_str("www.example.com").unwrap().to_string(),
1870 "www.example.com"
1871 );
1872 }
1873
1874 #[test]
1875 fn test_from_ascii() {
1876 let bytes_name = Name::from_labels(vec![b"WWW" as &[u8], b"example", b"COM"]).unwrap();
1877 let ascii_name = Name::from_ascii("WWW.example.COM.").unwrap();
1878 let lower_name = Name::from_ascii("www.example.com.").unwrap();
1879
1880 assert!(bytes_name.eq_case(&ascii_name));
1881 assert!(!lower_name.eq_case(&ascii_name));
1882 }
1883
1884 #[test]
1885 fn test_from_utf8() {
1886 let bytes_name = Name::from_labels(vec![b"WWW" as &[u8], b"example", b"COM"]).unwrap();
1887 let utf8_name = Name::from_utf8("WWW.example.COM.").unwrap();
1888 let lower_name = Name::from_utf8("www.example.com.").unwrap();
1889
1890 assert!(!bytes_name.eq_case(&utf8_name));
1891 assert!(lower_name.eq_case(&utf8_name));
1892 }
1893
1894 #[test]
1895 fn test_into_name() {
1896 let name = Name::from_utf8("www.example.com").unwrap();
1897 assert_eq!(Name::from_utf8("www.example.com").unwrap(), name);
1898 assert_eq!(
1899 Name::from_utf8("www.example.com").unwrap(),
1900 Name::from_utf8("www.example.com")
1901 .unwrap()
1902 .into_name()
1903 .unwrap()
1904 );
1905 assert_eq!(
1906 Name::from_utf8("www.example.com").unwrap(),
1907 "www.example.com".into_name().unwrap()
1908 );
1909 assert_eq!(
1910 Name::from_utf8("www.example.com").unwrap(),
1911 "www.example.com".to_string().into_name().unwrap()
1912 );
1913 }
1914
1915 #[test]
1916 fn test_encoding() {
1917 assert_eq!(
1918 Name::from_ascii("WWW.example.COM.").unwrap().to_ascii(),
1919 "WWW.example.COM."
1920 );
1921 assert_eq!(
1922 Name::from_utf8("WWW.example.COM.").unwrap().to_ascii(),
1923 "www.example.com."
1924 );
1925 assert_eq!(
1926 Name::from_ascii("WWW.example.COM.").unwrap().to_utf8(),
1927 "WWW.example.COM."
1928 );
1929 }
1930
1931 #[test]
1932 fn test_excessive_encoding_len() {
1933 use crate::error::ProtoError;
1934
1935 let mut buf = Vec::with_capacity(u16::MAX as usize);
1937 let mut encoder = BinEncoder::new(&mut buf);
1938
1939 let mut result = Ok(());
1940 for i in 0..10000 {
1941 let name = Name::from_ascii(format!("name{i}.example.com.")).unwrap();
1942 result = name.emit(&mut encoder);
1943 if result.is_err() {
1944 break;
1945 }
1946 }
1947
1948 match result.unwrap_err() {
1949 ProtoError::MaxBufferSizeExceeded(_) => (),
1950 _ => panic!(),
1951 }
1952 }
1953
1954 #[test]
1955 fn test_underscore() {
1956 Name::from_str("_begin.example.com").expect("failed at beginning");
1957 Name::from_str_relaxed("mid_dle.example.com").expect("failed in the middle");
1958 Name::from_str_relaxed("end_.example.com").expect("failed at the end");
1959 }
1960
1961 #[test]
1962 fn test_parse_arpa_name() {
1963 assert!(
1964 Name::from_ascii("168.192.in-addr.arpa")
1965 .unwrap()
1966 .parse_arpa_name()
1967 .is_err()
1968 );
1969 assert!(
1970 Name::from_ascii("host.example.com.")
1971 .unwrap()
1972 .parse_arpa_name()
1973 .is_err()
1974 );
1975 assert!(
1976 Name::from_ascii("caffee.ip6.arpa.")
1977 .unwrap()
1978 .parse_arpa_name()
1979 .is_err()
1980 );
1981 assert!(
1982 Name::from_ascii(
1983 "1.4.3.3.7.0.7.3.0.E.2.A.8.9.1.3.1.3.D.8.0.3.A.5.8.8.B.D.0.1.0.0.2.ip6.arpa."
1984 )
1985 .unwrap()
1986 .parse_arpa_name()
1987 .is_err()
1988 );
1989 assert!(
1990 Name::from_ascii("caffee.in-addr.arpa.")
1991 .unwrap()
1992 .parse_arpa_name()
1993 .is_err()
1994 );
1995 assert!(
1996 Name::from_ascii("1.2.3.4.5.in-addr.arpa.")
1997 .unwrap()
1998 .parse_arpa_name()
1999 .is_err()
2000 );
2001 assert!(
2002 Name::from_ascii("1.2.3.4.home.arpa.")
2003 .unwrap()
2004 .parse_arpa_name()
2005 .is_err()
2006 );
2007 assert_eq!(
2008 Name::from_ascii("168.192.in-addr.arpa.")
2009 .unwrap()
2010 .parse_arpa_name()
2011 .unwrap(),
2012 IpNet::V4(Ipv4Net::new("192.168.0.0".parse().unwrap(), 16).unwrap())
2013 );
2014 assert_eq!(
2015 Name::from_ascii("1.0.168.192.in-addr.arpa.")
2016 .unwrap()
2017 .parse_arpa_name()
2018 .unwrap(),
2019 IpNet::V4(Ipv4Net::new("192.168.0.1".parse().unwrap(), 32).unwrap())
2020 );
2021 assert_eq!(
2022 Name::from_ascii("0.1.0.0.2.ip6.arpa.")
2023 .unwrap()
2024 .parse_arpa_name()
2025 .unwrap(),
2026 IpNet::V6(Ipv6Net::new("2001::".parse().unwrap(), 20).unwrap())
2027 );
2028 assert_eq!(
2029 Name::from_ascii("D.0.1.0.0.2.ip6.arpa.")
2030 .unwrap()
2031 .parse_arpa_name()
2032 .unwrap(),
2033 IpNet::V6(Ipv6Net::new("2001:d00::".parse().unwrap(), 24).unwrap())
2034 );
2035 assert_eq!(
2036 Name::from_ascii("B.D.0.1.0.0.2.ip6.arpa.")
2037 .unwrap()
2038 .parse_arpa_name()
2039 .unwrap(),
2040 IpNet::V6(Ipv6Net::new("2001:db0::".parse().unwrap(), 28).unwrap())
2041 );
2042 assert_eq!(
2043 Name::from_ascii("8.B.D.0.1.0.0.2.ip6.arpa.")
2044 .unwrap()
2045 .parse_arpa_name()
2046 .unwrap(),
2047 IpNet::V6(Ipv6Net::new("2001:db8::".parse().unwrap(), 32).unwrap())
2048 );
2049 assert_eq!(
2050 Name::from_ascii(
2051 "4.3.3.7.0.7.3.0.E.2.A.8.9.1.3.1.3.D.8.0.3.A.5.8.8.B.D.0.1.0.0.2.ip6.arpa."
2052 )
2053 .unwrap()
2054 .parse_arpa_name()
2055 .unwrap(),
2056 IpNet::V6(
2057 Ipv6Net::new("2001:db8:85a3:8d3:1319:8a2e:370:7334".parse().unwrap(), 128).unwrap()
2058 )
2059 );
2060 }
2061
2062 #[test]
2063 fn test_prepend_label() {
2064 for name in ["foo.com", "foo.com."] {
2065 let name = Name::from_ascii(name).unwrap();
2066
2067 for label in ["bar", "baz", "quux"] {
2068 let sub = name.clone().prepend_label(label).unwrap();
2069 let expected = Name::from_ascii(format!("{label}.{name}")).unwrap();
2070 assert_eq!(expected, sub);
2071 }
2072 }
2073
2074 for name in ["", "."] {
2075 let name = Name::from_ascii(name).unwrap();
2076
2077 for label in ["bar", "baz", "quux"] {
2078 let sub = name.clone().prepend_label(label).unwrap();
2079 let expected = Name::from_ascii(format!("{label}{name}")).unwrap();
2080 assert_eq!(expected, sub);
2081 }
2082 }
2083 }
2084
2085 #[test]
2086 fn test_name_too_long_with_prepend() {
2087 let n = Name::from_ascii("Llocainvannnnnnaxgtezqzqznnnnnn1na.nnntnninvannnnnnaxgtezqzqznnnnnn1na.nnntnnnnnnnaxgtezqzqznnnnnn1na.nnntnaaaaaaaaaaaaaaaaaaaaaaaaiK.iaaaaaaaaaaaaaaaaaaaaaaaaiKa.innnnnaxgtezqzqznnnnnn1na.nnntnaaaaaaaaaaaaaaaaaaaaaaaaiK.iaaaaaaaaaaaaaaaaaaaaaaaaiKa.in").unwrap();
2088 let sfx = "xxxxxxx.yyyyy.zzz";
2089
2090 let error = n
2091 .prepend_label(sfx)
2092 .expect_err("should have errored, too long");
2093
2094 match error {
2095 ProtoError::Decode(DecodeError::DomainNameTooLong(_)) => (),
2096 _ => panic!("expected too long message"),
2097 }
2098 }
2099
2100 #[test]
2101 fn test_name_too_long_with_append() {
2102 let n = Name::from_ascii("Llocainvannnnnnaxgtezqzqznnnnnn1na.nnntnninvannnnnnaxgtezqzqznnnnnn1na.nnntnnnnnnnaxgtezqzqznnnnnn1na.nnntnaaaaaaaaaaaaaaaaaaaaaaaaiK.iaaaaaaaaaaaaaaaaaaaaaaaaiKa.innnnnaxgtezqzqznnnnnn1na.nnntnaaaaaaaaaaaaaaaaaaaaaaaaiK.iaaaaaaaaaaaaaaaaaaaaaaaaiKa.in").unwrap();
2104 let sfx = Name::from_ascii("xxxxxxx.yyyyy.zzz").unwrap();
2105
2106 let error = n
2107 .append_domain(&sfx)
2108 .expect_err("should have errored, too long");
2109
2110 match error {
2111 ProtoError::Decode(DecodeError::DomainNameTooLong(_)) => (),
2112 _ => panic!("expected too long message"),
2113 }
2114 }
2115
2116 #[test]
2117 fn test_encoded_len() {
2118 for name in [
2119 Name::parse("www.example.com.", None).unwrap(),
2121 Name::parse("www", None).unwrap(),
2123 Name::root(),
2125 Name::new(),
2127 ] {
2128 let mut buffer = Vec::new();
2129 let mut encoder = BinEncoder::new(&mut buffer);
2130 name.emit(&mut encoder).unwrap();
2131
2132 assert_eq!(
2133 name.encoded_len(),
2134 buffer.len(),
2135 "encoded_len() was incorrect for {name:?}"
2136 );
2137 }
2138 }
2139
2140 #[test]
2141 fn test_length_limits() {
2142 let encoded_name_255_bytes: [u8; 255] = [
2147 63, b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2148 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2149 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2150 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2151 b'a', b'a', b'a', b'a', b'a', b'a', b'a', 63, b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2152 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2153 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2154 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2155 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', 63,
2156 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2157 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2158 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2159 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2160 b'a', b'a', b'a', b'a', b'a', b'a', b'a', 61, b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2161 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2162 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2163 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a',
2164 b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', 0,
2165 ];
2166 let expected_name_str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.\
2167 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.\
2168 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.\
2169 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.";
2170
2171 let mut decoder = BinDecoder::new(&encoded_name_255_bytes);
2172 let decoded_name = Name::read(&mut decoder).unwrap();
2173 assert!(decoder.is_empty());
2174
2175 assert_eq!(decoded_name.to_string(), expected_name_str);
2176
2177 let long_label_error = Name::parse(&format!("a{expected_name_str}"), None).unwrap_err();
2179 assert!(matches!(
2180 long_label_error,
2181 ProtoError::Decode(DecodeError::LabelBytesTooLong(64))
2182 ));
2183 let long_name_error =
2184 Name::parse(&format!("a.{}", &expected_name_str[1..]), None).unwrap_err();
2185 assert!(matches!(
2186 long_name_error,
2187 ProtoError::Decode(DecodeError::DomainNameTooLong(256))
2188 ))
2189 }
2190
2191 #[test]
2192 fn test_double_ended_iterator() {
2193 let name = Name::from_ascii("www.example.com").unwrap();
2194 let mut iter = name.iter();
2195
2196 assert_eq!(iter.next().unwrap(), b"www");
2197 assert_eq!(iter.next_back().unwrap(), b"com");
2198 assert_eq!(iter.next().unwrap(), b"example");
2199 assert!(iter.next_back().is_none());
2200 assert!(iter.next().is_none());
2201 }
2202
2203 #[test]
2204 fn test_size_hint() {
2205 let name = Name::from_ascii("www.example.com").unwrap();
2206 let mut iter = name.iter();
2207
2208 assert_eq!(iter.size_hint().0, 3);
2209 assert_eq!(iter.next().unwrap(), b"www");
2210 assert_eq!(iter.size_hint().0, 2);
2211 assert_eq!(iter.next_back().unwrap(), b"com");
2212 assert_eq!(iter.size_hint().0, 1);
2213 assert_eq!(iter.next().unwrap(), b"example");
2214 assert_eq!(iter.size_hint().0, 0);
2215 assert!(iter.next_back().is_none());
2216 assert_eq!(iter.size_hint().0, 0);
2217 assert!(iter.next().is_none());
2218 assert_eq!(iter.size_hint().0, 0);
2219 }
2220
2221 #[test]
2222 #[cfg(feature = "std")]
2223 fn test_label_randomization() {
2224 let mut name = Name::root();
2225 name.randomize_label_case();
2226 assert!(name.eq_case(&Name::root()));
2227
2228 for qname in [
2229 "x",
2230 "0",
2231 "aaaaaaaaaaaaaaaa",
2232 "AAAAAAAAAAAAAAAA",
2233 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.",
2234 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.",
2235 "abcdefghijklmnopqrstuvwxyz0123456789A.",
2236 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.",
2237 "www01.example-site.com",
2238 "1234567890.e-1204089_043820-5.com.",
2239 ] {
2240 let mut name = Name::from_ascii(qname).unwrap();
2241 let name2 = name.clone();
2242 name.randomize_label_case();
2243 assert_eq!(name, name2);
2244 println!("{name2} == {name}: {}", name == name2);
2245 }
2246
2247 let iterations = 50_000;
2250
2251 let test_str = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.lmnopqrstuvwxyzabcdefghjijklmnopqrstuvwxyzabcdefghijklmnopqrstu.vwxyzABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF.GHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNO";
2254 let mut name = Name::from_ascii(test_str).unwrap();
2255 let name2 = name.clone();
2256
2257 let len = name.label_data.len();
2258 let mut cap_table: [u32; 255] = [0; 255];
2259 let mut lower_table: [u32; 255] = [0; 255];
2260 let mut mean_table: [f64; 255] = [0.0; 255];
2261
2262 for _ in 0..iterations {
2263 name.randomize_label_case();
2264 assert_eq!(name, name2);
2265
2266 for (j, &cbyte) in name.label_data.iter().enumerate() {
2267 if cbyte.is_ascii_lowercase() {
2268 lower_table[j] += 1;
2269 } else if cbyte.is_ascii_uppercase() {
2270 cap_table[j] += 1;
2271 }
2272 }
2273 name = Name::from_ascii(test_str).unwrap();
2274 }
2275
2276 println!("Distribution of lower case values by label offset");
2277 println!("-------------------------------------------------");
2278 for i in 0..len {
2279 let cap_ratio = cap_table[i] as f64 / iterations as f64;
2280 let lower_ratio = lower_table[i] as f64 / iterations as f64;
2281 let total_ratio = cap_ratio + lower_ratio;
2282 mean_table[i] = lower_ratio;
2283 println!(
2284 "{i:03} {:.3}% {:.3}% {:.3}%",
2285 cap_ratio * 100.0,
2286 lower_ratio * 100.0,
2287 total_ratio * 100.0,
2288 );
2289 }
2290 println!("-------------------------------------------------");
2291
2292 let data_mean = mean_table.iter().sum::<f64>() / len as f64;
2293 let data_std_deviation = std_deviation(data_mean, &mean_table);
2294
2295 let mut max_zscore = 0.0;
2296 for elem in mean_table.iter() {
2297 let zscore = (elem - data_mean) / data_std_deviation;
2298
2299 if zscore > max_zscore {
2300 max_zscore = zscore;
2301 }
2302 }
2303
2304 println!("μ: {data_mean:.4} σ: {data_std_deviation:.4}, max variance: {max_zscore:.4}σ");
2305
2306 assert!(data_mean > 0.485 && data_mean < 0.515);
2317 assert!(data_std_deviation < 0.18);
2318 assert!(max_zscore < 0.33);
2319 }
2320
2321 #[cfg(feature = "std")]
2322 fn std_deviation(mean: f64, data: &[f64]) -> f64 {
2323 match (mean, data.len()) {
2324 (data_mean, count) if count > 0 => {
2325 let variance = data
2326 .iter()
2327 .map(|value| {
2328 let diff = data_mean - *value;
2329
2330 diff * diff
2331 })
2332 .sum::<f64>()
2333 / count as f64;
2334
2335 variance.sqrt()
2336 }
2337 _ => 0.0,
2338 }
2339 }
2340
2341 #[test]
2342 fn test_fqdn_escaped_dot() {
2343 let name = Name::from_utf8("test.").unwrap();
2344 assert!(name.is_fqdn());
2345
2346 let name = Name::from_utf8("test\\.").unwrap();
2347 assert!(!name.is_fqdn());
2348
2349 let name = Name::from_utf8("").unwrap();
2350 assert!(!name.is_fqdn());
2351
2352 let name = Name::from_utf8(".").unwrap();
2353 assert!(name.is_fqdn());
2354 }
2355
2356 #[test]
2357 #[allow(clippy::nonminimal_bool)]
2358 fn test_name_partialeq_constraints() {
2359 let example_fqdn = Name::from_utf8("example.com.").unwrap();
2360 let example_nonfqdn = Name::from_utf8("example.com").unwrap();
2361 let other_fqdn = Name::from_utf8("otherdomain.com.").unwrap();
2362
2363 assert_eq!(example_fqdn, example_fqdn);
2364 assert_eq!(example_nonfqdn, example_nonfqdn);
2365 assert!(example_fqdn != example_nonfqdn);
2366
2367 assert!(example_fqdn != example_nonfqdn && !(example_fqdn == example_nonfqdn));
2369 assert!(example_nonfqdn != example_fqdn && !(example_nonfqdn == example_fqdn));
2370 assert!(example_fqdn != other_fqdn && !(example_fqdn == other_fqdn));
2371 assert!(example_nonfqdn != other_fqdn && !(example_nonfqdn == other_fqdn));
2372 }
2373
2374 #[test]
2375 fn test_name_partialord_constraints() {
2376 use core::cmp::Ordering::*;
2377
2378 let example_fqdn = Name::from_utf8("example.com.").unwrap();
2379 let foo_example_fqdn = Name::from_utf8("foo.example.com.").unwrap();
2380 let example_nonfqdn = Name::from_utf8("example.com").unwrap();
2381 let foo_example_nonfqdn = Name::from_utf8("foo.example.com").unwrap();
2382
2383 assert_eq!(example_fqdn.partial_cmp(&example_fqdn), Some(Equal),);
2385 assert!(example_fqdn.partial_cmp(&example_nonfqdn) != Some(Equal));
2386
2387 assert!(
2389 example_nonfqdn < example_fqdn
2390 && example_nonfqdn.partial_cmp(&example_fqdn) == Some(Less)
2391 );
2392
2393 assert!(
2394 example_fqdn < foo_example_fqdn
2395 && example_fqdn.partial_cmp(&foo_example_fqdn) == Some(Less)
2396 );
2397
2398 assert!(
2399 example_nonfqdn < foo_example_nonfqdn
2400 && example_nonfqdn.partial_cmp(&foo_example_nonfqdn) == Some(Less)
2401 );
2402
2403 assert!(
2405 example_fqdn > example_nonfqdn
2406 && example_fqdn.partial_cmp(&example_nonfqdn) == Some(Greater)
2407 );
2408
2409 assert!(
2410 foo_example_fqdn > example_fqdn
2411 && foo_example_fqdn.partial_cmp(&example_fqdn) == Some(Greater)
2412 );
2413
2414 assert!(
2415 foo_example_nonfqdn > example_nonfqdn
2416 && foo_example_nonfqdn.partial_cmp(&example_nonfqdn) == Some(Greater)
2417 );
2418
2419 assert!(example_nonfqdn <= example_fqdn);
2421 assert!(example_nonfqdn <= example_nonfqdn);
2422 assert!(example_fqdn <= example_fqdn);
2423 assert!(example_nonfqdn <= foo_example_nonfqdn);
2424 assert!(example_fqdn <= foo_example_fqdn);
2425 assert!(foo_example_nonfqdn <= foo_example_nonfqdn);
2426 assert!(foo_example_fqdn <= foo_example_fqdn);
2427
2428 assert!(example_fqdn >= example_nonfqdn);
2430 assert!(example_nonfqdn >= example_nonfqdn);
2431 assert!(example_fqdn >= example_fqdn);
2432 assert!(foo_example_nonfqdn >= example_nonfqdn);
2433 assert!(foo_example_fqdn >= example_fqdn);
2434 assert!(foo_example_nonfqdn >= foo_example_nonfqdn);
2435 assert!(foo_example_fqdn >= foo_example_fqdn);
2436
2437 }
2439
2440 #[test]
2441 fn test_name_ord_constraints() {
2442 use core::cmp;
2443
2444 let example_fqdn = Name::from_utf8("example.com.").unwrap();
2445 let foo_example_fqdn = Name::from_utf8("foo.example.com.").unwrap();
2446 let example_nonfqdn = Name::from_utf8("example.com").unwrap();
2447 let foo_example_nonfqdn = Name::from_utf8("foo.example.com").unwrap();
2448
2449 for pair in [
2453 (&example_fqdn, &example_fqdn),
2454 (&example_fqdn, &example_nonfqdn),
2455 (&example_fqdn, &foo_example_fqdn),
2456 (&example_fqdn, &foo_example_nonfqdn),
2457 (&example_nonfqdn, &example_nonfqdn),
2458 (&example_nonfqdn, &example_fqdn),
2459 (&example_nonfqdn, &foo_example_fqdn),
2460 (&example_nonfqdn, &foo_example_nonfqdn),
2461 (&foo_example_fqdn, &example_nonfqdn),
2462 (&foo_example_fqdn, &example_fqdn),
2463 (&foo_example_fqdn, &foo_example_fqdn),
2464 (&foo_example_fqdn, &foo_example_nonfqdn),
2465 (&foo_example_fqdn, &example_nonfqdn),
2466 (&foo_example_fqdn, &example_fqdn),
2467 (&foo_example_fqdn, &foo_example_fqdn),
2468 (&foo_example_fqdn, &foo_example_nonfqdn),
2469 ] {
2470 let name1 = pair.0;
2471 let name2 = pair.1;
2472
2473 assert_eq!(name1.partial_cmp(name2), Some(name1.cmp(name2)));
2475
2476 assert_eq!(
2478 name1.clone().max(name2.clone()),
2479 cmp::max_by(name1.clone(), name2.clone(), |x: &Name, y: &Name| x.cmp(y)),
2480 );
2481
2482 assert_eq!(
2484 name1.clone().min(name2.clone()),
2485 cmp::min_by(name1.clone(), name2.clone(), |x: &Name, y: &Name| x.cmp(y)),
2486 );
2487 }
2488
2489 let min_name = Name::from_utf8("com").unwrap();
2497 let max_name = Name::from_utf8("max.example.com.").unwrap();
2498
2499 assert_eq!(
2500 min_name
2501 .clone()
2502 .clamp(min_name.clone(), example_nonfqdn.clone()),
2503 min_name.clone(),
2504 );
2505
2506 assert_eq!(
2507 max_name
2508 .clone()
2509 .clamp(example_nonfqdn.clone(), example_fqdn.clone()),
2510 example_fqdn.clone(),
2511 );
2512
2513 assert_eq!(
2514 max_name
2515 .clone()
2516 .clamp(example_nonfqdn.clone(), max_name.clone()),
2517 max_name.clone(),
2518 );
2519
2520 let most_min_name = Name::from_utf8("").unwrap();
2524 let most_max_name = Name::from_utf8("most.max.example.com.").unwrap();
2525 assert_eq!(min_name.cmp(&example_nonfqdn), Ordering::Less);
2526 assert_eq!(most_min_name.cmp(&min_name), Ordering::Less);
2527 assert_eq!(most_min_name.cmp(&example_nonfqdn), Ordering::Less);
2528 assert_eq!(max_name.cmp(&example_fqdn), Ordering::Greater);
2529 assert_eq!(most_max_name.cmp(&max_name), Ordering::Greater);
2530 assert_eq!(most_max_name.cmp(&example_fqdn), Ordering::Greater);
2531 }
2532
2533 #[test]
2534 #[should_panic]
2535 fn test_ord_clamp_panic() {
2536 let min_name = Name::from_utf8("com").unwrap();
2537 let max_name = Name::from_utf8("max.example.com.").unwrap();
2538
2539 let _ = min_name.clone().clamp(max_name, min_name);
2541 }
2542
2543 #[test]
2544 #[cfg(feature = "std")]
2545 fn test_hash() {
2546 let mut hasher = DefaultHasher::new();
2548 let with_dot = Name::from_utf8("com.").unwrap();
2549 with_dot.hash(&mut hasher);
2550 let hash_with_dot = hasher.finish();
2551
2552 let mut hasher = DefaultHasher::new();
2553 let without_dot = Name::from_utf8("com").unwrap();
2554 without_dot.hash(&mut hasher);
2555 let hash_without_dot = hasher.finish();
2556 assert_ne!(with_dot, without_dot);
2557 assert_ne!(hash_with_dot, hash_without_dot);
2558 }
2559
2560 #[test]
2561 fn eq_ignore_root_tests() {
2562 let fqdn_name = Name::from_utf8("host.example.com.").unwrap();
2563 let relative_name = Name::from_utf8("host.example.com").unwrap();
2564 let upper_relative_name = Name::from_ascii("HOST.EXAMPLE.COM").unwrap();
2565
2566 assert_ne!(fqdn_name, relative_name);
2567 assert!(fqdn_name.eq_ignore_root(&relative_name));
2568 assert!(!fqdn_name.eq_ignore_root_case(&upper_relative_name));
2569 assert!(fqdn_name.eq_ignore_root(&upper_relative_name));
2570 }
2571
2572 #[test]
2573 fn rfc4034_canonical_ordering_example() {
2574 let names = Vec::from([
2576 Name::from_labels::<_, &[u8]>([b"example".as_slice()]).unwrap(),
2577 Name::from_labels::<_, &[u8]>([b"a".as_slice(), b"example".as_slice()]).unwrap(),
2578 Name::from_labels::<_, &[u8]>([
2579 b"yljkjljk".as_slice(),
2580 b"a".as_slice(),
2581 b"example".as_slice(),
2582 ])
2583 .unwrap(),
2584 Name::from_labels::<_, &[u8]>([
2585 b"Z".as_slice(),
2586 b"a".as_slice(),
2587 b"example".as_slice(),
2588 ])
2589 .unwrap(),
2590 Name::from_labels::<_, &[u8]>([
2591 b"zABC".as_slice(),
2592 b"a".as_slice(),
2593 b"EXAMPLE".as_slice(),
2594 ])
2595 .unwrap(),
2596 Name::from_labels::<_, &[u8]>([b"z".as_slice(), b"example".as_slice()]).unwrap(),
2597 Name::from_labels::<_, &[u8]>([
2598 b"\x01".as_slice(),
2599 b"z".as_slice(),
2600 b"example".as_slice(),
2601 ])
2602 .unwrap(),
2603 Name::from_labels::<_, &[u8]>([
2604 b"*".as_slice(),
2605 b"z".as_slice(),
2606 b"example".as_slice(),
2607 ])
2608 .unwrap(),
2609 Name::from_labels::<_, &[u8]>([
2610 b"\x80".as_slice(),
2611 b"z".as_slice(),
2612 b"example".as_slice(),
2613 ])
2614 .unwrap(),
2615 ]);
2616 let mut sorted = names.clone();
2617 sorted.sort();
2618 assert_eq!(names, sorted);
2619 }
2620}