pub fn contains_script_closing_tag(source: &[u8]) -> bool {
let finder = memchr::memmem::Finder::new(b"</");
let mut remaining = source;
while let Some(pos) = finder.find(remaining) {
if remaining.len() >= pos + 8 {
if is_script_close_tag(&remaining[pos..pos + 8]) {
return true;
}
}
remaining = &remaining[pos + 2..];
}
false
}
#[expect(clippy::inline_always)]
#[inline(always)]
fn is_script_close_tag(slice: &[u8]) -> bool {
let mut bytes: [u8; 8] = slice.try_into().unwrap();
for byte in bytes.iter_mut().skip(2) {
*byte |= 32;
}
bytes == *b"</script"
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_contains_script_closing_tag_lowercase() {
assert!(contains_script_closing_tag(b"</script>"));
assert!(contains_script_closing_tag(b"some code </script> more"));
assert!(contains_script_closing_tag(b"prefix</script"));
}
#[test]
fn test_contains_script_closing_tag_uppercase() {
assert!(contains_script_closing_tag(b"</SCRIPT>"));
assert!(contains_script_closing_tag(b"</SCRIPT"));
assert!(contains_script_closing_tag(b"code </SCRIPT> code"));
}
#[test]
fn test_contains_script_closing_tag_mixed_case() {
assert!(contains_script_closing_tag(b"</Script>"));
assert!(contains_script_closing_tag(b"</ScRiPt>"));
assert!(contains_script_closing_tag(b"</sCRIPT"));
}
#[test]
fn test_contains_script_closing_tag_not_found() {
assert!(!contains_script_closing_tag(b""));
assert!(!contains_script_closing_tag(b"no script tag here"));
assert!(!contains_script_closing_tag(b"<script>"));
assert!(!contains_script_closing_tag(b"</scrip"));
assert!(!contains_script_closing_tag(b"</ script"));
assert!(!contains_script_closing_tag(b"</style>"));
}
#[test]
fn test_contains_script_closing_tag_multiple_occurrences() {
assert!(contains_script_closing_tag(b"</script></script>"));
assert!(contains_script_closing_tag(b"</div></script></span>"));
}
#[test]
fn test_contains_script_closing_tag_in_tagged_template() {
assert!(contains_script_closing_tag(b"html`</script>`"));
assert!(contains_script_closing_tag(b"const x = `</SCRIPT>`"));
}
}