Skip to content

Conversation

@thecrypticace
Copy link
Contributor

@thecrypticace thecrypticace commented Mar 25, 2025

Fixes #17379

The preprocessor we added to detect embedded languages uses a back reference and given a long enough file with certain byte / character patterns it'll cause what appears to be an indefinite hang (might just be catastrophically exponential backtracking but not sure)

This replaces the one regex w/ back references with two, anchored, multi-line regexes

Now we search for all the starting & ending delimiters in the file. We then loop over all the starting delimiters, find the paired ending one, and preprocess the content inside

@thecrypticace thecrypticace requested a review from a team as a code owner March 25, 2025 21:19
@thecrypticace
Copy link
Contributor Author

thecrypticace commented Mar 25, 2025

I didn't put this test case in because it's kinda absurd but this froze previously with the old regex — yes the indentation is like that on purpose:

// https://github.com/tailwindlabs/tailwindcss/issues/17334 #[test] fn test_wip() { let input = r#" <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div> <div class="underline underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div>  <div class="underline underline underline underline underline underline underline underline underline"></div> "#; Ruby::test_extract_contains(input, vec!["underline"]); }
@philipp-spiess philipp-spiess merged commit 3dcd615 into main Mar 26, 2025
6 checks passed
@philipp-spiess philipp-spiess deleted the fix/ruby-files-hanging branch March 26, 2025 10:00
philipp-spiess added a commit that referenced this pull request Mar 26, 2025
Fixes #17379 The preprocessor we added to detect embedded languages uses a back reference and given a long enough file with certain byte / character patterns it'll cause what appears to be an indefinite hang (might just be catastrophically exponential backtracking but not sure) This replaces the one regex w/ back references with two, anchored, multi-line regexes Now we search for all the starting & ending delimiters in the file. We then loop over all the starting delimiters, find the paired ending one, and preprocess the content inside --------- Co-authored-by: Philipp Spiess <hello@philippspiess.com>
philipp-spiess added a commit that referenced this pull request Mar 28, 2025
Fixes #17379 The preprocessor we added to detect embedded languages uses a back reference and given a long enough file with certain byte / character patterns it'll cause what appears to be an indefinite hang (might just be catastrophically exponential backtracking but not sure) This replaces the one regex w/ back references with two, anchored, multi-line regexes Now we search for all the starting & ending delimiters in the file. We then loop over all the starting delimiters, find the paired ending one, and preprocess the content inside --------- Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants