Skip to content

Commit 0112085

Browse files
committed
Addressed some clippy warnings.
1 parent 3dc19ee commit 0112085

File tree

5 files changed

+952
-940
lines changed

5 files changed

+952
-940
lines changed

.github/workflows/build-and-test.yml

+22-22
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
name: Rust
2-
3-
on:
4-
push:
5-
branches: [ "main" ]
6-
pull_request:
7-
branches: [ "main" ]
8-
9-
env:
10-
CARGO_TERM_COLOR: always
11-
12-
jobs:
13-
build:
14-
15-
runs-on: ubuntu-latest
16-
17-
steps:
18-
- uses: actions/checkout@v3
19-
- name: Build
20-
run: cargo build --verbose
21-
- name: Run tests
22-
run: cargo test --workspace --verbose
1+
name: Rust
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
12+
jobs:
13+
build:
14+
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v3
19+
- name: Build
20+
run: cargo build --verbose
21+
- name: Run tests
22+
run: cargo test --workspace --verbose

inputfilter/src/filter/strip_tags.rs

+166-160
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,166 @@
1-
use std::borrow::Cow;
2-
use std::sync::OnceLock;
3-
use ammonia;
4-
5-
static DEFAULT_AMMONIA_BUILDER: OnceLock<ammonia::Builder> = OnceLock::new();
6-
7-
/// Sanitizes incoming HTML using the [Ammonia](https://docs.rs/ammonia/1.0.0/ammonia/) crate.
8-
///
9-
/// ```rust
10-
/// use walrs_inputfilter::filter::StripTags;
11-
/// use std::borrow::Cow;
12-
///
13-
/// let filter = StripTags::new();
14-
///
15-
/// for (i, (incoming_src, expected_src)) in [
16-
/// ("", ""),
17-
/// ("Socrates'", "Socrates'"),
18-
/// ("\"Hello\"", "\"Hello\""),
19-
/// ("Hello", "Hello"),
20-
/// ("<script>alert(\"Hello World\");</script>", ""), // Removes `script` tags, by default
21-
/// ("<p>The quick brown fox</p><style>p { font-weight: bold; }</style>",
22-
/// "<p>The quick brown fox</p>"), // Removes `style` tags, by default
23-
/// ("<p>The quick brown fox", "<p>The quick brown fox</p>") // Fixes erroneous markup, by default
24-
/// ]
25-
/// .into_iter().enumerate() {
26-
/// println!("Filter test {}: filter({}) == {}", i, incoming_src, expected_src);
27-
/// let result = filter.filter(incoming_src.into());
28-
///
29-
/// assert_eq!(result, expected_src.to_string());
30-
/// assert_eq!(filter(incoming_src.into()), result);
31-
/// }
32-
/// ```
33-
///
34-
pub struct StripTags<'a> {
35-
/// Ammonia builder used to sanitize incoming HTML.
36-
///
37-
/// If `None`, a default builder is used when `filter`/instance is called.
38-
pub ammonia: Option<ammonia::Builder<'a>>,
39-
}
40-
41-
impl<'a> StripTags<'a> {
42-
/// Constructs a new `StripTags` instance.
43-
pub fn new() -> Self {
44-
Self {
45-
ammonia: None,
46-
}
47-
}
48-
49-
/// Filters incoming HTML using the contained `ammonia::Builder` instance.
50-
/// If no instance is set gets/(and/or) initializes a new (default, and singleton) instance.
51-
///
52-
/// ```rust
53-
/// use std::borrow::Cow;
54-
/// use std::sync::OnceLock;
55-
/// use ammonia::Builder as AmmoniaBuilder;
56-
/// use walrs_inputfilter::filter::StripTags;
57-
///
58-
/// // Using default settings:
59-
/// let filter = StripTags::new();
60-
///
61-
/// let subject = r#"<p>Hello</p><script>alert('hello');</script>
62-
/// <style>p { font-weight: bold; }</style>"#;
63-
///
64-
/// // Ammonia removes `script`, and `style` tags by default.
65-
/// assert_eq!(filter.filter(subject.into()).trim(),
66-
/// "<p>Hello</p>"
67-
/// );
68-
///
69-
/// // Using custom settings:
70-
/// // Instantiate a custom sanitizer instance.
71-
/// let mut sanitizer = AmmoniaBuilder::default();
72-
/// let additional_allowed_tags = vec!["style"];
73-
///
74-
/// sanitizer
75-
/// .add_tags(&additional_allowed_tags) // Add 'style' tag to "tags-whitelist"
76-
///
77-
/// // Remove 'style' tag from "tags-blacklist"
78-
/// .rm_clean_content_tags(&additional_allowed_tags);
79-
///
80-
/// let filter = StripTags {
81-
/// ammonia: Some(sanitizer)
82-
/// };
83-
///
84-
/// // Notice `style` tags are no longer removed.
85-
/// assert_eq!(filter.filter(
86-
/// "<script>alert('hello');</script><style>p { font-weight: bold; }</style>".into()
87-
/// ),
88-
/// "<style>p { font-weight: bold; }</style>"
89-
/// );
90-
/// ```
91-
///
92-
pub fn filter<'b>(&self, input: Cow<'b, str>) -> Cow<'b, str> {
93-
match self.ammonia {
94-
None => Cow::Owned(
95-
DEFAULT_AMMONIA_BUILDER.get_or_init(|| ammonia::Builder::default())
96-
.clean(&input).to_string()
97-
),
98-
Some(ref sanitizer) => Cow::Owned(
99-
sanitizer.clean(&input).to_string()
100-
),
101-
}
102-
}
103-
}
104-
105-
impl<'a, 'b> FnOnce<(Cow<'b, str>, )> for StripTags<'a> {
106-
type Output = Cow<'b, str>;
107-
108-
extern "rust-call" fn call_once(self, args: (Cow<'b, str>, )) -> Self::Output {
109-
self.filter(args.0)
110-
}
111-
}
112-
113-
impl<'a, 'b> FnMut<(Cow<'b, str>, )> for StripTags<'a> {
114-
extern "rust-call" fn call_mut(&mut self, args: (Cow<'b, str>, )) -> Self::Output {
115-
self.filter(args.0)
116-
}
117-
}
118-
119-
impl<'a, 'b> Fn<(Cow<'b, str>, )> for StripTags<'a> {
120-
extern "rust-call" fn call(&self, args: (Cow<'b, str>, )) -> Self::Output {
121-
self.filter(args.0)
122-
}
123-
}
124-
125-
#[cfg(test)]
126-
mod test {
127-
use super::*;
128-
129-
#[test]
130-
fn test_construction() {
131-
let _ = StripTags::new();
132-
let _ = StripTags {
133-
ammonia: Some(ammonia::Builder::default()),
134-
};
135-
}
136-
137-
#[test]
138-
fn test_filter() {
139-
let filter = StripTags::new();
140-
141-
for (i, (incoming_src, expected_src)) in [
142-
("", ""),
143-
("Socrates'", "Socrates'"),
144-
("\"Hello\"", "\"Hello\""),
145-
("Hello", "Hello"),
146-
("<script>alert(\"Hello World\");</script>", ""), // Removes `script` tags, by default
147-
("<p>The quick brown fox</p><style>p { font-weight: bold; }</style>",
148-
"<p>The quick brown fox</p>"), // Removes `style` tags, by default
149-
("<p>The quick brown fox", "<p>The quick brown fox</p>") // Fixes erroneous markup
150-
]
151-
.into_iter().enumerate() {
152-
println!("Filter test {}: filter({}) == {}", i, incoming_src, expected_src);
153-
154-
let result = filter.filter(incoming_src.into());
155-
156-
assert_eq!(result, expected_src.to_string());
157-
assert_eq!(filter(incoming_src.into()), result);
158-
}
159-
}
160-
}
1+
use std::borrow::Cow;
2+
use std::sync::OnceLock;
3+
use ammonia;
4+
5+
static DEFAULT_AMMONIA_BUILDER: OnceLock<ammonia::Builder> = OnceLock::new();
6+
7+
/// Sanitizes incoming HTML using the [Ammonia](https://docs.rs/ammonia/1.0.0/ammonia/) crate.
8+
///
9+
/// ```rust
10+
/// use walrs_inputfilter::filter::StripTags;
11+
/// use std::borrow::Cow;
12+
///
13+
/// let filter = StripTags::new();
14+
///
15+
/// for (i, (incoming_src, expected_src)) in [
16+
/// ("", ""),
17+
/// ("Socrates'", "Socrates'"),
18+
/// ("\"Hello\"", "\"Hello\""),
19+
/// ("Hello", "Hello"),
20+
/// ("<script>alert(\"Hello World\");</script>", ""), // Removes `script` tags, by default
21+
/// ("<p>The quick brown fox</p><style>p { font-weight: bold; }</style>",
22+
/// "<p>The quick brown fox</p>"), // Removes `style` tags, by default
23+
/// ("<p>The quick brown fox", "<p>The quick brown fox</p>") // Fixes erroneous markup, by default
24+
/// ]
25+
/// .into_iter().enumerate() {
26+
/// println!("Filter test {}: filter({}) == {}", i, incoming_src, expected_src);
27+
/// let result = filter.filter(incoming_src.into());
28+
///
29+
/// assert_eq!(result, expected_src.to_string());
30+
/// assert_eq!(filter(incoming_src.into()), result);
31+
/// }
32+
/// ```
33+
///
34+
pub struct StripTags<'a> {
35+
/// Ammonia builder used to sanitize incoming HTML.
36+
///
37+
/// If `None`, a default builder is used when `filter`/instance is called.
38+
pub ammonia: Option<ammonia::Builder<'a>>,
39+
}
40+
41+
impl<'a> StripTags<'a> {
42+
/// Constructs a new `StripTags` instance.
43+
pub fn new() -> Self {
44+
Self {
45+
ammonia: None,
46+
}
47+
}
48+
49+
/// Filters incoming HTML using the contained `ammonia::Builder` instance.
50+
/// If no instance is set gets/(and/or) initializes a new (default, and singleton) instance.
51+
///
52+
/// ```rust
53+
/// use std::borrow::Cow;
54+
/// use std::sync::OnceLock;
55+
/// use ammonia::Builder as AmmoniaBuilder;
56+
/// use walrs_inputfilter::filter::StripTags;
57+
///
58+
/// // Using default settings:
59+
/// let filter = StripTags::new();
60+
///
61+
/// let subject = r#"<p>Hello</p><script>alert('hello');</script>
62+
/// <style>p { font-weight: bold; }</style>"#;
63+
///
64+
/// // Ammonia removes `script`, and `style` tags by default.
65+
/// assert_eq!(filter.filter(subject.into()).trim(),
66+
/// "<p>Hello</p>"
67+
/// );
68+
///
69+
/// // Using custom settings:
70+
/// // Instantiate a custom sanitizer instance.
71+
/// let mut sanitizer = AmmoniaBuilder::default();
72+
/// let additional_allowed_tags = vec!["style"];
73+
///
74+
/// sanitizer
75+
/// .add_tags(&additional_allowed_tags) // Add 'style' tag to "tags-whitelist"
76+
///
77+
/// // Remove 'style' tag from "tags-blacklist"
78+
/// .rm_clean_content_tags(&additional_allowed_tags);
79+
///
80+
/// let filter = StripTags {
81+
/// ammonia: Some(sanitizer)
82+
/// };
83+
///
84+
/// // Notice `style` tags are no longer removed.
85+
/// assert_eq!(filter.filter(
86+
/// "<script>alert('hello');</script><style>p { font-weight: bold; }</style>".into()
87+
/// ),
88+
/// "<style>p { font-weight: bold; }</style>"
89+
/// );
90+
/// ```
91+
///
92+
pub fn filter<'b>(&self, input: Cow<'b, str>) -> Cow<'b, str> {
93+
match self.ammonia {
94+
None => Cow::Owned(
95+
DEFAULT_AMMONIA_BUILDER.get_or_init(ammonia::Builder::default)
96+
.clean(&input).to_string()
97+
),
98+
Some(ref sanitizer) => Cow::Owned(
99+
sanitizer.clean(&input).to_string()
100+
),
101+
}
102+
}
103+
}
104+
105+
impl<'a> Default for StripTags<'a> {
106+
fn default() -> Self {
107+
Self::new()
108+
}
109+
}
110+
111+
impl<'a, 'b> FnOnce<(Cow<'b, str>, )> for StripTags<'a> {
112+
type Output = Cow<'b, str>;
113+
114+
extern "rust-call" fn call_once(self, args: (Cow<'b, str>, )) -> Self::Output {
115+
self.filter(args.0)
116+
}
117+
}
118+
119+
impl<'a, 'b> FnMut<(Cow<'b, str>, )> for StripTags<'a> {
120+
extern "rust-call" fn call_mut(&mut self, args: (Cow<'b, str>, )) -> Self::Output {
121+
self.filter(args.0)
122+
}
123+
}
124+
125+
impl<'a, 'b> Fn<(Cow<'b, str>, )> for StripTags<'a> {
126+
extern "rust-call" fn call(&self, args: (Cow<'b, str>, )) -> Self::Output {
127+
self.filter(args.0)
128+
}
129+
}
130+
131+
#[cfg(test)]
132+
mod test {
133+
use super::*;
134+
135+
#[test]
136+
fn test_construction() {
137+
let _ = StripTags::new();
138+
let _ = StripTags {
139+
ammonia: Some(ammonia::Builder::default()),
140+
};
141+
}
142+
143+
#[test]
144+
fn test_filter() {
145+
let filter = StripTags::new();
146+
147+
for (i, (incoming_src, expected_src)) in [
148+
("", ""),
149+
("Socrates'", "Socrates'"),
150+
("\"Hello\"", "\"Hello\""),
151+
("Hello", "Hello"),
152+
("<script>alert(\"Hello World\");</script>", ""), // Removes `script` tags, by default
153+
("<p>The quick brown fox</p><style>p { font-weight: bold; }</style>",
154+
"<p>The quick brown fox</p>"), // Removes `style` tags, by default
155+
("<p>The quick brown fox", "<p>The quick brown fox</p>") // Fixes erroneous markup
156+
]
157+
.into_iter().enumerate() {
158+
println!("Filter test {}: filter({}) == {}", i, incoming_src, expected_src);
159+
160+
let result = filter.filter(incoming_src.into());
161+
162+
assert_eq!(result, expected_src.to_string());
163+
assert_eq!(filter(incoming_src.into()), result);
164+
}
165+
}
166+
}

0 commit comments

Comments
 (0)