Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure strings are consumed as-is when using internal segment() #13608

Merged
merged 7 commits into from Apr 30, 2024

Conversation

RobinMalfait
Copy link
Contributor

This PR fixes an issue where parens, bracket and curlies needed to be balanced inside of strings instead of consuming the string until the end.

When encountering strings when using segment we didn't really treat them as actual strings. This means that if you used any parens, brackets, or curlies then we wanted them to be properly balanced.

This should not be the case, whenever we encounter a string, we want to consume it as-is and don't want to worry about bracket balancing. We will now consume it until the end of the string (and make sure that escaped closing quotes are not seen as real closing quotes).

Fixes: #13607

When encountering strings when using `segment` we didn't really treat
them as actual strings. This means that if you used any parens,
brackets, or curlies then we wanted them to be properly balanced.

This should not be the case, whenever we encounter a string, we want to
consume it as-is and don't want to worry about bracket balancing. We
will now consume it until the end of the string (and make sure that
escaped closing quotes are not seen as real closing quotes).
Copy link
Contributor

@thecrypticace thecrypticace left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — just one tweak in the tests plz

packages/tailwindcss/src/utils/segment.test.ts Outdated Show resolved Hide resolved
Already had this test
@brandonmcconnell
Copy link
Contributor

@RobinMalfait @thecrypticace It may be useful to include tests for bracket and quote chars in arbitrary values, specifically, to include tests similar to the original issue: e.g. supports-[content:"("]:[content:"("]

We don't need to include all of these, but these should all pass with the proper fix, perhaps with some minor alterations: https://play.tailwindcss.com/EAhSfQFfTa

Copy link
Member

@adamwathan adamwathan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! This looks good to me.

Couple things:

  • Should we add a test somewhere for the higher level issue that made us notice this, or is there not really a good/obvious place to put it? It's kinda weird to put it in the supports tests because it applies to other stuff like the data variant too.
  • Did you benchmark this against the previous implementation (even though it had a bug)? Hoping it's basically negligible.

@brandonmcconnell
Copy link
Contributor

@RobinMalfait Thanks for the quick fix here!

@RobinMalfait
Copy link
Contributor Author

RobinMalfait commented Apr 29, 2024

Yeah good ideas to add another, more high level test.

My thinking is to add a generic test for candidate parsing so that we know that we at least parse it into the correct data structure. If we want, we can add a specific one for supports-[...] but as you mentioned, this is a more generic fix anyway.

Right now we don't really have generic tests for this.

Benchmarking wise, it's actually even better when we encounter strings because we can skip a lot of work. The checks to know that we are in a string or a single integer check.

Current PR:

 ✓ src/utils/segment.bench.ts (1) 792ms
     name               hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · segment  1,087,386.63  0.0008  0.9782  0.0009  0.0009  0.0010  0.0012  0.0033  ±0.53%   543694   fastest

Next branch:

 ✓ src/utils/segment.bench.ts (1) 789ms
     name               hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · segment  1,042,913.63  0.0008  0.9799  0.0010  0.0010  0.0011  0.0014  0.0028  ±0.55%   521457   fastest

CHANGELOG.md Outdated
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- Make sure `contain-*` utility variables resolve to a valid value ([#13521](https://github.com/tailwindlabs/tailwindcss/pull/13521))
- Ensure strings are consumed as-is when using internal `segment()` ([#13608](https://github.com/tailwindlabs/tailwindcss/pull/13608))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we change this to represent the user-facing fix? Maybe something more like "Support unbalanced parentheses and braces in quotes in arbitrary values and variants".

case SINGLE_QUOTE:
case DOUBLE_QUOTE:
while (
// Ensure we don't go out of bounds.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might look less weird with the comment above the while instead of in the condition.

@adamwathan adamwathan merged commit cb17447 into next Apr 30, 2024
1 check passed
@adamwathan adamwathan deleted the fix/issue-13607 branch April 30, 2024 16:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

v4: Bug with how the parser handles nested quote_stack and bracket_stack characters when in a string context
4 participants