Fix Haml pre-processing crash when there is no \n at the end of the file (#18155)

This PR fixes a Haml pre-processing issue where a crash occurs if there
is no trailing `\n` at the end of the file and the code before it was
considered Ruby code.

This happens in situations where Ruby code was used. E.g.:

```
- index = 0
- index += 1
```

In this situation when we see the `-` on the second line, then we will
find the whole indented block and parse it as Ruby code instead. The
block ands at the last `\n`, but since we reach the end of the file,
there is no `\n`. Right now we incorrectly reset the internal cursor to
the last known `\n` position. This means that the `start` of the Ruby
block will be _after_ the `end` of the Ruby block and the Haml parser
will crash.

To solve this, once we reach the end of the file, we don't reset the
cursor to the wrong position.

Fixes:
https://github.com/tailwindlabs/tailwindcss/issues/17379#issuecomment-2910108646

## Test plan

1. Added a regression test that did fail before the fix, and doesn't
anymore
This commit is contained in:
Robin Malfait 2025-05-26 18:52:44 +02:00 • committed by GitHub
parent 5131237d67
commit 1d4c263c73
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 18 additions and 0 deletions

View file

@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support Leptos `class:` attributes when extracting classes ([#18093](https://github.com/tailwindlabs/tailwindcss/pull/18093))
- Fix "Cannot read properties of undefined" crash on malformed arbitrary value ([#18133](https://github.com/tailwindlabs/tailwindcss/pull/18133))
- Upgrade: Migrate `-mt-[0px]` to `mt-[0px]` instead of the other way around ([#18154](https://github.com/tailwindlabs/tailwindcss/pull/18154))
- Fix Haml pre-processing crash when there is no `\n` at the end of the file ([#18155](https://github.com/tailwindlabs/tailwindcss/pull/18155))
## [4.1.7] - 2025-05-15

View file

@ -330,6 +330,11 @@ impl Haml {
cursor.advance();
}
// We didn't find a newline, we reached the end of the input
if last_known_newline_position == last_newline_position {
return cursor.pos;
}
// Move the cursor to the last newline position
cursor.move_to(last_newline_position);
@ -446,4 +451,16 @@ mod tests {
"#;
Haml::test_extract_contains(input, vec!["flex", "items-center"]);
}
// https://github.com/tailwindlabs/tailwindcss/issues/17379#issuecomment-2910108646
#[test]
fn test_crash_missing_newline() {
// The empty `""` will introduce a newline
let good = ["- index = 0", "- index += 1", ""].join("\n");
Haml::test_extract_contains(&good, vec!["index"]);
// This used to crash before the fix
let bad = ["- index = 0", "- index += 1"].join("\n");
Haml::test_extract_contains(&bad, vec!["index"]);
}
}