Skip to content

Commit 4746bb1

Browse files
authored
fix: not try to add integrity to tags with remote url (#12262)
1 parent 888337a commit 4746bb1

File tree

7 files changed

+95
-1
lines changed

7 files changed

+95
-1
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/rspack_plugin_sri/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ serde_json = { workspace = true }
3333
sha2 = { workspace = true }
3434
tokio = { workspace = true }
3535
tracing = { workspace = true }
36+
url = { workspace = true }
3637
urlencoding = { workspace = true }
3738

3839
[package.metadata.cargo-shear]
3940
ignored = ["tracing", "async-trait", "rspack_hash", "tokio"]
4041

4142
[lints.rust.unexpected_cfgs]
42-
level = "warn"
4343
check-cfg = ['cfg(allocative)']
44+
level = "warn"

crates/rspack_plugin_sri/src/html.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rspack_plugin_html::{
1111
};
1212
use rustc_hash::FxHashMap as HashMap;
1313
use tokio::sync::RwLock;
14+
use url::Url;
1415

1516
use crate::{
1617
SRICompilationContext, SubresourceIntegrityHashFunction, SubresourceIntegrityPlugin,
@@ -170,6 +171,14 @@ async fn process_tag(
170171
return Ok(None);
171172
};
172173

174+
// A tag which is not generated by chunks should be skipped
175+
if let Ok(url) = Url::parse(&tag_src)
176+
&& (url.scheme() == "http" || url.scheme() == "https")
177+
&& (public_path.is_empty() || !tag_src.starts_with(public_path))
178+
{
179+
return Ok(None);
180+
}
181+
173182
let src = get_asset_path(&tag_src, public_path);
174183
if let Some(integrity) =
175184
get_integrity_checksum_for_asset(&src, integrities, normalized_integrities).await

packages/rspack/src/builtin-plugin/SubresourceIntegrityPlugin.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,18 @@ export class SubresourceIntegrityPlugin extends NativeSubresourceIntegrityPlugin
190190
return;
191191
}
192192

193+
try {
194+
const url = new URL(tagSrc);
195+
if (
196+
(url.protocol === "http:" || url.protocol === "https:") &&
197+
(!publicPath || !tagSrc.startsWith(publicPath))
198+
) {
199+
return;
200+
}
201+
} catch (_) {
202+
// do nothing
203+
}
204+
193205
const src = relative(publicPath, decodeURIComponent(tagSrc));
194206
tag.attributes.integrity =
195207
this.getIntegrityChecksumForAsset(src) ||
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
it("should compile", () => { });
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
const { experiments, HtmlRspackPlugin } = require("@rspack/core");
2+
const HtmlWebpackPlugin = require("html-webpack-plugin");
3+
const fs = require("fs");
4+
const path = require("path");
5+
6+
/** @type {import("@rspack/core").Configuration} */
7+
module.exports = (_, { testPath }) => ([{
8+
target: "web",
9+
output: {
10+
crossOriginLoading: "anonymous",
11+
},
12+
plugins: [
13+
new experiments.SubresourceIntegrityPlugin(),
14+
new HtmlRspackPlugin({
15+
filename: "index.html",
16+
}),
17+
{
18+
apply(compiler) {
19+
compiler.hooks.compilation.tap('TestPlugin', (compilation) => {
20+
HtmlRspackPlugin.getCompilationHooks(compilation).beforeAssetTagGeneration.tap('SubresourceIntegrityPlugin', (data) => {
21+
data.assets.js.push("http://localhost:3000/index.js");
22+
});
23+
});
24+
}
25+
},
26+
{
27+
apply(compiler) {
28+
compiler.hooks.done.tap('TestPlugin', () => {
29+
const htmlContent = fs.readFileSync(path.resolve(testPath, "index.html"), "utf-8");
30+
expect(htmlContent).toMatch(/<script crossorigin defer integrity=".+" src="bundle0\.js">/);
31+
expect(htmlContent).toMatch(/<script defer src="http:\/\/localhost:3000\/index\.js">/);
32+
});
33+
}
34+
}
35+
],
36+
}, {
37+
target: "web",
38+
output: {
39+
crossOriginLoading: "anonymous",
40+
},
41+
plugins: [
42+
new experiments.SubresourceIntegrityPlugin({
43+
htmlPlugin: require.resolve("html-webpack-plugin"),
44+
}),
45+
new HtmlWebpackPlugin({
46+
filename: "index1.html",
47+
}),
48+
{
49+
apply(compiler) {
50+
compiler.hooks.compilation.tap('TestPlugin', (compilation) => {
51+
HtmlWebpackPlugin.getCompilationHooks(compilation).beforeAssetTagGeneration.tap('SubresourceIntegrityPlugin', (data) => {
52+
data.assets.js.push("http://localhost:3000/index.js");
53+
});
54+
});
55+
}
56+
},
57+
{
58+
apply(compiler) {
59+
compiler.hooks.done.tap('TestPlugin', () => {
60+
const htmlContent = fs.readFileSync(path.resolve(testPath, "index1.html"), "utf-8");
61+
expect(htmlContent).toMatch(/<script defer="defer" src="bundle1.js" integrity=".+" crossorigin="anonymous">/);
62+
expect(htmlContent).toMatch(/<script defer="defer" src="http:\/\/localhost:3000\/index\.js">/);
63+
});
64+
}
65+
}
66+
],
67+
}]);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
noTests: true
3+
};

0 commit comments

Comments
 (0)