From 71d1609a8a3510a625f0d60e9aa59247a95d59f3 Mon Sep 17 00:00:00 2001 From: saniya Jabbar Khatik Date: Thu, 4 Dec 2025 22:04:27 +0530 Subject: [PATCH 1/2] Improve UTF-8 handling in scanner module Replaced unsafe UTF-8 conversion with safe handling to filter invalid candidates. --- crates/oxide/src/scanner/mod.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/oxide/src/scanner/mod.rs b/crates/oxide/src/scanner/mod.rs index ec6aea642481..ea914cb6f5b9 100644 --- a/crates/oxide/src/scanner/mod.rs +++ b/crates/oxide/src/scanner/mod.rs @@ -553,11 +553,17 @@ where a }) .into_iter() - .map(|s| unsafe { String::from_utf8_unchecked(s.to_vec()) }) + .filter_map(|s| match String::from_utf8(s.to_vec()) { + Ok(s) => Some(s), + Err(_e) => { + // Optionally log or handle invalid UTF-8 here + // eprintln!("Skipped invalid UTF-8 candidate, error: {:?}", _e); + None + } + }) .collect(); - // SAFETY: Unstable sort is faster and in this scenario it's also safe because we are - // guaranteed to have unique candidates. + // Unstable sort is performant & remains correct with unique candidates result.par_sort_unstable(); result From bb60cc4d65684c1d282fa3121aad4648e43220f9 Mon Sep 17 00:00:00 2001 From: saniya Jabbar Khatik Date: Thu, 4 Dec 2025 22:06:28 +0530 Subject: [PATCH 2/2] Enhance style block detection logic Refactor style block detection to use HTML parser for improved robustness. --- .../codemods/template/is-safe-migration.ts | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts b/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts index fa7ee7f4a1c5..6f57358e3836 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/template/is-safe-migration.ts @@ -1,4 +1,5 @@ import { parseCandidate } from '../../../../tailwindcss/src/candidate' +import { parse as parseHtml } from 'node-html-parser' import type { DesignSystem } from '../../../../tailwindcss/src/design-system' import { DefaultMap } from '../../../../tailwindcss/src/utils/default-map' import * as version from '../../utils/version' @@ -187,31 +188,24 @@ export function isSafeMigration( return true } -// Assumptions: -// - All `` tag -// - All `` -// - No nested `', offset) - if (endTag === -1) return ranges - offset = endTag + 1 - - ranges.push(startTag, endTag) + const ranges: number[] = [] + try { + const root = parseHtml(source, { lowerCaseTagName: false, comment: false, blockTextElements: { style: true } }) + const styleNodes = root.querySelectorAll('style') + styleNodes.forEach(node => { + const nodeHtml = node.toString() + const start = typeof node.range === 'object' && node.range !== null + ? node.range[0] + : source.indexOf(nodeHtml) + const end = start + nodeHtml.length + ranges.push(start, end) + }) + } catch (_) { + // fallback: do nothing if parser fails } + return ranges }) const BACKSLASH = 0x5c