Skip to content

Commit 70ee60e

Browse files
committed
chore: clean up a few things around the script element check
Rename the flag to `allow_self_closing_script`, which may be verbose, but it's also not recommended to use anyway. And it feels a bit more descriptive, we don't ignore script errors, but allow the error of a self-closing script tag. Ensure that the configuration from the config file as well as from the CLI gets evaluated. Introduce an "options" struct, making future enhancements a bit simpler. Use plain strings for errors, vs concatenating and formatting.
1 parent b5a234c commit 70ee60e

File tree

5 files changed

+57
-34
lines changed

5 files changed

+57
-34
lines changed

src/common/html_rewrite.rs

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
use anyhow::{Error, Result};
1+
use anyhow::{bail, Result};
22
use lol_html::{element, html_content::Element, HtmlRewriter, Settings};
33

4+
#[derive(Clone, Debug, Default)]
5+
pub struct DocumentOptions {
6+
/// Ignore self-closing script warnings
7+
pub allow_self_closing_script: bool,
8+
}
9+
410
/// A wrapper for Html modifications, and rewrites.
511
#[derive(Debug)]
612
pub struct Document(Vec<u8>);
@@ -14,33 +20,26 @@ impl AsRef<[u8]> for Document {
1420
impl Document {
1521
/// Create a new document
1622
///
17-
/// Note: if this is not a valid HTML document, it will fail later on.
18-
// In case we want to add more things to check in the future, we can take in the config as an
19-
// argument, and `anyhow::Result<()>` could be
20-
// replaced with an `std::result::Result<(), MyErrorEnum>` in case we want to handle the error
21-
// case differently depending on the error variant.
22-
pub fn new(data: impl Into<Vec<u8>>, ignore_script_error: bool) -> Result<Self> {
23+
/// This will fail if a non-valid HTML is provided or a self-closing script element is found
24+
/// and the self-closing script element is not allowed in the options.
25+
pub fn new(data: impl Into<Vec<u8>>, options: DocumentOptions) -> Result<Self> {
2326
let doc = Self(data.into());
2427

25-
// Check for self closed script tags such as "<script.../>"
26-
doc.select("script[data-trunk]", |el| {
28+
// Check for self-closed script tags such as "<script.../>"
29+
doc.select("script", |el| {
2730
if el.is_self_closing() {
28-
const SELF_CLOSED_SCRIPT: &str = concat!(
29-
"Self closing script tag found. ",
30-
r#"Replace the self closing script tag ("<script .../>") with a normally closed one such as "<script ...></script>"."#,
31-
"\nFor more information please take a look at https://github.com/trunk-rs/trunk/discussions/771."
32-
);
33-
34-
if ignore_script_error {
35-
tracing::warn!("{}", SELF_CLOSED_SCRIPT);
31+
if options.allow_self_closing_script {
32+
tracing::warn!("Self-closing script tag found (allowed by configuration)");
3633
}
3734
else {
38-
return Err(Error::msg(
39-
format!("{}\n{}",
40-
SELF_CLOSED_SCRIPT,
41-
r#"In case this is a false positive the "--ignore-script-error" flag can be used to issue a warning instead."#
42-
)
43-
))
35+
bail!(
36+
r#"Self-closing script tag found.
37+
38+
Replace the self-closing script tag ("<script .../>") with a normally closed one such as "<script ...></script>".
39+
For more information, please take a look at https://github.com/trunk-rs/trunk/discussions/771."
40+
41+
In case this is a false positive, the "--allow-self-closing-script" flag can be used to issue a warning instead."#
42+
)
4443
}
4544
}
4645
Ok(())
@@ -147,19 +146,25 @@ impl Document {
147146
mod test {
148147
use super::*;
149148

149+
/// Run some basic tests with a spec-compliant HTML file.
150+
///
151+
/// The focus is on the `<script>` element, and around other self-closing elements. If a
152+
/// self-closing script tag is being used which, according to the spec should not be used, bad
153+
/// things may happen. This test is there to test our expectation towards a spec-compliant file.
150154
#[test]
151155
fn test_script_spec() {
152156
let mut doc = Document::new(
153157
r#"
154158
<html>
155159
<head>
160+
<link/>
156161
<script href="test"></script>
157162
<link>
158163
</head>
159164
<body></body>
160165
</html>
161166
"#,
162-
false,
167+
Default::default(),
163168
)
164169
.expect("this is valid HTML");
165170

@@ -173,6 +178,7 @@ mod test {
173178
r#"
174179
<html>
175180
<head>
181+
<link/>
176182
<script href="test"><span>here</span></script>
177183
<link>
178184
</head>
@@ -182,9 +188,17 @@ mod test {
182188
);
183189
}
184190

191+
/// Ensure we get an error for any self-closing script tag
185192
#[test]
186193
fn test_self_closing_script_tag() {
187-
let doc = Document::new("<script data-trunk/>", false);
194+
let doc = Document::new("<script/>", Default::default());
195+
assert!(doc.is_err());
196+
}
197+
198+
/// Ensure we get an error for a self-closing trunk script tag.
199+
#[test]
200+
fn test_self_closing_trunk_script_tag() {
201+
let doc = Document::new("<script data-trunk/>", Default::default());
188202
assert!(doc.is_err());
189203
}
190204
}

src/config/models/build.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,11 @@ pub struct ConfigOptsBuild {
143143
#[arg(long)]
144144
pub no_sri: bool,
145145

146-
/// Ignore error's related to self closing script elements, and instead issue a warning.
146+
/// Ignore error's related to self-closing script elements, and instead issue a warning.
147147
///
148-
/// Since this error can cause the HTML output to be truncated, only enable this in case you
148+
/// Since this issue can cause the HTML output to be truncated, only enable this in case you
149149
/// are sure it is caused due to a false positive.
150150
#[serde(default)]
151151
#[arg(long)]
152-
pub ignore_script_error: bool,
152+
pub allow_self_closing_script: bool,
153153
}

src/config/models/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@ impl ConfigOpts {
362362
if l.no_sri {
363363
g.no_sri = true;
364364
}
365+
// NOTE: this can not be disabled in the cascade.
366+
if l.allow_self_closing_script {
367+
g.allow_self_closing_script = true;
368+
}
365369

366370
Some(g)
367371
}

src/config/rt/build.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ pub struct RtcBuild {
7878
pub minify: Minify,
7979
/// Allow disabling SRI
8080
pub no_sri: bool,
81-
/// Ignore error's due to self closed script tags, instead will issue a warning.
82-
pub ignore_script_error: bool,
81+
/// Ignore error's due to self-closed script tags, instead will issue a warning.
82+
pub allow_self_closing_script: bool,
8383
}
8484

8585
impl RtcBuild {
@@ -185,7 +185,7 @@ impl RtcBuild {
185185
accept_invalid_certs: opts.accept_invalid_certs,
186186
minify,
187187
no_sri: opts.no_sri,
188-
ignore_script_error: opts.ignore_script_error,
188+
allow_self_closing_script: opts.allow_self_closing_script,
189189
})
190190
}
191191

@@ -228,7 +228,7 @@ impl RtcBuild {
228228
accept_invalid_certs: None,
229229
minify: Minify::Never,
230230
no_sri: false,
231-
ignore_script_error: false,
231+
allow_self_closing_script: false,
232232
})
233233
}
234234

src/pipelines/html.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Source HTML pipelines.
22
33
use crate::{
4-
common::html_rewrite::Document,
4+
common::html_rewrite::{Document, DocumentOptions},
55
config::{RtcBuild, WsProtocol},
66
hooks::{spawn_hooks, wait_hooks},
77
pipelines::{
@@ -83,7 +83,12 @@ impl HtmlPipeline {
8383

8484
// Open the source HTML file for processing.
8585
let raw_html = fs::read(&self.target_html_path).await?;
86-
let mut target_html = Document::new(raw_html, self.cfg.ignore_script_error)?;
86+
let mut target_html = Document::new(
87+
raw_html,
88+
DocumentOptions {
89+
allow_self_closing_script: self.cfg.allow_self_closing_script,
90+
},
91+
)?;
8792
let mut partial_assets = vec![];
8893

8994
// Since the `lol_html` doesn't provide an iterator for elements, we must use our own id.

0 commit comments

Comments
 (0)