1#[cfg(feature = "serde")]
11use alloc::string::ToString;
12use alloc::{string::String, vec::Vec};
13use core::char;
14use core::cmp::{Ordering, PartialEq};
15use core::fmt::{self, Write};
16use core::hash::{Hash, Hasher};
17#[cfg(not(feature = "std"))]
18use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
19use core::str::FromStr;
20#[cfg(feature = "std")]
21use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
22
23use ipnet::{IpNet, Ipv4Net, Ipv6Net};
24#[cfg(feature = "serde")]
25use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
26use tinyvec::TinyVec;
27
28use crate::error::{ProtoError, ProtoErrorKind, ProtoResult};
29use crate::rr::domain::label::{CaseInsensitive, CaseSensitive, IntoLabel, Label, LabelCmp};
30use crate::rr::domain::usage::LOCALHOST as LOCALHOST_usage;
31use crate::serialize::binary::{
32 BinDecodable, BinDecoder, BinEncodable, BinEncoder, DecodeError, Restrict,
33};
34
35#[derive(Clone, Default, Eq)]
37pub struct Name {
38 is_fqdn: bool,
39 label_data: TinyVec<[u8; 32]>,
40 label_ends: TinyVec<[u8; 24]>,
43}
44
45impl Name {
46 pub const MAX_LENGTH: usize = 255;
48
49 pub fn new() -> Self {
51 Self::default()
52 }
53
54 pub fn root() -> Self {
56 let mut this = Self::new();
57 this.is_fqdn = true;
58 this
59 }
60
61 fn extend_name(&mut self, label: &[u8]) -> Result<(), ProtoError> {
63 let new_len = self.encoded_len() + label.len() + 1;
64
65 if new_len > Self::MAX_LENGTH {
66 return Err(ProtoErrorKind::DomainNameTooLong(new_len).into());
67 };
68
69 self.label_data.extend_from_slice(label);
70 self.label_ends.push(self.label_data.len() as u8);
71
72 Ok(())
73 }
74
75 #[cfg(feature = "std")]
77 pub fn randomize_label_case(&mut self) {
78 let mut rand_bits: u32 = 0;
81
82 for (i, b) in self.label_data.iter_mut().enumerate() {
83 if i % 32 == 0 {
85 rand_bits = rand::random();
86 }
87
88 let flip_case = rand_bits & 1 == 1;
89
90 if b.is_ascii_alphabetic() && flip_case {
91 *b ^= 0x20; }
93
94 rand_bits >>= 1;
95 }
96 }
97
98 pub fn is_root(&self) -> bool {
111 self.label_ends.is_empty() && self.is_fqdn()
112 }
113
114 pub fn is_fqdn(&self) -> bool {
137 self.is_fqdn
138 }
139
140 pub fn set_fqdn(&mut self, val: bool) {
144 self.is_fqdn = val
145 }
146
147 pub fn iter(&self) -> LabelIter<'_> {
149 LabelIter {
150 name: self,
151 start: 0,
152 end: self.label_ends.len() as u8,
153 }
154 }
155
156 pub fn append_label<L: IntoLabel>(mut self, label: L) -> ProtoResult<Self> {
169 self.extend_name(label.into_label()?.as_bytes())?;
170 Ok(self)
171 }
172
173 pub fn prepend_label<L: IntoLabel>(&self, label: L) -> ProtoResult<Self> {
186 let mut name = Self::new().append_label(label)?;
187
188 for label in self.into_iter() {
189 name.extend_name(label)?;
190 }
191
192 name.set_fqdn(self.is_fqdn);
193
194 Ok(name)
195 }
196
197 pub fn from_labels<I, L>(labels: I) -> ProtoResult<Self>
221 where
222 I: IntoIterator<Item = L>,
223 L: IntoLabel,
224 {
225 let (labels, errors): (Vec<_>, Vec<_>) = labels
226 .into_iter()
227 .map(IntoLabel::into_label)
228 .partition(Result::is_ok);
229 let labels: Vec<_> = labels.into_iter().map(Result::unwrap).collect();
230 let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect();
231
232 if labels.len() > 255 {
233 return Err(ProtoErrorKind::DomainNameTooLong(labels.len()).into());
234 };
235 if !errors.is_empty() {
236 return Err(format!("error converting some labels: {errors:?}").into());
237 };
238
239 let mut name = Self {
240 is_fqdn: true,
241 ..Self::default()
242 };
243 for label in labels {
244 name = name.append_label(label)?;
245 }
246
247 Ok(name)
248 }
249
250 pub fn append_name(mut self, other: &Self) -> Result<Self, ProtoError> {
276 for label in other.iter() {
277 self.extend_name(label)?;
278 }
279
280 self.is_fqdn = other.is_fqdn;
281 Ok(self)
282 }
283
284 pub fn append_domain(self, domain: &Self) -> Result<Self, ProtoError> {
302 let mut this = self.append_name(domain)?;
303 this.set_fqdn(true);
304 Ok(this)
305 }
306
307 pub fn to_lowercase(&self) -> Self {
322 let new_label_data = self
323 .label_data
324 .iter()
325 .map(|c| c.to_ascii_lowercase())
326 .collect();
327 Self {
328 is_fqdn: self.is_fqdn,
329 label_data: new_label_data,
330 label_ends: self.label_ends.clone(),
331 }
332 }
333
334 pub fn base_name(&self) -> Self {
348 let length = self.label_ends.len();
349 if length > 0 {
350 return self.trim_to(length - 1);
351 }
352 self.clone()
353 }
354
355 pub fn trim_to(&self, num_labels: usize) -> Self {
370 if num_labels > self.label_ends.len() {
371 self.clone()
372 } else {
373 Self::from_labels(self.iter().skip(self.label_ends.len() - num_labels)).unwrap()
374 }
375 }
376
377 pub fn zone_of_case(&self, name: &Self) -> bool {
379 let self_len = self.label_ends.len();
380 let name_len = name.label_ends.len();
381 if self_len == 0 {
382 return true;
383 }
384 if name_len == 0 {
385 return false;
387 }
388 if self_len > name_len {
389 return false;
390 }
391
392 let self_iter = self.iter().rev();
393 let name_iter = name.iter().rev();
394
395 let zip_iter = self_iter.zip(name_iter);
396
397 for (self_label, name_label) in zip_iter {
398 if self_label != name_label {
399 return false;
400 }
401 }
402
403 true
404 }
405
406 pub fn zone_of(&self, name: &Self) -> bool {
422 let self_lower = self.to_lowercase();
423 let name_lower = name.to_lowercase();
424
425 self_lower.zone_of_case(&name_lower)
426 }
427
428 pub fn num_labels(&self) -> u8 {
446 let num = self.label_ends.len() as u8;
449
450 self.iter()
451 .next()
452 .map(|l| if l == b"*" { num - 1 } else { num })
453 .unwrap_or(num)
454 }
455
456 pub fn len(&self) -> usize {
472 let dots = if !self.label_ends.is_empty() {
473 self.label_ends.len()
474 } else {
475 1
476 };
477 dots + self.label_data.len()
478 }
479
480 fn encoded_len(&self) -> usize {
485 self.label_ends.len() + self.label_data.len() + 1
486 }
487
488 pub fn is_empty(&self) -> bool {
491 false
492 }
493
494 pub fn parse(local: &str, origin: Option<&Self>) -> ProtoResult<Self> {
507 Self::from_encoded_str::<LabelEncUtf8>(local, origin)
508 }
509
510 pub fn from_ascii<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
538 Self::from_encoded_str::<LabelEncAscii>(name.as_ref(), None)
539 }
540
541 pub fn from_utf8<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
562 Self::from_encoded_str::<LabelEncUtf8>(name.as_ref(), None)
563 }
564
565 pub fn from_str_relaxed<S: AsRef<str>>(name: S) -> ProtoResult<Self> {
584 let name = name.as_ref();
585 Self::from_utf8(name).or_else(|_| Self::from_ascii(name))
586 }
587
588 fn from_encoded_str<E: LabelEnc>(local: &str, origin: Option<&Self>) -> ProtoResult<Self> {
589 let mut name = Self::new();
590 let mut label = String::new();
591
592 let mut state = ParseState::Label;
593
594 if local == "." {
596 name.set_fqdn(true);
597 return Ok(name);
598 }
599
600 for ch in local.chars() {
603 match state {
604 ParseState::Label => match ch {
605 '.' => {
606 name = name.append_label(E::to_label(&label)?)?;
607 label.clear();
608 }
609 '\\' => state = ParseState::Escape1,
610 ch if !ch.is_control() && !ch.is_whitespace() => label.push(ch),
611 _ => return Err(format!("unrecognized char: {ch}").into()),
612 },
613 ParseState::Escape1 => {
614 if ch.is_numeric() {
615 state = ParseState::Escape2(
616 ch.to_digit(8)
617 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?,
618 );
619 } else {
620 label.push(ch);
622 state = ParseState::Label;
623 }
624 }
625 ParseState::Escape2(i) => {
626 if ch.is_numeric() {
627 state = ParseState::Escape3(
628 i,
629 ch.to_digit(8)
630 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?,
631 );
632 } else {
633 return Err(ProtoError::from(format!("unrecognized char: {ch}")));
634 }
635 }
636 ParseState::Escape3(i, ii) => {
637 if ch.is_numeric() {
638 let val: u32 = (i * 8 * 8)
640 + (ii * 8)
641 + ch.to_digit(8)
642 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?;
643 let new: char = char::from_u32(val)
644 .ok_or_else(|| ProtoError::from(format!("illegal char: {ch}")))?;
645 label.push(new);
646 state = ParseState::Label;
647 } else {
648 return Err(format!("unrecognized char: {ch}").into());
649 }
650 }
651 }
652 }
653
654 if !label.is_empty() {
655 name = name.append_label(E::to_label(&label)?)?;
656 }
657
658 if label.is_empty() && !local.is_empty() {
660 name.set_fqdn(true);
661 } else if let Some(other) = origin {
662 return name.append_domain(other);
663 }
664
665 Ok(name)
666 }
667
668 pub fn emit_as_canonical(
672 &self,
673 encoder: &mut BinEncoder<'_>,
674 canonical: bool,
675 ) -> ProtoResult<()> {
676 let buf_len = encoder.len(); let labels = self.iter();
680
681 let mut labels_written = Vec::with_capacity(self.label_ends.len());
683 for label in labels {
686 if label.len() > 63 {
687 return Err(ProtoErrorKind::LabelBytesTooLong(label.len()).into());
688 }
689
690 labels_written.push(encoder.offset());
691 encoder.emit_character_data(label)?;
692 }
693 let last_index = encoder.offset();
694 for label_idx in &labels_written {
697 match encoder.get_label_pointer(*label_idx, last_index) {
698 Some(_) if canonical => continue,
700 Some(loc) if !canonical => {
701 encoder.set_offset(*label_idx);
703 encoder.trim();
704
705 encoder.emit_u16(0xC000u16 | (loc & 0x3FFFu16))?;
708
709 return Ok(());
711 }
712 _ => {
713 encoder.store_label_pointer(*label_idx, last_index);
715 }
716 }
717 }
718
719 encoder.emit(0)?;
722
723 let length = encoder.len() - buf_len;
725 if length > 255 {
726 return Err(ProtoErrorKind::DomainNameTooLong(length).into());
727 }
728
729 Ok(())
730 }
731
732 pub fn emit_with_lowercase(
739 &self,
740 encoder: &mut BinEncoder<'_>,
741 lowercase: bool,
742 ) -> ProtoResult<()> {
743 let is_canonical_names = encoder.is_canonical_names();
744 if lowercase {
745 self.to_lowercase()
746 .emit_as_canonical(encoder, is_canonical_names)
747 } else {
748 self.emit_as_canonical(encoder, is_canonical_names)
749 }
750 }
751
752 fn cmp_with_f<F: LabelCmp>(&self, other: &Self) -> Ordering {
754 match (self.is_fqdn(), other.is_fqdn()) {
755 (false, true) => Ordering::Less,
756 (true, false) => Ordering::Greater,
757 _ => self.cmp_labels::<F>(other),
758 }
759 }
760
761 fn cmp_labels<F: LabelCmp>(&self, other: &Self) -> Ordering {
763 if self.label_ends.is_empty() && other.label_ends.is_empty() {
764 return Ordering::Equal;
765 }
766
767 let self_labels = self.iter().rev();
769 let other_labels = other.iter().rev();
770
771 for (l, r) in self_labels.zip(other_labels) {
772 let l = Label::from_raw_bytes(l).unwrap();
773 let r = Label::from_raw_bytes(r).unwrap();
774 match l.cmp_with_f::<F>(&r) {
775 Ordering::Equal => continue,
776 not_eq => return not_eq,
777 }
778 }
779
780 self.label_ends.len().cmp(&other.label_ends.len())
781 }
782
783 pub fn cmp_case(&self, other: &Self) -> Ordering {
785 self.cmp_with_f::<CaseSensitive>(other)
786 }
787
788 pub fn eq_case(&self, other: &Self) -> bool {
790 self.cmp_with_f::<CaseSensitive>(other) == Ordering::Equal
791 }
792
793 pub fn eq_ignore_root(&self, other: &Self) -> bool {
827 self.cmp_labels::<CaseInsensitive>(other) == Ordering::Equal
828 }
829
830 pub fn eq_ignore_root_case(&self, other: &Self) -> bool {
852 self.cmp_labels::<CaseSensitive>(other) == Ordering::Equal
853 }
854
855 pub fn to_ascii(&self) -> String {
860 let mut s = String::with_capacity(self.len());
861 self.write_labels::<String, LabelEncAscii>(&mut s)
862 .expect("string conversion of name should not fail");
863 s
864 }
865
866 pub fn to_utf8(&self) -> String {
872 format!("{self}")
873 }
874
875 pub fn parse_arpa_name(&self) -> Result<IpNet, ProtoError> {
877 if !self.is_fqdn() {
878 return Err("PQDN cannot be valid arpa name".into());
879 }
880 let mut iter = self.iter().rev();
881 let first = iter
882 .next()
883 .ok_or_else(|| ProtoError::from("not an arpa address"))?;
884 if !"arpa".eq_ignore_ascii_case(core::str::from_utf8(first)?) {
885 return Err("not an arpa address".into());
886 }
887 let second = iter
888 .next()
889 .ok_or_else(|| ProtoError::from("invalid arpa address"))?;
890 let mut prefix_len: u8 = 0;
891 match &core::str::from_utf8(second)?.to_ascii_lowercase()[..] {
892 "in-addr" => {
893 let mut octets: [u8; 4] = [0; 4];
894 for octet in octets.iter_mut() {
895 match iter.next() {
896 Some(label) => *octet = core::str::from_utf8(label)?.parse()?,
897 None => break,
898 }
899 prefix_len += 8;
900 }
901 if iter.next().is_some() {
902 return Err("unrecognized in-addr.arpa.".into());
903 }
904 Ok(IpNet::V4(
905 Ipv4Net::new(octets.into(), prefix_len).expect("Ipv4Net::new"),
906 ))
907 }
908 "ip6" => {
909 let mut address: u128 = 0;
910 while prefix_len < 128 {
911 match iter.next() {
912 Some(label) => {
913 if label.len() == 1 {
914 prefix_len += 4;
915 let hex = u8::from_str_radix(core::str::from_utf8(label)?, 16)?;
916 address |= u128::from(hex) << (128 - prefix_len);
917 } else {
918 return Err("invalid label length for ip6.arpa".into());
919 }
920 }
921 None => break,
922 }
923 }
924 if iter.next().is_some() {
925 return Err("unrecognized ip6.arpa.".into());
926 }
927 Ok(IpNet::V6(
928 Ipv6Net::new(address.into(), prefix_len).expect("Ipv6Net::new"),
929 ))
930 }
931 _ => Err("unrecognized arpa address".into()),
932 }
933 }
934
935 fn write_labels<W: Write, E: LabelEnc>(&self, f: &mut W) -> Result<(), fmt::Error> {
936 let mut iter = self.iter().map(|b| Label::from_raw_bytes(b).unwrap());
937 if let Some(label) = iter.next() {
938 E::write_label(f, &label)?;
939 }
940
941 for label in iter {
942 write!(f, ".")?;
943 E::write_label(f, &label)?;
944 }
945
946 if self.is_root() || self.is_fqdn() {
948 write!(f, ".")?;
949 }
950 Ok(())
951 }
952
953 pub fn is_localhost(&self) -> bool {
971 LOCALHOST_usage.zone_of(self)
972 }
973
974 pub fn is_wildcard(&self) -> bool {
992 self.iter().next().is_some_and(|l| l == b"*")
993 }
994
995 pub fn into_wildcard(self) -> Self {
1011 if self.label_ends.is_empty() {
1012 return Self::root();
1013 }
1014 let mut label_data = TinyVec::new();
1015 label_data.push(b'*');
1016 let mut label_ends = TinyVec::new();
1017 label_ends.push(1);
1018
1019 for label in self.iter().skip(1) {
1021 label_data.extend_from_slice(label);
1022 label_ends.push(label_data.len() as u8);
1023 }
1024 Self {
1025 label_data,
1026 label_ends,
1027 is_fqdn: self.is_fqdn,
1028 }
1029 }
1030}
1031
1032impl core::fmt::Debug for Name {
1033 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1034 f.write_str("Name(\"")?;
1035 self.write_labels::<_, LabelEncUtf8>(f)?;
1036 f.write_str("\")")
1037 }
1038}
1039
1040trait LabelEnc {
1041 #[allow(clippy::wrong_self_convention)]
1042 fn to_label(name: &str) -> ProtoResult<Label>;
1043 fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error>;
1044}
1045
1046struct LabelEncAscii;
1047
1048impl LabelEnc for LabelEncAscii {
1049 #[allow(clippy::wrong_self_convention)]
1050 fn to_label(name: &str) -> ProtoResult<Label> {
1051 Label::from_ascii(name)
1052 }
1053
1054 fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error> {
1055 label.write_ascii(f)
1056 }
1057}
1058
1059struct LabelEncUtf8;
1060
1061impl LabelEnc for LabelEncUtf8 {
1062 #[allow(clippy::wrong_self_convention)]
1063 fn to_label(name: &str) -> ProtoResult<Label> {
1064 Label::from_utf8(name)
1065 }
1066
1067 fn write_label<W: Write>(f: &mut W, label: &Label) -> Result<(), fmt::Error> {
1068 write!(f, "{label}")
1069 }
1070}
1071
1072pub struct LabelIter<'a> {
1074 name: &'a Name,
1075 start: u8,
1076 end: u8,
1077}
1078
1079impl<'a> Iterator for LabelIter<'a> {
1080 type Item = &'a [u8];
1081
1082 fn next(&mut self) -> Option<Self::Item> {
1083 if self.start >= self.end {
1084 return None;
1085 }
1086
1087 let end = *self.name.label_ends.get(self.start as usize)?;
1088 let start = match self.start {
1089 0 => 0,
1090 _ => self.name.label_ends[(self.start - 1) as usize],
1091 };
1092 self.start += 1;
1093 Some(&self.name.label_data[start as usize..end as usize])
1094 }
1095
1096 fn size_hint(&self) -> (usize, Option<usize>) {
1097 let len = self.end.saturating_sub(self.start) as usize;
1098 (len, Some(len))
1099 }
1100}
1101
1102impl ExactSizeIterator for LabelIter<'_> {}
1103
1104impl DoubleEndedIterator for LabelIter<'_> {
1105 fn next_back(&mut self) -> Option<Self::Item> {
1106 if self.end <= self.start {
1107 return None;
1108 }
1109
1110 self.end -= 1;
1111
1112 let end = *self.name.label_ends.get(self.end as usize)?;
1113 let start = match self.end {
1114 0 => 0,
1115 _ => self.name.label_ends[(self.end - 1) as usize],
1116 };
1117
1118 Some(&self.name.label_data[start as usize..end as usize])
1119 }
1120}
1121
1122impl<'a> IntoIterator for &'a Name {
1123 type Item = &'a [u8];
1124 type IntoIter = LabelIter<'a>;
1125
1126 fn into_iter(self) -> Self::IntoIter {
1127 self.iter()
1128 }
1129}
1130
1131impl From<IpAddr> for Name {
1132 fn from(addr: IpAddr) -> Self {
1133 match addr {
1134 IpAddr::V4(ip) => ip.into(),
1135 IpAddr::V6(ip) => ip.into(),
1136 }
1137 }
1138}
1139
1140impl From<Ipv4Addr> for Name {
1141 fn from(addr: Ipv4Addr) -> Self {
1142 let octets = addr.octets();
1143
1144 let mut labels =
1145 octets
1146 .iter()
1147 .rev()
1148 .fold(Vec::<Label>::with_capacity(6), |mut labels, o| {
1149 let label: Label = format!("{o}")
1150 .as_bytes()
1151 .into_label()
1152 .expect("IP octet to label should never fail");
1153 labels.push(label);
1154 labels
1155 });
1156
1157 labels.push(
1158 b"in-addr"
1159 .into_label()
1160 .expect("simple name should never fail"),
1161 );
1162 labels.push(b"arpa".into_label().expect("simple name should never fail"));
1163
1164 Self::from_labels(labels).expect("a translation of Ipv4Addr should never fail")
1165 }
1166}
1167
1168impl From<Ipv6Addr> for Name {
1169 fn from(addr: Ipv6Addr) -> Self {
1170 let segments = addr.segments();
1171
1172 let mut labels =
1173 segments
1174 .iter()
1175 .rev()
1176 .fold(Vec::<Label>::with_capacity(34), |mut labels, o| {
1177 labels.push(
1178 format!("{:x}", (*o & 0x000F) as u8)
1179 .as_bytes()
1180 .into_label()
1181 .expect("IP octet to label should never fail"),
1182 );
1183 labels.push(
1184 format!("{:x}", ((*o >> 4) & 0x000F) as u8)
1185 .as_bytes()
1186 .into_label()
1187 .expect("IP octet to label should never fail"),
1188 );
1189 labels.push(
1190 format!("{:x}", ((*o >> 8) & 0x000F) as u8)
1191 .as_bytes()
1192 .into_label()
1193 .expect("IP octet to label should never fail"),
1194 );
1195 labels.push(
1196 format!("{:x}", ((*o >> 12) & 0x000F) as u8)
1197 .as_bytes()
1198 .into_label()
1199 .expect("IP octet to label should never fail"),
1200 );
1201 labels
1202 });
1203
1204 labels.push(b"ip6".into_label().expect("simple name should never fail"));
1205 labels.push(b"arpa".into_label().expect("simple name should never fail"));
1206
1207 Self::from_labels(labels).expect("a translation of Ipv6Addr should never fail")
1208 }
1209}
1210
1211impl PartialEq<Self> for Name {
1212 fn eq(&self, other: &Self) -> bool {
1213 match self.is_fqdn == other.is_fqdn {
1214 true => self.cmp_with_f::<CaseInsensitive>(other) == Ordering::Equal,
1215 false => false,
1216 }
1217 }
1218}
1219
1220impl Hash for Name {
1221 fn hash<H: Hasher>(&self, state: &mut H) {
1222 self.is_fqdn.hash(state);
1223
1224 for l in self
1226 .iter()
1227 .map(|l| Label::from_raw_bytes(l).unwrap().to_lowercase())
1228 {
1229 l.hash(state);
1230 }
1231 }
1232}
1233
1234enum ParseState {
1235 Label,
1236 Escape1,
1237 Escape2(u32),
1238 Escape3(u32, u32),
1239}
1240
1241impl BinEncodable for Name {
1242 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
1243 let is_canonical_names = encoder.is_canonical_names();
1244 self.emit_as_canonical(encoder, is_canonical_names)
1245 }
1246}
1247
1248impl<'r> BinDecodable<'r> for Name {
1249 fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
1254 let mut name = Self::default();
1255 read_inner(decoder, &mut name, None)?;
1256 Ok(name)
1257 }
1258}
1259
1260fn read_inner(
1261 decoder: &mut BinDecoder<'_>,
1262 name: &mut Name,
1263 max_idx: Option<usize>,
1264) -> Result<(), DecodeError> {
1265 let mut state: LabelParseState = LabelParseState::LabelLengthOrPointer;
1266 let name_start = decoder.index();
1267
1268 loop {
1274 if let Some(max_idx) = max_idx {
1276 if decoder.index() >= max_idx {
1277 return Err(DecodeError::LabelOverlapsWithOther {
1278 label: name_start,
1279 other: max_idx,
1280 });
1281 }
1282 }
1283
1284 state = match state {
1285 LabelParseState::LabelLengthOrPointer => {
1286 match decoder
1288 .peek()
1289 .map(Restrict::unverified )
1290 {
1291 Some(0) => {
1292 name.set_fqdn(true);
1302 LabelParseState::Root
1303 }
1304 None => {
1305 return Err(DecodeError::InsufficientBytes);
1308 }
1309 Some(byte) if byte & 0b1100_0000 == 0b1100_0000 => LabelParseState::Pointer,
1310 Some(byte) if byte & 0b1100_0000 == 0b0000_0000 => LabelParseState::Label,
1311 Some(byte) => return Err(DecodeError::UnrecognizedLabelCode(byte)),
1312 }
1313 }
1314 LabelParseState::Label => {
1316 let label = decoder
1317 .read_character_data()?
1318 .verify_unwrap(|l| l.len() <= 63)
1319 .map_err(|l| DecodeError::LabelBytesTooLong(l.len()))?;
1320
1321 name.extend_name(label)
1322 .map_err(|_| DecodeError::DomainNameTooLong(label.len()))?;
1323
1324 LabelParseState::LabelLengthOrPointer
1326 }
1327 LabelParseState::Pointer => {
1349 let pointer_location = decoder.index();
1350 let location = decoder
1351 .read_u16()?
1352 .map(|u| {
1353 u & 0x3FFF
1355 })
1356 .verify_unwrap(|ptr| {
1357 (*ptr as usize) < name_start
1359 })
1360 .map_err(|e| DecodeError::PointerNotPriorToLabel {
1361 idx: pointer_location,
1362 ptr: e,
1363 })?;
1364
1365 let mut pointer = decoder.clone(location);
1366 read_inner(&mut pointer, name, Some(name_start))?;
1367
1368 break;
1370 }
1371 LabelParseState::Root => {
1372 decoder.pop()?;
1374 break;
1375 }
1376 }
1377 }
1378
1379 let len = name.len();
1381 if len >= 255 {
1382 return Err(DecodeError::DomainNameTooLong(len));
1383 }
1384
1385 Ok(())
1386}
1387
1388impl fmt::Display for Name {
1389 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1390 self.write_labels::<fmt::Formatter<'_>, LabelEncUtf8>(f)
1391 }
1392}
1393
1394impl PartialOrd<Self> for Name {
1395 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1396 Some(self.cmp(other))
1397 }
1398}
1399
1400impl Ord for Name {
1401 fn cmp(&self, other: &Self) -> Ordering {
1437 self.cmp_with_f::<CaseInsensitive>(other)
1438 }
1439}
1440
1441enum LabelParseState {
1443 LabelLengthOrPointer, Label, Pointer, Root, }
1448
1449impl FromStr for Name {
1450 type Err = ProtoError;
1451
1452 fn from_str(s: &str) -> Result<Self, Self::Err> {
1454 Self::from_str_relaxed(s)
1455 }
1456}
1457
1458pub trait IntoName: Sized {
1460 fn into_name(self) -> ProtoResult<Name>;
1462
1463 fn to_ip(&self) -> Option<IpAddr>;
1465}
1466
1467impl IntoName for &str {
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 IntoName for String {
1479 fn into_name(self) -> ProtoResult<Name> {
1481 Name::from_utf8(self)
1482 }
1483
1484 fn to_ip(&self) -> Option<IpAddr> {
1485 IpAddr::from_str(self).ok()
1486 }
1487}
1488
1489impl IntoName for &String {
1490 fn into_name(self) -> ProtoResult<Name> {
1492 Name::from_utf8(self)
1493 }
1494
1495 fn to_ip(&self) -> Option<IpAddr> {
1496 IpAddr::from_str(self).ok()
1497 }
1498}
1499
1500impl<T> IntoName for T
1501where
1502 T: Into<Name>,
1503{
1504 fn into_name(self) -> ProtoResult<Name> {
1505 Ok(self.into())
1506 }
1507
1508 fn to_ip(&self) -> Option<IpAddr> {
1509 None
1510 }
1511}
1512
1513#[cfg(feature = "serde")]
1514impl Serialize for Name {
1515 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1516 where
1517 S: Serializer,
1518 {
1519 serializer.serialize_str(&self.to_string())
1520 }
1521}
1522
1523#[cfg(feature = "serde")]
1524impl<'de> Deserialize<'de> for Name {
1525 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1526 where
1527 D: Deserializer<'de>,
1528 {
1529 let s = String::deserialize(deserializer)?;
1530 FromStr::from_str(&s).map_err(de::Error::custom)
1531 }
1532}
1533
1534#[cfg(test)]
1535mod tests {
1536 #![allow(clippy::dbg_macro, clippy::print_stdout)]
1537
1538 use alloc::string::ToString;
1539 use core::cmp::Ordering;
1540 use core::iter;
1541 #[cfg(feature = "std")]
1542 use std::{collections::hash_map::DefaultHasher, println};
1543
1544 use super::*;
1545
1546 use crate::serialize::binary::bin_tests::{test_emit_data_set, test_read_data_set};
1547 #[allow(clippy::useless_attribute)]
1548 #[allow(unused)]
1549 use crate::serialize::binary::*;
1550
1551 fn get_data() -> Vec<(Name, Vec<u8>)> {
1552 vec![
1553 (Name::from_str(".").unwrap(), vec![0]), (Name::from_str("a.").unwrap(), vec![1, b'a', 0]), (
1556 Name::from_str("a.bc.").unwrap(),
1557 vec![1, b'a', 2, b'b', b'c', 0],
1558 ), (
1560 Name::from_str("a.♥.").unwrap(),
1561 vec![1, b'a', 7, b'x', b'n', b'-', b'-', b'g', b'6', b'h', 0],
1562 ), ]
1564 }
1565
1566 #[test]
1567 fn test_num_labels() {
1568 assert_eq!(Name::from_str("*").unwrap().num_labels(), 0);
1569 assert_eq!(Name::from_str("a").unwrap().num_labels(), 1);
1570 assert_eq!(Name::from_str("*.b").unwrap().num_labels(), 1);
1571 assert_eq!(Name::from_str("a.b").unwrap().num_labels(), 2);
1572 assert_eq!(Name::from_str("*.b.c").unwrap().num_labels(), 2);
1573 assert_eq!(Name::from_str("a.b.c").unwrap().num_labels(), 3);
1574 }
1575
1576 #[test]
1577 fn test_read() {
1578 test_read_data_set(get_data(), |mut d| Name::read(&mut d));
1579 }
1580
1581 #[test]
1582 fn test_write_to() {
1583 test_emit_data_set(get_data(), |e, n| n.emit(e));
1584 }
1585
1586 #[test]
1587 fn test_pointer() {
1588 let mut bytes = Vec::with_capacity(512);
1589
1590 let first = Name::from_str("ra.rb.rc.").unwrap();
1591 let second = Name::from_str("rb.rc.").unwrap();
1592 let third = Name::from_str("rc.").unwrap();
1593 let fourth = Name::from_str("z.ra.rb.rc.").unwrap();
1594
1595 {
1596 let mut e = BinEncoder::new(&mut bytes);
1597
1598 first.emit(&mut e).unwrap();
1599 assert_eq!(e.len(), 10); second.emit(&mut e).unwrap();
1602 assert_eq!(e.len(), 12);
1604
1605 third.emit(&mut e).unwrap();
1606 assert_eq!(e.len(), 14);
1607
1608 fourth.emit(&mut e).unwrap();
1609 assert_eq!(e.len(), 18);
1610 }
1611
1612 let mut d = BinDecoder::new(&bytes);
1614
1615 let r_test = Name::read(&mut d).unwrap();
1616 assert_eq!(first, r_test);
1617
1618 let r_test = Name::read(&mut d).unwrap();
1619 assert_eq!(second, r_test);
1620
1621 let r_test = Name::read(&mut d).unwrap();
1622 assert_eq!(third, r_test);
1623
1624 let r_test = Name::read(&mut d).unwrap();
1625 assert_eq!(fourth, r_test);
1626 }
1627
1628 #[test]
1629 fn test_pointer_with_pointer_ending_labels() {
1630 let mut bytes: Vec<u8> = Vec::with_capacity(512);
1631
1632 let first = Name::from_str("ra.rb.rc.").unwrap();
1633 let second = Name::from_str("ra.rc.").unwrap();
1634 let third = Name::from_str("ra.rc.").unwrap();
1635
1636 {
1637 let mut e = BinEncoder::new(&mut bytes);
1638
1639 first.emit(&mut e).unwrap();
1640 assert_eq!(e.len(), 10);
1641
1642 second.emit(&mut e).unwrap();
1643 assert_eq!(e.len(), 15);
1645
1646 third.emit(&mut e).unwrap();
1648 assert_eq!(e.len(), 17);
1649 }
1650
1651 let mut d = BinDecoder::new(&bytes);
1653
1654 let r_test = Name::read(&mut d).unwrap();
1655 assert_eq!(first, r_test);
1656
1657 let r_test = Name::read(&mut d).unwrap();
1658 assert_eq!(second, r_test);
1659
1660 let r_test = Name::read(&mut d).unwrap();
1661 assert_eq!(third, r_test);
1662 }
1663
1664 #[test]
1665 fn test_recursive_pointer() {
1666 let bytes = vec![0xC0, 0x01];
1668 let mut d = BinDecoder::new(&bytes);
1669
1670 assert!(Name::read(&mut d).is_err());
1671
1672 let bytes = vec![0xC0, 0x00];
1674 let mut d = BinDecoder::new(&bytes);
1675
1676 assert!(Name::read(&mut d).is_err());
1677
1678 let bytes = vec![0x01, 0x41, 0xC0, 0x00];
1680 let mut d = BinDecoder::new(&bytes);
1681
1682 assert!(Name::read(&mut d).is_err());
1683
1684 let bytes = vec![0xC0, 0x02, 0xC0, 0x00];
1687 let mut d = BinDecoder::new(&bytes);
1688
1689 assert!(Name::read(&mut d).is_err());
1690 }
1691
1692 #[test]
1693 fn test_bin_overlap_enforced() {
1694 let mut bytes: Vec<u8> = Vec::with_capacity(512);
1695 let n: u8 = 31;
1696 for _ in 0..=5 {
1697 bytes.extend(iter::repeat(n).take(n as usize));
1698 }
1699 bytes.push(n + 1);
1700 for b in 0..n {
1701 bytes.push(1 + n + b);
1702 }
1703 bytes.extend_from_slice(&[1, 0]);
1704 for b in 0..n {
1705 bytes.extend_from_slice(&[0xC0, b]);
1706 }
1707 let mut d = BinDecoder::new(&bytes);
1708 d.read_slice(n as usize).unwrap();
1709 assert!(Name::read(&mut d).is_err());
1710 }
1711
1712 #[test]
1713 fn test_bin_max_octets() {
1714 let mut bytes = Vec::with_capacity(512);
1715 for _ in 0..256 {
1716 bytes.extend_from_slice(&[1, b'a']);
1717 }
1718 bytes.push(0);
1719
1720 let mut d = BinDecoder::new(&bytes);
1721 assert!(Name::read(&mut d).is_err());
1722 }
1723
1724 #[test]
1725 fn test_base_name() {
1726 let zone = Name::from_str("example.com.").unwrap();
1727
1728 assert_eq!(zone.base_name(), Name::from_str("com.").unwrap());
1729 assert!(zone.base_name().base_name().is_root());
1730 assert!(zone.base_name().base_name().base_name().is_root());
1731 }
1732
1733 #[test]
1734 fn test_zone_of() {
1735 let zone = Name::from_str("example.com").unwrap();
1736 let www = Name::from_str("www.example.com").unwrap();
1737 let none = Name::from_str("none.com").unwrap();
1738 let root = Name::root();
1739
1740 assert!(zone.zone_of(&zone));
1741 assert!(zone.zone_of(&www));
1742 assert!(!zone.zone_of(&none));
1743 assert!(root.zone_of(&zone));
1744 assert!(!zone.zone_of(&root));
1745 }
1746
1747 #[test]
1748 fn test_zone_of_case() {
1749 let zone = Name::from_ascii("examplE.cOm").unwrap();
1750 let www = Name::from_str("www.example.com").unwrap();
1751 let none = Name::from_str("none.com").unwrap();
1752
1753 assert!(zone.zone_of(&zone));
1754 assert!(zone.zone_of(&www));
1755 assert!(!zone.zone_of(&none))
1756 }
1757
1758 #[test]
1759 fn test_partial_cmp_eq() {
1760 let root = Some(Name::from_labels(Vec::<&str>::new()).unwrap());
1761 let comparisons: Vec<(Name, Name)> = vec![
1762 (root.clone().unwrap(), root.clone().unwrap()),
1763 (
1764 Name::parse("example.", root.as_ref()).unwrap(),
1765 Name::parse("example", root.as_ref()).unwrap(),
1766 ),
1767 ];
1768
1769 for (left, right) in comparisons {
1770 #[cfg(feature = "std")]
1771 println!("left: {left}, right: {right}");
1772 assert_eq!(left.partial_cmp(&right), Some(Ordering::Equal));
1773 }
1774 }
1775
1776 #[test]
1777 fn test_partial_cmp() {
1778 let comparisons: Vec<(Name, Name)> = vec![
1779 (
1780 Name::from_str("example.").unwrap(),
1781 Name::from_str("a.example.").unwrap(),
1782 ),
1783 (
1784 Name::from_str("a.example.").unwrap(),
1785 Name::from_str("yljkjljk.a.example.").unwrap(),
1786 ),
1787 (
1788 Name::from_str("yljkjljk.a.example.").unwrap(),
1789 Name::from_ascii("Z.a.example.").unwrap(),
1790 ),
1791 (
1792 Name::from_ascii("Z.a.example").unwrap(),
1793 Name::from_ascii("zABC.a.EXAMPLE.").unwrap(),
1794 ),
1795 (
1796 Name::from_ascii("zABC.a.EXAMPLE.").unwrap(),
1797 Name::from_str("z.example.").unwrap(),
1798 ),
1799 (
1800 Name::from_str("z.example").unwrap(),
1801 Name::from_labels(vec![&[1u8] as &[u8], b"z", b"example."]).unwrap(),
1802 ),
1803 (
1804 Name::from_labels(vec![&[1u8] as &[u8], b"z", b"example"]).unwrap(),
1805 Name::from_str("*.z.example.").unwrap(),
1806 ),
1807 (
1808 Name::from_str("*.z.example").unwrap(),
1809 Name::from_labels(vec![&[200u8] as &[u8], b"z", b"example."]).unwrap(),
1810 ),
1811 ];
1812
1813 for (left, right) in comparisons {
1814 #[cfg(feature = "std")]
1815 println!("left: {left}, right: {right}");
1816 assert_eq!(left.cmp(&right), Ordering::Less);
1817 }
1818 }
1819
1820 #[test]
1821 fn test_cmp_ignore_case() {
1822 let comparisons: Vec<(Name, Name)> = vec![
1823 (
1824 Name::from_ascii("ExAmPle.").unwrap(),
1825 Name::from_ascii("example.").unwrap(),
1826 ),
1827 (
1828 Name::from_ascii("A.example.").unwrap(),
1829 Name::from_ascii("a.example.").unwrap(),
1830 ),
1831 ];
1832
1833 for (left, right) in comparisons {
1834 #[cfg(feature = "std")]
1835 println!("left: {left}, right: {right}");
1836 assert_eq!(left, right);
1837 }
1838 }
1839
1840 #[test]
1841 fn test_from_ipv4() {
1842 let ip = IpAddr::V4(Ipv4Addr::new(26, 3, 0, 103));
1843 let name = Name::from_str("103.0.3.26.in-addr.arpa.").unwrap();
1844
1845 assert_eq!(Into::<Name>::into(ip), name);
1846 }
1847
1848 #[test]
1849 fn test_from_ipv6() {
1850 let ip = IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x1));
1851 let name = Name::from_str(
1852 "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.",
1853 )
1854 .unwrap();
1855
1856 assert_eq!(Into::<Name>::into(ip), name);
1857 }
1858
1859 #[test]
1860 fn test_from_str() {
1861 assert_eq!(
1862 Name::from_str("www.example.com.").unwrap(),
1863 Name::from_labels(vec![b"www" as &[u8], b"example", b"com"]).unwrap()
1864 );
1865 assert_eq!(
1866 Name::from_str(".").unwrap(),
1867 Name::from_labels(Vec::<&str>::new()).unwrap()
1868 );
1869 }
1870
1871 #[test]
1872 fn test_fqdn() {
1873 assert!(Name::root().is_fqdn());
1874 assert!(Name::from_str(".").unwrap().is_fqdn());
1875 assert!(Name::from_str("www.example.com.").unwrap().is_fqdn());
1876 assert!(
1877 Name::from_labels(vec![b"www" as &[u8], b"example", b"com"])
1878 .unwrap()
1879 .is_fqdn()
1880 );
1881
1882 assert!(!Name::new().is_fqdn());
1883 assert!(!Name::from_str("www.example.com").unwrap().is_fqdn());
1884 assert!(!Name::from_str("www.example").unwrap().is_fqdn());
1885 assert!(!Name::from_str("www").unwrap().is_fqdn());
1886 }
1887
1888 #[test]
1889 fn test_to_string() {
1890 assert_eq!(
1891 Name::from_str("www.example.com.").unwrap().to_string(),
1892 "www.example.com."
1893 );
1894 assert_eq!(
1895 Name::from_str("www.example.com").unwrap().to_string(),
1896 "www.example.com"
1897 );
1898 }
1899
1900 #[test]
1901 fn test_from_ascii() {
1902 let bytes_name = Name::from_labels(vec![b"WWW" as &[u8], b"example", b"COM"]).unwrap();
1903 let ascii_name = Name::from_ascii("WWW.example.COM.").unwrap();
1904 let lower_name = Name::from_ascii("www.example.com.").unwrap();
1905
1906 assert!(bytes_name.eq_case(&ascii_name));
1907 assert!(!lower_name.eq_case(&ascii_name));
1908 }
1909
1910 #[test]
1911 fn test_from_utf8() {
1912 let bytes_name = Name::from_labels(vec![b"WWW" as &[u8], b"example", b"COM"]).unwrap();
1913 let utf8_name = Name::from_utf8("WWW.example.COM.").unwrap();
1914 let lower_name = Name::from_utf8("www.example.com.").unwrap();
1915
1916 assert!(!bytes_name.eq_case(&utf8_name));
1917 assert!(lower_name.eq_case(&utf8_name));
1918 }
1919
1920 #[test]
1921 fn test_into_name() {
1922 let name = Name::from_utf8("www.example.com").unwrap();
1923 assert_eq!(Name::from_utf8("www.example.com").unwrap(), name);
1924 assert_eq!(
1925 Name::from_utf8("www.example.com").unwrap(),
1926 Name::from_utf8("www.example.com")
1927 .unwrap()
1928 .into_name()
1929 .unwrap()
1930 );
1931 assert_eq!(
1932 Name::from_utf8("www.example.com").unwrap(),
1933 "www.example.com".into_name().unwrap()
1934 );
1935 assert_eq!(
1936 Name::from_utf8("www.example.com").unwrap(),
1937 "www.example.com".to_string().into_name().unwrap()
1938 );
1939 }
1940
1941 #[test]
1942 fn test_encoding() {
1943 assert_eq!(
1944 Name::from_ascii("WWW.example.COM.").unwrap().to_ascii(),
1945 "WWW.example.COM."
1946 );
1947 assert_eq!(
1948 Name::from_utf8("WWW.example.COM.").unwrap().to_ascii(),
1949 "www.example.com."
1950 );
1951 assert_eq!(
1952 Name::from_ascii("WWW.example.COM.").unwrap().to_utf8(),
1953 "WWW.example.COM."
1954 );
1955 }
1956
1957 #[test]
1958 fn test_excessive_encoding_len() {
1959 use crate::error::ProtoErrorKind;
1960
1961 let mut buf = Vec::with_capacity(u16::MAX as usize);
1963 let mut encoder = BinEncoder::new(&mut buf);
1964
1965 let mut result = Ok(());
1966 for i in 0..10000 {
1967 let name = Name::from_ascii(format!("name{i}.example.com.")).unwrap();
1968 result = name.emit(&mut encoder);
1969 if result.is_err() {
1970 break;
1971 }
1972 }
1973
1974 assert!(result.is_err());
1975 match result.unwrap_err().kind() {
1976 ProtoErrorKind::MaxBufferSizeExceeded(_) => (),
1977 _ => panic!(),
1978 }
1979 }
1980
1981 #[test]
1982 fn test_underscore() {
1983 Name::from_str("_begin.example.com").expect("failed at beginning");
1984 Name::from_str_relaxed("mid_dle.example.com").expect("failed in the middle");
1985 Name::from_str_relaxed("end_.example.com").expect("failed at the end");
1986 }
1987
1988 #[test]
1989 fn test_parse_arpa_name() {
1990 assert!(
1991 Name::from_ascii("168.192.in-addr.arpa")
1992 .unwrap()
1993 .parse_arpa_name()
1994 .is_err()
1995 );
1996 assert!(
1997 Name::from_ascii("host.example.com.")
1998 .unwrap()
1999 .parse_arpa_name()
2000 .is_err()
2001 );
2002 assert!(
2003 Name::from_ascii("caffee.ip6.arpa.")
2004 .unwrap()
2005 .parse_arpa_name()
2006 .is_err()
2007 );
2008 assert!(
2009 Name::from_ascii(
2010 "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."
2011 )
2012 .unwrap()
2013 .parse_arpa_name()
2014 .is_err()
2015 );
2016 assert!(
2017 Name::from_ascii("caffee.in-addr.arpa.")
2018 .unwrap()
2019 .parse_arpa_name()
2020 .is_err()
2021 );
2022 assert!(
2023 Name::from_ascii("1.2.3.4.5.in-addr.arpa.")
2024 .unwrap()
2025 .parse_arpa_name()
2026 .is_err()
2027 );
2028 assert!(
2029 Name::from_ascii("1.2.3.4.home.arpa.")
2030 .unwrap()
2031 .parse_arpa_name()
2032 .is_err()
2033 );
2034 assert_eq!(
2035 Name::from_ascii("168.192.in-addr.arpa.")
2036 .unwrap()
2037 .parse_arpa_name()
2038 .unwrap(),
2039 IpNet::V4(Ipv4Net::new("192.168.0.0".parse().unwrap(), 16).unwrap())
2040 );
2041 assert_eq!(
2042 Name::from_ascii("1.0.168.192.in-addr.arpa.")
2043 .unwrap()
2044 .parse_arpa_name()
2045 .unwrap(),
2046 IpNet::V4(Ipv4Net::new("192.168.0.1".parse().unwrap(), 32).unwrap())
2047 );
2048 assert_eq!(
2049 Name::from_ascii("0.1.0.0.2.ip6.arpa.")
2050 .unwrap()
2051 .parse_arpa_name()
2052 .unwrap(),
2053 IpNet::V6(Ipv6Net::new("2001::".parse().unwrap(), 20).unwrap())
2054 );
2055 assert_eq!(
2056 Name::from_ascii("D.0.1.0.0.2.ip6.arpa.")
2057 .unwrap()
2058 .parse_arpa_name()
2059 .unwrap(),
2060 IpNet::V6(Ipv6Net::new("2001:d00::".parse().unwrap(), 24).unwrap())
2061 );
2062 assert_eq!(
2063 Name::from_ascii("B.D.0.1.0.0.2.ip6.arpa.")
2064 .unwrap()
2065 .parse_arpa_name()
2066 .unwrap(),
2067 IpNet::V6(Ipv6Net::new("2001:db0::".parse().unwrap(), 28).unwrap())
2068 );
2069 assert_eq!(
2070 Name::from_ascii("8.B.D.0.1.0.0.2.ip6.arpa.")
2071 .unwrap()
2072 .parse_arpa_name()
2073 .unwrap(),
2074 IpNet::V6(Ipv6Net::new("2001:db8::".parse().unwrap(), 32).unwrap())
2075 );
2076 assert_eq!(
2077 Name::from_ascii(
2078 "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."
2079 )
2080 .unwrap()
2081 .parse_arpa_name()
2082 .unwrap(),
2083 IpNet::V6(
2084 Ipv6Net::new("2001:db8:85a3:8d3:1319:8a2e:370:7334".parse().unwrap(), 128).unwrap()
2085 )
2086 );
2087 }
2088
2089 #[test]
2090 fn test_prepend_label() {
2091 for name in ["foo.com", "foo.com."] {
2092 let name = Name::from_ascii(name).unwrap();
2093
2094 for label in ["bar", "baz", "quux"] {
2095 let sub = name.clone().prepend_label(label).unwrap();
2096 let expected = Name::from_ascii(format!("{label}.{name}")).unwrap();
2097 assert_eq!(expected, sub);
2098 }
2099 }
2100
2101 for name in ["", "."] {
2102 let name = Name::from_ascii(name).unwrap();
2103
2104 for label in ["bar", "baz", "quux"] {
2105 let sub = name.clone().prepend_label(label).unwrap();
2106 let expected = Name::from_ascii(format!("{label}{name}")).unwrap();
2107 assert_eq!(expected, sub);
2108 }
2109 }
2110 }
2111
2112 #[test]
2113 fn test_name_too_long_with_prepend() {
2114 let n = Name::from_ascii("Llocainvannnnnnaxgtezqzqznnnnnn1na.nnntnninvannnnnnaxgtezqzqznnnnnn1na.nnntnnnnnnnaxgtezqzqznnnnnn1na.nnntnaaaaaaaaaaaaaaaaaaaaaaaaiK.iaaaaaaaaaaaaaaaaaaaaaaaaiKa.innnnnaxgtezqzqznnnnnn1na.nnntnaaaaaaaaaaaaaaaaaaaaaaaaiK.iaaaaaaaaaaaaaaaaaaaaaaaaiKa.in").unwrap();
2115 let sfx = "xxxxxxx.yyyyy.zzz";
2116
2117 let error = n
2118 .prepend_label(sfx)
2119 .expect_err("should have errored, too long");
2120
2121 match error.kind() {
2122 ProtoErrorKind::DomainNameTooLong(_) => (),
2123 _ => panic!("expected too long message"),
2124 }
2125 }
2126
2127 #[test]
2128 fn test_name_too_long_with_append() {
2129 let n = Name::from_ascii("Llocainvannnnnnaxgtezqzqznnnnnn1na.nnntnninvannnnnnaxgtezqzqznnnnnn1na.nnntnnnnnnnaxgtezqzqznnnnnn1na.nnntnaaaaaaaaaaaaaaaaaaaaaaaaiK.iaaaaaaaaaaaaaaaaaaaaaaaaiKa.innnnnaxgtezqzqznnnnnn1na.nnntnaaaaaaaaaaaaaaaaaaaaaaaaiK.iaaaaaaaaaaaaaaaaaaaaaaaaiKa.in").unwrap();
2131 let sfx = Name::from_ascii("xxxxxxx.yyyyy.zzz").unwrap();
2132
2133 let error = n
2134 .append_domain(&sfx)
2135 .expect_err("should have errored, too long");
2136
2137 match error.kind() {
2138 ProtoErrorKind::DomainNameTooLong(_) => (),
2139 _ => panic!("expected too long message"),
2140 }
2141 }
2142
2143 #[test]
2144 fn test_encoded_len() {
2145 for name in [
2146 Name::parse("www.example.com.", None).unwrap(),
2148 Name::parse("www", None).unwrap(),
2150 Name::root(),
2152 Name::new(),
2154 ] {
2155 let mut buffer = Vec::new();
2156 let mut encoder = BinEncoder::new(&mut buffer);
2157 name.emit(&mut encoder).unwrap();
2158
2159 assert_eq!(
2160 name.encoded_len(),
2161 buffer.len(),
2162 "encoded_len() was incorrect for {name:?}"
2163 );
2164 }
2165 }
2166
2167 #[test]
2168 fn test_length_limits() {
2169 let encoded_name_255_bytes: [u8; 255] = [
2174 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',
2175 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',
2176 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',
2177 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',
2178 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',
2179 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',
2180 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',
2181 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',
2182 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,
2183 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',
2184 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',
2185 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',
2186 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',
2187 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',
2188 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',
2189 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',
2190 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',
2191 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,
2192 ];
2193 let expected_name_str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.\
2194 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.\
2195 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.\
2196 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.";
2197
2198 let mut decoder = BinDecoder::new(&encoded_name_255_bytes);
2199 let decoded_name = Name::read(&mut decoder).unwrap();
2200 assert!(decoder.is_empty());
2201
2202 assert_eq!(decoded_name.to_string(), expected_name_str);
2203
2204 let long_label_error = Name::parse(&format!("a{expected_name_str}"), None).unwrap_err();
2206 assert!(matches!(
2207 long_label_error.kind(),
2208 ProtoErrorKind::LabelBytesTooLong(64)
2209 ));
2210 let long_name_error =
2211 Name::parse(&format!("a.{}", &expected_name_str[1..]), None).unwrap_err();
2212 assert!(matches!(
2213 long_name_error.kind(),
2214 ProtoErrorKind::DomainNameTooLong(256)
2215 ))
2216 }
2217
2218 #[test]
2219 fn test_double_ended_iterator() {
2220 let name = Name::from_ascii("www.example.com").unwrap();
2221 let mut iter = name.iter();
2222
2223 assert_eq!(iter.next().unwrap(), b"www");
2224 assert_eq!(iter.next_back().unwrap(), b"com");
2225 assert_eq!(iter.next().unwrap(), b"example");
2226 assert!(iter.next_back().is_none());
2227 assert!(iter.next().is_none());
2228 }
2229
2230 #[test]
2231 fn test_size_hint() {
2232 let name = Name::from_ascii("www.example.com").unwrap();
2233 let mut iter = name.iter();
2234
2235 assert_eq!(iter.size_hint().0, 3);
2236 assert_eq!(iter.next().unwrap(), b"www");
2237 assert_eq!(iter.size_hint().0, 2);
2238 assert_eq!(iter.next_back().unwrap(), b"com");
2239 assert_eq!(iter.size_hint().0, 1);
2240 assert_eq!(iter.next().unwrap(), b"example");
2241 assert_eq!(iter.size_hint().0, 0);
2242 assert!(iter.next_back().is_none());
2243 assert_eq!(iter.size_hint().0, 0);
2244 assert!(iter.next().is_none());
2245 assert_eq!(iter.size_hint().0, 0);
2246 }
2247
2248 #[test]
2249 #[cfg(feature = "std")]
2250 fn test_label_randomization() {
2251 let mut name = Name::root();
2252 name.randomize_label_case();
2253 assert!(name.eq_case(&Name::root()));
2254
2255 for qname in [
2256 "x",
2257 "0",
2258 "aaaaaaaaaaaaaaaa",
2259 "AAAAAAAAAAAAAAAA",
2260 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.",
2261 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.",
2262 "abcdefghijklmnopqrstuvwxyz0123456789A.",
2263 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.",
2264 "www01.example-site.com",
2265 "1234567890.e-1204089_043820-5.com.",
2266 ] {
2267 let mut name = Name::from_ascii(qname).unwrap();
2268 let name2 = name.clone();
2269 name.randomize_label_case();
2270 assert_eq!(name, name2);
2271 println!("{name2} == {name}: {}", name == name2);
2272 }
2273
2274 let iterations = 50_000;
2277
2278 let test_str = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.lmnopqrstuvwxyzabcdefghjijklmnopqrstuvwxyzabcdefghijklmnopqrstu.vwxyzABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF.GHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNO";
2281 let mut name = Name::from_ascii(test_str).unwrap();
2282 let name2 = name.clone();
2283
2284 let len = name.label_data.len();
2285 let mut cap_table: [u32; 255] = [0; 255];
2286 let mut lower_table: [u32; 255] = [0; 255];
2287 let mut mean_table: [f64; 255] = [0.0; 255];
2288
2289 for _ in 0..iterations {
2290 name.randomize_label_case();
2291 assert_eq!(name, name2);
2292
2293 for (j, &cbyte) in name.label_data.iter().enumerate() {
2294 if cbyte.is_ascii_lowercase() {
2295 lower_table[j] += 1;
2296 } else if cbyte.is_ascii_uppercase() {
2297 cap_table[j] += 1;
2298 }
2299 }
2300 name = Name::from_ascii(test_str).unwrap();
2301 }
2302
2303 println!("Distribution of lower case values by label offset");
2304 println!("-------------------------------------------------");
2305 for i in 0..len {
2306 let cap_ratio = cap_table[i] as f64 / iterations as f64;
2307 let lower_ratio = lower_table[i] as f64 / iterations as f64;
2308 let total_ratio = cap_ratio + lower_ratio;
2309 mean_table[i] = lower_ratio;
2310 println!(
2311 "{i:03} {:.3}% {:.3}% {:.3}%",
2312 cap_ratio * 100.0,
2313 lower_ratio * 100.0,
2314 total_ratio * 100.0,
2315 );
2316 }
2317 println!("-------------------------------------------------");
2318
2319 let data_mean = mean_table.iter().sum::<f64>() / len as f64;
2320 let data_std_deviation = std_deviation(data_mean, &mean_table);
2321
2322 let mut max_zscore = 0.0;
2323 for elem in mean_table.iter() {
2324 let zscore = (elem - data_mean) / data_std_deviation;
2325
2326 if zscore > max_zscore {
2327 max_zscore = zscore;
2328 }
2329 }
2330
2331 println!("μ: {data_mean:.4} σ: {data_std_deviation:.4}, max variance: {max_zscore:.4}σ");
2332
2333 assert!(data_mean > 0.485 && data_mean < 0.515);
2344 assert!(data_std_deviation < 0.18);
2345 assert!(max_zscore < 0.33);
2346 }
2347
2348 #[cfg(feature = "std")]
2349 fn std_deviation(mean: f64, data: &[f64]) -> f64 {
2350 match (mean, data.len()) {
2351 (data_mean, count) if count > 0 => {
2352 let variance = data
2353 .iter()
2354 .map(|value| {
2355 let diff = data_mean - *value;
2356
2357 diff * diff
2358 })
2359 .sum::<f64>()
2360 / count as f64;
2361
2362 variance.sqrt()
2363 }
2364 _ => 0.0,
2365 }
2366 }
2367
2368 #[test]
2369 fn test_fqdn_escaped_dot() {
2370 let name = Name::from_utf8("test.").unwrap();
2371 assert!(name.is_fqdn());
2372
2373 let name = Name::from_utf8("test\\.").unwrap();
2374 assert!(!name.is_fqdn());
2375
2376 let name = Name::from_utf8("").unwrap();
2377 assert!(!name.is_fqdn());
2378
2379 let name = Name::from_utf8(".").unwrap();
2380 assert!(name.is_fqdn());
2381 }
2382
2383 #[test]
2384 #[allow(clippy::nonminimal_bool)]
2385 fn test_name_partialeq_constraints() {
2386 let example_fqdn = Name::from_utf8("example.com.").unwrap();
2387 let example_nonfqdn = Name::from_utf8("example.com").unwrap();
2388 let other_fqdn = Name::from_utf8("otherdomain.com.").unwrap();
2389
2390 assert_eq!(example_fqdn, example_fqdn);
2391 assert_eq!(example_nonfqdn, example_nonfqdn);
2392 assert!(example_fqdn != example_nonfqdn);
2393
2394 assert!(example_fqdn != example_nonfqdn && !(example_fqdn == example_nonfqdn));
2396 assert!(example_nonfqdn != example_fqdn && !(example_nonfqdn == example_fqdn));
2397 assert!(example_fqdn != other_fqdn && !(example_fqdn == other_fqdn));
2398 assert!(example_nonfqdn != other_fqdn && !(example_nonfqdn == other_fqdn));
2399 }
2400
2401 #[test]
2402 fn test_name_partialord_constraints() {
2403 use core::cmp::Ordering::*;
2404
2405 let example_fqdn = Name::from_utf8("example.com.").unwrap();
2406 let foo_example_fqdn = Name::from_utf8("foo.example.com.").unwrap();
2407 let example_nonfqdn = Name::from_utf8("example.com").unwrap();
2408 let foo_example_nonfqdn = Name::from_utf8("foo.example.com").unwrap();
2409
2410 assert_eq!(example_fqdn.partial_cmp(&example_fqdn), Some(Equal),);
2412 assert!(example_fqdn.partial_cmp(&example_nonfqdn) != Some(Equal));
2413
2414 assert!(
2416 example_nonfqdn < example_fqdn
2417 && example_nonfqdn.partial_cmp(&example_fqdn) == Some(Less)
2418 );
2419
2420 assert!(
2421 example_fqdn < foo_example_fqdn
2422 && example_fqdn.partial_cmp(&foo_example_fqdn) == Some(Less)
2423 );
2424
2425 assert!(
2426 example_nonfqdn < foo_example_nonfqdn
2427 && example_nonfqdn.partial_cmp(&foo_example_nonfqdn) == Some(Less)
2428 );
2429
2430 assert!(
2432 example_fqdn > example_nonfqdn
2433 && example_fqdn.partial_cmp(&example_nonfqdn) == Some(Greater)
2434 );
2435
2436 assert!(
2437 foo_example_fqdn > example_fqdn
2438 && foo_example_fqdn.partial_cmp(&example_fqdn) == Some(Greater)
2439 );
2440
2441 assert!(
2442 foo_example_nonfqdn > example_nonfqdn
2443 && foo_example_nonfqdn.partial_cmp(&example_nonfqdn) == Some(Greater)
2444 );
2445
2446 assert!(example_nonfqdn <= example_fqdn);
2448 assert!(example_nonfqdn <= example_nonfqdn);
2449 assert!(example_fqdn <= example_fqdn);
2450 assert!(example_nonfqdn <= foo_example_nonfqdn);
2451 assert!(example_fqdn <= foo_example_fqdn);
2452 assert!(foo_example_nonfqdn <= foo_example_nonfqdn);
2453 assert!(foo_example_fqdn <= foo_example_fqdn);
2454
2455 assert!(example_fqdn >= example_nonfqdn);
2457 assert!(example_nonfqdn >= example_nonfqdn);
2458 assert!(example_fqdn >= example_fqdn);
2459 assert!(foo_example_nonfqdn >= example_nonfqdn);
2460 assert!(foo_example_fqdn >= example_fqdn);
2461 assert!(foo_example_nonfqdn >= foo_example_nonfqdn);
2462 assert!(foo_example_fqdn >= foo_example_fqdn);
2463
2464 }
2466
2467 #[test]
2468 fn test_name_ord_constraints() {
2469 use core::cmp;
2470
2471 let example_fqdn = Name::from_utf8("example.com.").unwrap();
2472 let foo_example_fqdn = Name::from_utf8("foo.example.com.").unwrap();
2473 let example_nonfqdn = Name::from_utf8("example.com").unwrap();
2474 let foo_example_nonfqdn = Name::from_utf8("foo.example.com").unwrap();
2475
2476 for pair in [
2480 (&example_fqdn, &example_fqdn),
2481 (&example_fqdn, &example_nonfqdn),
2482 (&example_fqdn, &foo_example_fqdn),
2483 (&example_fqdn, &foo_example_nonfqdn),
2484 (&example_nonfqdn, &example_nonfqdn),
2485 (&example_nonfqdn, &example_fqdn),
2486 (&example_nonfqdn, &foo_example_fqdn),
2487 (&example_nonfqdn, &foo_example_nonfqdn),
2488 (&foo_example_fqdn, &example_nonfqdn),
2489 (&foo_example_fqdn, &example_fqdn),
2490 (&foo_example_fqdn, &foo_example_fqdn),
2491 (&foo_example_fqdn, &foo_example_nonfqdn),
2492 (&foo_example_fqdn, &example_nonfqdn),
2493 (&foo_example_fqdn, &example_fqdn),
2494 (&foo_example_fqdn, &foo_example_fqdn),
2495 (&foo_example_fqdn, &foo_example_nonfqdn),
2496 ] {
2497 let name1 = pair.0;
2498 let name2 = pair.1;
2499
2500 assert_eq!(name1.partial_cmp(name2), Some(name1.cmp(name2)));
2502
2503 assert_eq!(
2505 name1.clone().max(name2.clone()),
2506 cmp::max_by(name1.clone(), name2.clone(), |x: &Name, y: &Name| x.cmp(y)),
2507 );
2508
2509 assert_eq!(
2511 name1.clone().min(name2.clone()),
2512 cmp::min_by(name1.clone(), name2.clone(), |x: &Name, y: &Name| x.cmp(y)),
2513 );
2514 }
2515
2516 let min_name = Name::from_utf8("com").unwrap();
2524 let max_name = Name::from_utf8("max.example.com.").unwrap();
2525
2526 assert_eq!(
2527 min_name
2528 .clone()
2529 .clamp(min_name.clone(), example_nonfqdn.clone()),
2530 min_name.clone(),
2531 );
2532
2533 assert_eq!(
2534 max_name
2535 .clone()
2536 .clamp(example_nonfqdn.clone(), example_fqdn.clone()),
2537 example_fqdn.clone(),
2538 );
2539
2540 assert_eq!(
2541 max_name
2542 .clone()
2543 .clamp(example_nonfqdn.clone(), max_name.clone()),
2544 max_name.clone(),
2545 );
2546
2547 let most_min_name = Name::from_utf8("").unwrap();
2551 let most_max_name = Name::from_utf8("most.max.example.com.").unwrap();
2552 assert_eq!(min_name.cmp(&example_nonfqdn), Ordering::Less);
2553 assert_eq!(most_min_name.cmp(&min_name), Ordering::Less);
2554 assert_eq!(most_min_name.cmp(&example_nonfqdn), Ordering::Less);
2555 assert_eq!(max_name.cmp(&example_fqdn), Ordering::Greater);
2556 assert_eq!(most_max_name.cmp(&max_name), Ordering::Greater);
2557 assert_eq!(most_max_name.cmp(&example_fqdn), Ordering::Greater);
2558 }
2559
2560 #[test]
2561 #[should_panic]
2562 fn test_ord_clamp_panic() {
2563 let min_name = Name::from_utf8("com").unwrap();
2564 let max_name = Name::from_utf8("max.example.com.").unwrap();
2565
2566 let _ = min_name.clone().clamp(max_name, min_name);
2568 }
2569
2570 #[test]
2571 #[cfg(feature = "std")]
2572 fn test_hash() {
2573 let mut hasher = DefaultHasher::new();
2575 let with_dot = Name::from_utf8("com.").unwrap();
2576 with_dot.hash(&mut hasher);
2577 let hash_with_dot = hasher.finish();
2578
2579 let mut hasher = DefaultHasher::new();
2580 let without_dot = Name::from_utf8("com").unwrap();
2581 without_dot.hash(&mut hasher);
2582 let hash_without_dot = hasher.finish();
2583 assert_ne!(with_dot, without_dot);
2584 assert_ne!(hash_with_dot, hash_without_dot);
2585 }
2586
2587 #[test]
2588 fn eq_ignore_root_tests() {
2589 let fqdn_name = Name::from_utf8("host.example.com.").unwrap();
2590 let relative_name = Name::from_utf8("host.example.com").unwrap();
2591 let upper_relative_name = Name::from_ascii("HOST.EXAMPLE.COM").unwrap();
2592
2593 assert_ne!(fqdn_name, relative_name);
2594 assert!(fqdn_name.eq_ignore_root(&relative_name));
2595 assert!(!fqdn_name.eq_ignore_root_case(&upper_relative_name));
2596 assert!(fqdn_name.eq_ignore_root(&upper_relative_name));
2597 }
2598
2599 #[test]
2600 fn rfc4034_canonical_ordering_example() {
2601 let names = Vec::from([
2603 Name::from_labels::<_, &[u8]>([b"example".as_slice()]).unwrap(),
2604 Name::from_labels::<_, &[u8]>([b"a".as_slice(), b"example".as_slice()]).unwrap(),
2605 Name::from_labels::<_, &[u8]>([
2606 b"yljkjljk".as_slice(),
2607 b"a".as_slice(),
2608 b"example".as_slice(),
2609 ])
2610 .unwrap(),
2611 Name::from_labels::<_, &[u8]>([
2612 b"Z".as_slice(),
2613 b"a".as_slice(),
2614 b"example".as_slice(),
2615 ])
2616 .unwrap(),
2617 Name::from_labels::<_, &[u8]>([
2618 b"zABC".as_slice(),
2619 b"a".as_slice(),
2620 b"EXAMPLE".as_slice(),
2621 ])
2622 .unwrap(),
2623 Name::from_labels::<_, &[u8]>([b"z".as_slice(), b"example".as_slice()]).unwrap(),
2624 Name::from_labels::<_, &[u8]>([
2625 b"\x01".as_slice(),
2626 b"z".as_slice(),
2627 b"example".as_slice(),
2628 ])
2629 .unwrap(),
2630 Name::from_labels::<_, &[u8]>([
2631 b"*".as_slice(),
2632 b"z".as_slice(),
2633 b"example".as_slice(),
2634 ])
2635 .unwrap(),
2636 Name::from_labels::<_, &[u8]>([
2637 b"\x80".as_slice(),
2638 b"z".as_slice(),
2639 b"example".as_slice(),
2640 ])
2641 .unwrap(),
2642 ]);
2643 let mut sorted = names.clone();
2644 sorted.sort();
2645 assert_eq!(names, sorted);
2646 }
2647}