Check-in [6e7d1e877b]
Logged in as anonymous
Overview
Comment:expand and reorganize
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6e7d1e877b804892cb7d7cf72e0c982ebf2a4d3478fa6cf7117e342d399cebbf
User & Date: arcade on 2026-07-31 15:10:10.067
Other Links: manifest | tags
Context
2026-07-31
15:11
make html tags check case insensitive check-in: bf99298edf user: arcade tags: trunk
15:10
expand and reorganize check-in: 6e7d1e877b user: arcade tags: trunk
15:09
add and propagate globs check-in: e67029b5a9 user: arcade tags: trunk
Changes
1
2
3
4
5






6
7
8
9


10












11
12


13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32





33
34

35
36
37
38
39
40
41
42
43
44
45
46
47










48
49
50






51
use smtp2tg::utils::{
	validate,
	RE_CLOSING,
	RE_DOMAIN,
};






use stacked_errors::Result;

#[test]
fn test_validate_valid_html() -> Result<()> {


	let html = "<p>Some <b>valid</b> HTML</p>";












	let escaped = validate(html)?;
	assert_eq!(escaped, "&lt;p&gt;Some &lt;b&gt;valid&lt;/b&gt; HTML&lt;/p&gt;");


	Ok(())
}

#[test]
fn test_validate_closing_tag() -> Result<()> {
	let html = "<p>Some <b>valid</b> HTML</p></code><a href='http://somewere.com'>Link injection!</a>";
	assert!(validate(html).is_err());

    assert!(validate("</pre>").is_err());
    assert!(validate("</code>").is_err());
    assert!(validate("</pre>\n").is_err());
    assert!(validate("</code>\t").is_err());
	Ok(())
}

#[test]
fn test_validate_empty_string() -> Result<()> {
	assert_eq!(validate("").unwrap(), "");
	Ok(())
}






#[test]
fn test_validate_whitespace() -> Result<()> {

	assert_eq!(validate("   \t\n").unwrap(), "   \t\n"); // no escaping for whitespace
	Ok(())
}

#[test]
fn test_regex_closing_tag_matches() {
	assert!(RE_CLOSING.is_match("</pre>"));
	assert!(RE_CLOSING.is_match("</code>\t>"));
	assert!(!RE_CLOSING.is_match("</div>")); // Not a pre/code tag
}

#[test]
fn test_regex_domain_matches() {










	assert!(RE_DOMAIN.is_match("example.com"));
	assert!(RE_DOMAIN.is_match("sub.example.co.uk"));
	assert!(!RE_DOMAIN.is_match("invalid@domain.com"));






}





>
>
>
>
>
>



|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>




|
<
<
>
|
|
<
<
<
<
|
|
|
|
|
<
|
>
>
>
>
>
|
<
>
|
<
|
|
<
<
<
<
<
|
<

|
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39


40
41
42




43
44
45
46
47

48
49
50
51
52
53
54

55
56

57
58





59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use smtp2tg::utils::{
	validate,
	RE_CLOSING,
	RE_DOMAIN,
};

use std::{
	borrow::Cow,
	mem::discriminant,
};

use stacked_errors::Result;

#[test]
fn test_validate_escaping_behavior () -> Result<()> {
	let cases: &[(&str, Cow<str>)] = &[
		// `validate` escapes HTML special characters.
		("<p>Some <b>valid</b> HTML</p>", Cow::Owned("&lt;p&gt;Some &lt;b&gt;valid&lt;/b&gt; HTML&lt;/p&gt;".into())),
		// Empty input is returned unchanged.
		("", Cow::Borrowed("")),
		// Whitespace-only input needs no escaping.
		("   \t\n", Cow::Borrowed("   \t\n")),
		// `validate` returns `Cow<'a, str>` borrowed from its input lifetime `'a`.
		// These two cases exercise both branches of that `Cow` to make sure the
		// explicit lifetime introduced on `validate` still lets callers observe a
		// zero-copy borrow when no escaping is required.
		("plain text without special html characters", Cow::Borrowed("plain text without special html characters")),
		("5 > 3 & 2 < 4", Cow::Owned("5 &gt; 3 &amp; 2 &lt; 4".into())),
	];
	for (input, expected) in cases {
		let result = validate(input)?;
		assert_eq!(&result, expected, "unexpected output for input {input:?}");
		assert_eq!(discriminant(&result), discriminant(expected), "wrong Cow variant for input {input:?}");
	}
	Ok(())
}

#[test]
fn test_validate_closing_tag_behavior () {


	let cases = [
		("</  pre  >", true),
		("</\tcode\t>", true),




		("</b>", false),
		("</Code>", true),
		("</code>", true),
		("</code>\t", true),
		("</code>\t>", true),

		("</div>", false), // Not a pre/code tag
		("</PRE>", true),
		("</pre>", true),
		("</pre>\n", true),
		("<p>Some <b>valid</b> HTML</p></code><a href='http://somewere.com'>Link injection!</a>", true),
		("<pre>", false),
	];

	for (input, expected) in cases {
		assert_eq!(RE_CLOSING.is_match(input), expected, "unexpected match result for {input:?}");

	}
}







#[test]
fn test_regex_domain_behavior() {
	let cases = [
		("", false),
		("-example.com", false),
		(".example.com", false),
		("123.456", true),
		("EXAMPLE.COM", false),
		("a", true),
		("a.b", true),
		("example-.com", false),
		("example..com", false),
		("example.com", true),
		("example.com.", false),
		("invalid@domain.com", false),
		("my-host.example.com", true),
		("sub.example.co.uk", true),
	];
	for (input, expected) in cases {
		assert_eq!(RE_DOMAIN.is_match(input), expected, "unexpected match result for {input:?}");
	}
}