txt.rs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. use log::*;
  2. use crate::wire::*;
  3. /// A **TXT** record, which holds arbitrary descriptive text.
  4. ///
  5. /// # Encoding
  6. ///
  7. /// The text encoding is not specified, but this crate treats it as UTF-8.
  8. /// Invalid bytes are turned into the replacement character.
  9. ///
  10. /// # References
  11. ///
  12. /// - [RFC 1035 §3.3.14](https://tools.ietf.org/html/rfc1035) — Domain Names,
  13. /// Implementation and Specification (November 1987)
  14. #[derive(PartialEq, Debug)]
  15. pub struct TXT {
  16. /// The message contained in the record.
  17. pub message: String,
  18. }
  19. impl Wire for TXT {
  20. const NAME: &'static str = "TXT";
  21. const RR_TYPE: u16 = 16;
  22. #[cfg_attr(all(test, feature = "with_mutagen"), ::mutagen::mutate)]
  23. fn read(stated_length: u16, c: &mut Cursor<&[u8]>) -> Result<Self, WireError> {
  24. let mut buf = Vec::new();
  25. let mut total_len = 0_u16;
  26. loop {
  27. let next_len = c.read_u8()?;
  28. total_len += u16::from(next_len) + 1;
  29. trace!("Parsed slice length -> {:?} (total so far {:?})", next_len, total_len);
  30. for _ in 0 .. next_len {
  31. buf.push(c.read_u8()?);
  32. }
  33. if next_len < 255 {
  34. break;
  35. }
  36. else {
  37. trace!("Got length 255, so looping");
  38. }
  39. }
  40. let message = String::from_utf8_lossy(&buf).to_string();
  41. trace!("Parsed message -> {:?}", message);
  42. if stated_length == total_len {
  43. trace!("Length is correct");
  44. Ok(Self { message })
  45. }
  46. else {
  47. warn!("Length is incorrect (stated length {:?}, message length {:?})", stated_length, total_len);
  48. Err(WireError::WrongLabelLength { stated_length, length_after_labels: total_len })
  49. }
  50. }
  51. }
  52. #[cfg(test)]
  53. mod test {
  54. use super::*;
  55. use pretty_assertions::assert_eq;
  56. #[test]
  57. fn parses_one_iteration() {
  58. let buf = &[
  59. 0x06, // message chunk length
  60. 0x74, 0x78, 0x74, 0x20, 0x6d, 0x65, // message chunk
  61. ];
  62. assert_eq!(TXT::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
  63. TXT {
  64. message: String::from("txt me"),
  65. });
  66. }
  67. #[test]
  68. fn parses_two_iterations() {
  69. let buf = &[
  70. 0xFF, // message chunk length
  71. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  72. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  73. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  74. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  75. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  76. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  77. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  78. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  79. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  80. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  81. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  82. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  83. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  84. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  85. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  86. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  87. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  88. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  89. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  90. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  91. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  92. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  93. 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
  94. 0x41, 0x41, // exactly two hundred and fifty five ‘A’s (screaming)
  95. 0x04, // message chunk length
  96. 0x41, 0x41, 0x41, 0x41, // four more ‘A’s (the scream abruptly stops)
  97. ];
  98. assert_eq!(TXT::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
  99. TXT {
  100. message: String::from("AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
  101. AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
  102. AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
  103. AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
  104. AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
  105. AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
  106. AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
  107. AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
  108. AAAAAAAAAAAAAAAAAAAAAAAAAAA"),
  109. });
  110. // did you know you can just _write_ code like this, and nobody will stop you?
  111. }
  112. #[test]
  113. fn right_at_the_limit() {
  114. let buf = &[
  115. 0xFE, // message chunk length
  116. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  117. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  118. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  119. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  120. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  121. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  122. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  123. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  124. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  125. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  126. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  127. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  128. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  129. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  130. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  131. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  132. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  133. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  134. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  135. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  136. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  137. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  138. 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
  139. 0x42, // exactly two hundred and fifty four ‘B’s (a hive)
  140. ];
  141. assert_eq!(TXT::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
  142. TXT {
  143. message: String::from("BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
  144. BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
  145. BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
  146. BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
  147. BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
  148. BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
  149. BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
  150. BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
  151. BBBBBBBBBBBBBBBBBBBBBB"),
  152. });
  153. }
  154. #[test]
  155. fn incorrect_length() {
  156. let buf = &[
  157. 0x06, // message chunk length
  158. 0x74, 0x78, 0x74, 0x20, 0x6d, 0x65, // message chunk
  159. ];
  160. assert_eq!(TXT::read(123, &mut Cursor::new(buf)),
  161. Err(WireError::WrongLabelLength { stated_length: 123, length_after_labels: 7 }));
  162. }
  163. #[test]
  164. fn record_empty() {
  165. assert_eq!(TXT::read(0, &mut Cursor::new(&[])),
  166. Err(WireError::IO));
  167. }
  168. #[test]
  169. fn buffer_ends_abruptly() {
  170. let buf = &[
  171. 0x06, 0x74, // the start of a message
  172. ];
  173. assert_eq!(TXT::read(23, &mut Cursor::new(buf)),
  174. Err(WireError::IO));
  175. }
  176. }