Check-in [85fa6bddaa]
Logged in as anonymous
Overview
Comment:add html escaping
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 85fa6bddaa61c222f6da09f8f9deeb295723b2892c4acaf8d1faf92469d81210
User & Date: arcade on 2026-01-18 09:13:59.034
Other Links: manifest | tags
Context
2026-01-18
09:17
disable double github action check-in: 8e37b3f028 user: arcade tags: trunk
09:13
add html escaping check-in: 85fa6bddaa user: arcade tags: trunk
08:52
simplify HTML checks to making sure nothing actually breaks check-in: dafeec0481 user: arcade tags: trunk
Changes
625
626
627
628
629
630
631









632
633
634
635
636
637
638
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647







+
+
+
+
+
+
+
+
+







source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617aaa3557aef3810a6369d0a99fac8a080891b68bd9f9812a1eeda0c0730cbd"
dependencies = [
 "cfg-if",
 "libc",
 "windows-link",
]

[[package]]
name = "html-escape"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476"
dependencies = [
 "utf8-width",
]

[[package]]
name = "http"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
dependencies = [
1626
1627
1628
1629
1630
1631
1632

1633
1634
1635
1636
1637
1638
1639
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649







+







[[package]]
name = "smtp2tg"
version = "0.6.0"
dependencies = [
 "async-compat",
 "config",
 "hostname",
 "html-escape",
 "just-getopt",
 "lazy_static",
 "mail-parser",
 "mailin-embedded",
 "regex",
 "smol",
 "stacked_errors",
1974
1975
1976
1977
1978
1979
1980






1981
1982
1983
1984
1985
1986
1987
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003







+
+
+
+
+
+







dependencies = [
 "form_urlencoded",
 "idna",
 "percent-encoding",
 "serde",
]

[[package]]
name = "utf8-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1292c0d970b54115d14f2492fe0170adf21d68a1de108eebc51c1df4f346a091"

[[package]]
name = "utf8_iter"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"

[[package]]
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20












+







[package]
name = "smtp2tg"
version = "0.6.0"
authors = [ "arcade@b1t.name" ]
edition = "2024"
license = "0BSD"
repository = "http://fs.b1t.name/smtp2tg"

[dependencies]
async-compat = "0.2.5"
config = { version = "0.15", default-features = false, features = [ "toml" ] }
hostname = "0.4.1"
html-escape = "0.2.13"
just-getopt = "2.0.0"
lazy_static = "1.5.0"
mail-parser = { version = "0.11", features = ["serde"] }
mailin-embedded = "^0"
regex = "1.11.1"
smol = "2.0.2"
stacked_errors = "0.7.1"
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19











-
+







use crate::utils::validate;

use stacked_errors::{
	Result,
	StackableErr,
};

#[test]
fn check_valid () -> Result<()> {
	let html = "<p>Some <b>valid</b> HTML</p>";
	let res = validate(html).stack()?;
	assert_eq!(res, html);
	assert_eq!(res, "&lt;p&gt;Some &lt;b&gt;valid&lt;/b&gt; HTML&lt;/p&gt;");
	Ok(())
}

#[test]
#[should_panic = "Telegram closing tag found."]
fn check_invalid () {
	let html = "<p>Some <b>valid</b> HTML</p></code><a href='http://somewere.com'>Link injection!</a>";
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
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


+
+
+




















+
-
+



-
+


use crate::Cursor;

use std::borrow::Cow;

use html_escape::encode_text;
use lazy_static::lazy_static;
use regex::Regex;
use stacked_errors::{
	bail,
	Result,
};

lazy_static! {
	pub static ref RE_DOMAIN: Regex = Regex::new(r"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$").unwrap();
	pub static ref RE_CLOSING: Regex = Regex::new(r"</[ \t]*(pre|code)[ \t]*>").unwrap();
}

/// `Attachment` object to store number attachment data and corresponding file name
#[derive(Debug)]
pub struct Attachment {
	pub data: Cursor<Vec<u8>>,
	pub name: String,
}

/// Pass any text here to be validated as not breaking from Telegram preformatted blocks
/// escape all HTML chars afterwards
pub fn validate (text: &str) -> Result<&str> {
pub fn validate (text: &str) -> Result<Cow<'_, str>> {
	if RE_CLOSING.is_match(text) {
		bail!("Telegram closing tag found.");
	} else {
		Ok(text)
		Ok(encode_text(text))
	}
}