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










[[package]]
name = "http"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
dependencies = [







>
>
>
>
>
>
>
>
>







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
[[package]]
name = "smtp2tg"
version = "0.6.0"
dependencies = [
 "async-compat",
 "config",
 "hostname",

 "just-getopt",
 "lazy_static",
 "mail-parser",
 "mailin-embedded",
 "regex",
 "smol",
 "stacked_errors",







>







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
dependencies = [
 "form_urlencoded",
 "idna",
 "percent-encoding",
 "serde",
]







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

[[package]]







>
>
>
>
>
>







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
[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"

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
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
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);
	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
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, "&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
use crate::Cursor;




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

pub fn validate (text: &str) -> Result<&str> {
	if RE_CLOSING.is_match(text) {
		bail!("Telegram closing tag found.");
	} else {
		Ok(text)
	}
}


>
>
>




















>
|



|


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<Cow<'_, str>> {
	if RE_CLOSING.is_match(text) {
		bail!("Telegram closing tag found.");
	} else {
		Ok(encode_text(text))
	}
}