SonarJS icon indicating copy to clipboard operation
SonarJS copied to clipboard

CSS parser error on invisible character <0x200b>

Open gabriel-vivas-sonarsource opened this issue 2 years ago • 2 comments

Label Description
Subject CSS parser error on invisible character <0x200b>
Community https://community.sonarsource.com/t/unexpected-unknown-type-selector/81316

Explanation

User reported an unclear error message appearing on otherwise normal CSS code:

.header-text-longname {
  display: none;
}​
.header-text-shortname {
  display: inline;
}​

Unexpected unknown type selector "​"

This error is raised by Sonar when an invisible character <0x200b> is placed where a selector is expected. In this case, on lines 3 and 6 after the braces.

The <0x200b> (zero-width space, ZWSP) character is in the range [0x2000 - 0x206F] General Punctuation.

Stylint also raises an error, as can be confirmed in the online playground, see working example [1]. The error message changes depending on the placement of the invisible character.

Unable to lint CSS: SyntaxError: The string did not match the expected pattern.

Unknown word (CssSyntaxError)

Suggestion

(Perhaps also in JavaScript and TypeScript):

  • Verify runtime behavior vs parser behavior for invisible characters to see if it could produce bugs.
  • Consider transparently stripping/ignoring invisible characters to avoid parsing errors.
  • Consider warning about the presence of an invisible character (instead of an unclear error).
  • Consider implementing a new rule in SonarText that raises on invisible characters that may cause parsing errors. There is precedent for this and perhaps security implications.

[1] Stylelint playground example

It turns out that the parsing error also happens in the browser.

This can obscure the next CSS rule after the character, creating a bug.

See this example:

Actual Expected
actual expected

Code to reproduce:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Invisible bug</title>
<style>
.first {
  background: blue;
  font-family: sans-serif;
  font-size: 10em;
}
.second {
  background: red;
}​
.third {
  background: green;
}
.fourth {
  color: white;
}
</style>
</head>
<body class="first second third fourth">
  There's an invisible bug in the code.
  The background will not be green, but red.
</body>
</html>

Note: Tested with Safari 16.2 (18614.3.7.1.5), Firefox 108.0.2 (64-bit), Chrome 109.0.5414.87 (arm64) and on macOS Ventura 13.1 (22C65).

As a first step to tackle this problem we could strip these invisible control characters from the stream to avoid parsing issues and log a warning for the user.

saberduck avatar Feb 14 '24 14:02 saberduck

This requires some discussions with other squads and requires specification.

ilia-kebets-sonarsource avatar Mar 18 '24 14:03 ilia-kebets-sonarsource

raising issues could be done in another way, but our analysis should be robust!

ilia-kebets-sonarsource avatar Mar 18 '24 14:03 ilia-kebets-sonarsource

Verified locally against SonarQube 10.4, using the latest plugin artifact.

ericmorand-sonarsource avatar Mar 26 '24 10:03 ericmorand-sonarsource