0000: 75 73 65 20 73 6d 74 70 32 74 67 3a 3a 75 74 69 use smtp2tg::uti
0010: 6c 73 3a 3a 7b 0a 09 76 61 6c 69 64 61 74 65 2c ls::{..validate,
0020: 0a 09 52 45 5f 43 4c 4f 53 49 4e 47 2c 0a 09 52 ..RE_CLOSING,..R
0030: 45 5f 44 4f 4d 41 49 4e 2c 0a 7d 3b 0a 0a 75 73 E_DOMAIN,.};..us
0040: 65 20 73 74 64 3a 3a 7b 0a 09 62 6f 72 72 6f 77 e std::{..borrow
0050: 3a 3a 43 6f 77 2c 0a 09 6d 65 6d 3a 3a 64 69 73 ::Cow,..mem::dis
0060: 63 72 69 6d 69 6e 61 6e 74 2c 0a 7d 3b 0a 0a 75 criminant,.};..u
0070: 73 65 20 73 74 61 63 6b 65 64 5f 65 72 72 6f 72 se stacked_error
0080: 73 3a 3a 52 65 73 75 6c 74 3b 0a 0a 23 5b 74 65 s::Result;..#[te
0090: 73 74 5d 0a 66 6e 20 74 65 73 74 5f 76 61 6c 69 st].fn test_vali
00a0: 64 61 74 65 5f 65 73 63 61 70 69 6e 67 5f 62 65 date_escaping_be
00b0: 68 61 76 69 6f 72 20 28 29 20 2d 3e 20 52 65 73 havior () -> Res
00c0: 75 6c 74 3c 28 29 3e 20 7b 0a 09 6c 65 74 20 63 ult<()> {..let c
00d0: 61 73 65 73 3a 20 26 5b 28 26 73 74 72 2c 20 43 ases: &[(&str, C
00e0: 6f 77 3c 73 74 72 3e 29 5d 20 3d 20 26 5b 0a 09 ow<str>)] = &[..
00f0: 09 2f 2f 20 60 76 61 6c 69 64 61 74 65 60 20 65 .// `validate` e
0100: 73 63 61 70 65 73 20 48 54 4d 4c 20 73 70 65 63 scapes HTML spec
0110: 69 61 6c 20 63 68 61 72 61 63 74 65 72 73 2e 0a ial characters..
0120: 09 09 28 22 3c 70 3e 53 6f 6d 65 20 3c 62 3e 76 ..("<p>Some <b>v
0130: 61 6c 69 64 3c 2f 62 3e 20 48 54 4d 4c 3c 2f 70 alid</b> HTML</p
0140: 3e 22 2c 20 43 6f 77 3a 3a 4f 77 6e 65 64 28 22 >", Cow::Owned("
0150: 26 6c 74 3b 70 26 67 74 3b 53 6f 6d 65 20 26 6c <p>Some &l
0160: 74 3b 62 26 67 74 3b 76 61 6c 69 64 26 6c 74 3b t;b>valid<
0170: 2f 62 26 67 74 3b 20 48 54 4d 4c 26 6c 74 3b 2f /b> HTML</
0180: 70 26 67 74 3b 22 2e 69 6e 74 6f 28 29 29 29 2c p>".into())),
0190: 0a 09 09 2f 2f 20 45 6d 70 74 79 20 69 6e 70 75 ...// Empty inpu
01a0: 74 20 69 73 20 72 65 74 75 72 6e 65 64 20 75 6e t is returned un
01b0: 63 68 61 6e 67 65 64 2e 0a 09 09 28 22 22 2c 20 changed....("",
01c0: 43 6f 77 3a 3a 42 6f 72 72 6f 77 65 64 28 22 22 Cow::Borrowed(""
01d0: 29 29 2c 0a 09 09 2f 2f 20 57 68 69 74 65 73 70 )),...// Whitesp
01e0: 61 63 65 2d 6f 6e 6c 79 20 69 6e 70 75 74 20 6e ace-only input n
01f0: 65 65 64 73 20 6e 6f 20 65 73 63 61 70 69 6e 67 eeds no escaping
0200: 2e 0a 09 09 28 22 20 20 20 5c 74 5c 6e 22 2c 20 ....(" \t\n",
0210: 43 6f 77 3a 3a 42 6f 72 72 6f 77 65 64 28 22 20 Cow::Borrowed("
0220: 20 20 5c 74 5c 6e 22 29 29 2c 0a 09 09 2f 2f 20 \t\n")),...//
0230: 60 76 61 6c 69 64 61 74 65 60 20 72 65 74 75 72 `validate` retur
0240: 6e 73 20 60 43 6f 77 3c 27 61 2c 20 73 74 72 3e ns `Cow<'a, str>
0250: 60 20 62 6f 72 72 6f 77 65 64 20 66 72 6f 6d 20 ` borrowed from
0260: 69 74 73 20 69 6e 70 75 74 20 6c 69 66 65 74 69 its input lifeti
0270: 6d 65 20 60 27 61 60 2e 0a 09 09 2f 2f 20 54 68 me `'a`....// Th
0280: 65 73 65 20 74 77 6f 20 63 61 73 65 73 20 65 78 ese two cases ex
0290: 65 72 63 69 73 65 20 62 6f 74 68 20 62 72 61 6e ercise both bran
02a0: 63 68 65 73 20 6f 66 20 74 68 61 74 20 60 43 6f ches of that `Co
02b0: 77 60 20 74 6f 20 6d 61 6b 65 20 73 75 72 65 20 w` to make sure
02c0: 74 68 65 0a 09 09 2f 2f 20 65 78 70 6c 69 63 69 the...// explici
02d0: 74 20 6c 69 66 65 74 69 6d 65 20 69 6e 74 72 6f t lifetime intro
02e0: 64 75 63 65 64 20 6f 6e 20 60 76 61 6c 69 64 61 duced on `valida
02f0: 74 65 60 20 73 74 69 6c 6c 20 6c 65 74 73 20 63 te` still lets c
0300: 61 6c 6c 65 72 73 20 6f 62 73 65 72 76 65 20 61 allers observe a
0310: 0a 09 09 2f 2f 20 7a 65 72 6f 2d 63 6f 70 79 20 ...// zero-copy
0320: 62 6f 72 72 6f 77 20 77 68 65 6e 20 6e 6f 20 65 borrow when no e
0330: 73 63 61 70 69 6e 67 20 69 73 20 72 65 71 75 69 scaping is requi
0340: 72 65 64 2e 0a 09 09 28 22 70 6c 61 69 6e 20 74 red....("plain t
0350: 65 78 74 20 77 69 74 68 6f 75 74 20 73 70 65 63 ext without spec
0360: 69 61 6c 20 68 74 6d 6c 20 63 68 61 72 61 63 74 ial html charact
0370: 65 72 73 22 2c 20 43 6f 77 3a 3a 42 6f 72 72 6f ers", Cow::Borro
0380: 77 65 64 28 22 70 6c 61 69 6e 20 74 65 78 74 20 wed("plain text
0390: 77 69 74 68 6f 75 74 20 73 70 65 63 69 61 6c 20 without special
03a0: 68 74 6d 6c 20 63 68 61 72 61 63 74 65 72 73 22 html characters"
03b0: 29 29 2c 0a 09 09 28 22 35 20 3e 20 33 20 26 20 )),...("5 > 3 &
03c0: 32 20 3c 20 34 22 2c 20 43 6f 77 3a 3a 4f 77 6e 2 < 4", Cow::Own
03d0: 65 64 28 22 35 20 26 67 74 3b 20 33 20 26 61 6d ed("5 > 3 &am
03e0: 70 3b 20 32 20 26 6c 74 3b 20 34 22 2e 69 6e 74 p; 2 < 4".int
03f0: 6f 28 29 29 29 2c 0a 09 5d 3b 0a 09 66 6f 72 20 o())),..];..for
0400: 28 69 6e 70 75 74 2c 20 65 78 70 65 63 74 65 64 (input, expected
0410: 29 20 69 6e 20 63 61 73 65 73 20 7b 0a 09 09 6c ) in cases {...l
0420: 65 74 20 72 65 73 75 6c 74 20 3d 20 76 61 6c 69 et result = vali
0430: 64 61 74 65 28 69 6e 70 75 74 29 3f 3b 0a 09 09 date(input)?;...
0440: 61 73 73 65 72 74 5f 65 71 21 28 26 72 65 73 75 assert_eq!(&resu
0450: 6c 74 2c 20 65 78 70 65 63 74 65 64 2c 20 22 75 lt, expected, "u
0460: 6e 65 78 70 65 63 74 65 64 20 6f 75 74 70 75 74 nexpected output
0470: 20 66 6f 72 20 69 6e 70 75 74 20 7b 69 6e 70 75 for input {inpu
0480: 74 3a 3f 7d 22 29 3b 0a 09 09 61 73 73 65 72 74 t:?}");...assert
0490: 5f 65 71 21 28 64 69 73 63 72 69 6d 69 6e 61 6e _eq!(discriminan
04a0: 74 28 26 72 65 73 75 6c 74 29 2c 20 64 69 73 63 t(&result), disc
04b0: 72 69 6d 69 6e 61 6e 74 28 65 78 70 65 63 74 65 riminant(expecte
04c0: 64 29 2c 20 22 77 72 6f 6e 67 20 43 6f 77 20 76 d), "wrong Cow v
04d0: 61 72 69 61 6e 74 20 66 6f 72 20 69 6e 70 75 74 ariant for input
04e0: 20 7b 69 6e 70 75 74 3a 3f 7d 22 29 3b 0a 09 7d {input:?}");..}
04f0: 0a 09 4f 6b 28 28 29 29 0a 7d 0a 0a 23 5b 74 65 ..Ok(()).}..#[te
0500: 73 74 5d 0a 66 6e 20 74 65 73 74 5f 76 61 6c 69 st].fn test_vali
0510: 64 61 74 65 5f 63 6c 6f 73 69 6e 67 5f 74 61 67 date_closing_tag
0520: 5f 62 65 68 61 76 69 6f 72 20 28 29 20 7b 0a 09 _behavior () {..
0530: 6c 65 74 20 63 61 73 65 73 20 3d 20 5b 0a 09 09 let cases = [...
0540: 28 22 3c 2f 20 20 70 72 65 20 20 3e 22 2c 20 74 ("</ pre >", t
0550: 72 75 65 29 2c 0a 09 09 28 22 3c 2f 5c 74 63 6f rue),...("</\tco
0560: 64 65 5c 74 3e 22 2c 20 74 72 75 65 29 2c 0a 09 de\t>", true),..
0570: 09 28 22 3c 2f 62 3e 22 2c 20 66 61 6c 73 65 29 .("</b>", false)
0580: 2c 0a 09 09 28 22 3c 2f 43 6f 64 65 3e 22 2c 20 ,...("</Code>",
0590: 74 72 75 65 29 2c 0a 09 09 28 22 3c 2f 63 6f 64 true),...("</cod
05a0: 65 3e 22 2c 20 74 72 75 65 29 2c 0a 09 09 28 22 e>", true),...("
05b0: 3c 2f 63 6f 64 65 3e 5c 74 22 2c 20 74 72 75 65 </code>\t", true
05c0: 29 2c 0a 09 09 28 22 3c 2f 63 6f 64 65 3e 5c 74 ),...("</code>\t
05d0: 3e 22 2c 20 74 72 75 65 29 2c 0a 09 09 28 22 3c >", true),...("<
05e0: 2f 64 69 76 3e 22 2c 20 66 61 6c 73 65 29 2c 20 /div>", false),
05f0: 2f 2f 20 4e 6f 74 20 61 20 70 72 65 2f 63 6f 64 // Not a pre/cod
0600: 65 20 74 61 67 0a 09 09 28 22 3c 2f 50 52 45 3e e tag...("</PRE>
0610: 22 2c 20 74 72 75 65 29 2c 0a 09 09 28 22 3c 2f ", true),...("</
0620: 70 72 65 3e 22 2c 20 74 72 75 65 29 2c 0a 09 09 pre>", true),...
0630: 28 22 3c 2f 70 72 65 3e 5c 6e 22 2c 20 74 72 75 ("</pre>\n", tru
0640: 65 29 2c 0a 09 09 28 22 3c 70 3e 53 6f 6d 65 20 e),...("<p>Some
0650: 3c 62 3e 76 61 6c 69 64 3c 2f 62 3e 20 48 54 4d <b>valid</b> HTM
0660: 4c 3c 2f 70 3e 3c 2f 63 6f 64 65 3e 3c 61 20 68 L</p></code><a h
0670: 72 65 66 3d 27 68 74 74 70 3a 2f 2f 73 6f 6d 65 ref='http://some
0680: 77 65 72 65 2e 63 6f 6d 27 3e 4c 69 6e 6b 20 69 were.com'>Link i
0690: 6e 6a 65 63 74 69 6f 6e 21 3c 2f 61 3e 22 2c 20 njection!</a>",
06a0: 74 72 75 65 29 2c 0a 09 09 28 22 3c 70 72 65 3e true),...("<pre>
06b0: 22 2c 20 66 61 6c 73 65 29 2c 0a 09 5d 3b 0a 09 ", false),..];..
06c0: 66 6f 72 20 28 69 6e 70 75 74 2c 20 65 78 70 65 for (input, expe
06d0: 63 74 65 64 29 20 69 6e 20 63 61 73 65 73 20 7b cted) in cases {
06e0: 0a 09 09 61 73 73 65 72 74 5f 65 71 21 28 52 45 ...assert_eq!(RE
06f0: 5f 43 4c 4f 53 49 4e 47 2e 69 73 5f 6d 61 74 63 _CLOSING.is_matc
0700: 68 28 69 6e 70 75 74 29 2c 20 65 78 70 65 63 74 h(input), expect
0710: 65 64 2c 20 22 75 6e 65 78 70 65 63 74 65 64 20 ed, "unexpected
0720: 6d 61 74 63 68 20 72 65 73 75 6c 74 20 66 6f 72 match result for
0730: 20 7b 69 6e 70 75 74 3a 3f 7d 22 29 3b 0a 09 7d {input:?}");..}
0740: 0a 7d 0a 0a 23 5b 74 65 73 74 5d 0a 66 6e 20 74 .}..#[test].fn t
0750: 65 73 74 5f 72 65 67 65 78 5f 64 6f 6d 61 69 6e est_regex_domain
0760: 5f 62 65 68 61 76 69 6f 72 28 29 20 7b 0a 09 6c _behavior() {..l
0770: 65 74 20 63 61 73 65 73 20 3d 20 5b 0a 09 09 28 et cases = [...(
0780: 22 22 2c 20 66 61 6c 73 65 29 2c 0a 09 09 28 22 "", false),...("
0790: 2d 65 78 61 6d 70 6c 65 2e 63 6f 6d 22 2c 20 66 -example.com", f
07a0: 61 6c 73 65 29 2c 0a 09 09 28 22 2e 65 78 61 6d alse),...(".exam
07b0: 70 6c 65 2e 63 6f 6d 22 2c 20 66 61 6c 73 65 29 ple.com", false)
07c0: 2c 0a 09 09 28 22 31 32 33 2e 34 35 36 22 2c 20 ,...("123.456",
07d0: 74 72 75 65 29 2c 0a 09 09 28 22 45 58 41 4d 50 true),...("EXAMP
07e0: 4c 45 2e 43 4f 4d 22 2c 20 66 61 6c 73 65 29 2c LE.COM", false),
07f0: 0a 09 09 28 22 61 22 2c 20 74 72 75 65 29 2c 0a ...("a", true),.
0800: 09 09 28 22 61 2e 62 22 2c 20 74 72 75 65 29 2c ..("a.b", true),
0810: 0a 09 09 28 22 65 78 61 6d 70 6c 65 2d 2e 63 6f ...("example-.co
0820: 6d 22 2c 20 66 61 6c 73 65 29 2c 0a 09 09 28 22 m", false),...("
0830: 65 78 61 6d 70 6c 65 2e 2e 63 6f 6d 22 2c 20 66 example..com", f
0840: 61 6c 73 65 29 2c 0a 09 09 28 22 65 78 61 6d 70 alse),...("examp
0850: 6c 65 2e 63 6f 6d 22 2c 20 74 72 75 65 29 2c 0a le.com", true),.
0860: 09 09 28 22 65 78 61 6d 70 6c 65 2e 63 6f 6d 2e ..("example.com.
0870: 22 2c 20 66 61 6c 73 65 29 2c 0a 09 09 28 22 69 ", false),...("i
0880: 6e 76 61 6c 69 64 40 64 6f 6d 61 69 6e 2e 63 6f nvalid@domain.co
0890: 6d 22 2c 20 66 61 6c 73 65 29 2c 0a 09 09 28 22 m", false),...("
08a0: 6d 79 2d 68 6f 73 74 2e 65 78 61 6d 70 6c 65 2e my-host.example.
08b0: 63 6f 6d 22 2c 20 74 72 75 65 29 2c 0a 09 09 28 com", true),...(
08c0: 22 73 75 62 2e 65 78 61 6d 70 6c 65 2e 63 6f 2e "sub.example.co.
08d0: 75 6b 22 2c 20 74 72 75 65 29 2c 0a 09 5d 3b 0a uk", true),..];.
08e0: 09 66 6f 72 20 28 69 6e 70 75 74 2c 20 65 78 70 .for (input, exp
08f0: 65 63 74 65 64 29 20 69 6e 20 63 61 73 65 73 20 ected) in cases
0900: 7b 0a 09 09 61 73 73 65 72 74 5f 65 71 21 28 52 {...assert_eq!(R
0910: 45 5f 44 4f 4d 41 49 4e 2e 69 73 5f 6d 61 74 63 E_DOMAIN.is_matc
0920: 68 28 69 6e 70 75 74 29 2c 20 65 78 70 65 63 74 h(input), expect
0930: 65 64 2c 20 22 75 6e 65 78 70 65 63 74 65 64 20 ed, "unexpected
0940: 6d 61 74 63 68 20 72 65 73 75 6c 74 20 66 6f 72 match result for
0950: 20 7b 69 6e 70 75 74 3a 3f 7d 22 29 3b 0a 09 7d {input:?}");..}
0960: 0a 7d 0a .}.