Skip to content

Commit 893cf7a

Browse files
mini-bombactron
authored andcommitted
fix: retain the insertion order of SRI resources
This fixes an oversight where the order of <link rel=preload> statements was different than the order of insertion into the SriBuilder. This was caused by the usage of BTreeMap, which internally reordered the entries in lexicographic order - Preload types first, then ModulePreloads, sorted by the lexicographic ordering of strings in case of any conflicts. This was likely not the intended result. This issue was mitigated by replacing the BTreeMap with a Vec, and manually implementing checks for identical keys.
1 parent 32b2457 commit 893cf7a

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

src/pipelines/rust/sri.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use crate::config::CrossOrigin;
22
use crate::processing::integrity::{IntegrityType, OutputDigest};
33
use nipper::Selection;
4-
use std::collections::BTreeMap;
54
use std::fmt::{Display, Formatter};
65
use std::future::Future;
76
use std::path::Path;
87

9-
#[derive(Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
8+
#[derive(Clone, Debug, PartialEq, Eq)]
109
pub enum SriType {
1110
Preload,
1211
ModulePreload,
@@ -74,9 +73,13 @@ impl SriBuilder {
7473
"recording SRI record - type: {:?}. name: {name}, value: {digest:?}",
7574
self.r#type,
7675
);
77-
self.result
78-
.integrities
79-
.insert((r#type, name), SriEntry { digest, options });
76+
let key = SriKey { r#type, name };
77+
let entry = SriEntry { digest, options };
78+
if let Some(record) = self.result.integrities.iter_mut().find(|(k, _)| k == &key) {
79+
record.1 = entry;
80+
} else {
81+
self.result.integrities.push((key, entry));
82+
}
8083
}
8184

8285
Ok(())
@@ -85,7 +88,7 @@ impl SriBuilder {
8588

8689
#[derive(Clone, Debug, Default)]
8790
pub struct SriResult {
88-
pub integrities: BTreeMap<(SriType, String), SriEntry>,
91+
pub integrities: Vec<(SriKey, SriEntry)>,
8992
}
9093

9194
#[derive(Clone, Debug, Default)]
@@ -120,6 +123,12 @@ impl Display for SriOptions {
120123
}
121124
}
122125

126+
#[derive(Clone, Debug, PartialEq, Eq)]
127+
pub struct SriKey {
128+
pub r#type: SriType,
129+
pub name: String,
130+
}
131+
123132
#[derive(Clone, Debug)]
124133
pub struct SriEntry {
125134
pub digest: OutputDigest,
@@ -128,7 +137,7 @@ pub struct SriEntry {
128137

129138
impl SriResult {
130139
pub fn inject(&self, mut location: Selection, base: impl Display, cross_origin: CrossOrigin) {
131-
for ((r#type, name), SriEntry { digest, options }) in &self.integrities {
140+
for (SriKey { r#type, name }, SriEntry { digest, options }) in &self.integrities {
132141
if let Some(integrity) = digest.to_integrity_value() {
133142
let preload = format!(
134143
r#"

0 commit comments

Comments
 (0)