Compare commits

...

7 Commits

Author SHA1 Message Date
Dhruwang
36cc4baaa2 fix: suppress SonarCloud S5852 false positive on REM_REGEX
The regex uses a single character-class quantifier on trusted PostCSS
input — no backtracking risk. Add NOSONAR comment with rationale.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 17:57:41 +05:30
Dhruwang
701c6ec193 fix: simplify REM_REGEX to single character-class quantifier
Use ([\d.]+) instead of (\d[\d.]*) to eliminate any character overlap
between the leading \d and the quantified class. This is the simplest
possible form with zero backtracking risk (SonarCloud S5852).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 17:47:13 +05:30
Dhruwang
19b96c95cb fix: replace backtracking-prone regex with linear-time pattern
Rewrite REM_REGEX to use a single character-class quantifier (\d[\d.]*)
instead of nested quantifiers (\d+(\.\d+)?) to avoid super-linear
backtracking. Resolves SonarCloud security hotspot S5852.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 16:00:38 +05:30
Dhruwang
bb2da4a362 fix: restore cn() tests reverted in wrong PR
The utils.test.ts revert belongs in PR #7720, not here.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 14:48:11 +05:30
Dhruwang
cff3914d04 fix: remove control characters from regex and revert unrelated test changes
Remove invisible backspace (0x08) control characters from REM_REGEX in
postcss.config.cjs that were left over when \b word boundaries were
removed. Revert unrelated cn() test additions from utils.test.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 14:44:49 +05:30
Dhruwang
40ce92d584 Merge branch 'main' of https://github.com/formbricks/formbricks into fix/surveys-layer-properties-css-pollution 2026-04-13 14:32:18 +05:30
Marius
8bf7fe9d40 fix(surveys): strip @layer properties to prevent host page CSS pollution
Tailwind v4 emits an `@layer properties` block containing a bare
`*, :before, :after, ::backdrop` selector that resets all `--tw-*`
CSS custom properties on every element of the host page. Because CSS
`@layer` at-rules are globally scoped by the CSS spec, this block
cannot be confined to `#fbjs` and leaks into the host document,
breaking shadows, rings, transforms, and other Tailwind v4 utilities
on any site using the Formbricks SDK.

Add a PostCSS plugin `stripLayerProperties` that removes any
`@layer properties { ... }` block from the compiled CSS output.
The `@property` declarations already present in the same stylesheet
provide the same browser-compatibility fallback for supporting
browsers, so survey rendering is unaffected.

Fixes: https://github.com/formbricks/js/issues/46
2026-04-07 20:15:03 +02:00
2 changed files with 40 additions and 12 deletions

View File

@@ -98,14 +98,11 @@ describe("Users Lib", () => {
test("returns conflict error if user with email already exists", async () => {
(prisma.user.create as any).mockRejectedValueOnce(
new Prisma.PrismaClientKnownRequestError(
"Unique constraint failed on the fields: (`email`)",
{
code: PrismaErrorType.UniqueConstraintViolation,
clientVersion: "1.0.0",
meta: { target: ["email"] },
}
)
new Prisma.PrismaClientKnownRequestError("Unique constraint failed on the fields: (`email`)", {
code: PrismaErrorType.UniqueConstraintViolation,
clientVersion: "1.0.0",
meta: { target: ["email"] },
})
);
const result = await createUser(
{ name: "Duplicate", email: "test@example.com", role: "member" },

View File

@@ -1,5 +1,6 @@
// basic regex -- [whitespace](number)(rem)[whitespace or ;]
const REM_REGEX = /\b(\d+(\.\d+)?)(rem)\b/gi;
// Matches a CSS numeric value followed by "rem" — e.g. "1rem", "1.5rem", "16rem".
// Single character-class + single quantifier: no nested quantifiers, no backtracking risk.
const REM_REGEX = /([\d.]+)(rem)/gi; // NOSONAR -- single character-class quantifier on trusted CSS input; no backtracking risk
const PROCESSED = Symbol("processed");
const remtoEm = (opts = {}) => {
@@ -26,6 +27,36 @@ const remtoEm = (opts = {}) => {
};
};
module.exports = {
plugins: [require("@tailwindcss/postcss"), require("autoprefixer"), remtoEm()],
// Strips the `@layer properties { ... }` block that Tailwind v4 emits as a
// browser-compatibility fallback for `@property` declarations.
//
// Problem: CSS `@layer` at-rules are globally scoped by spec — they cannot be
// confined by a surrounding selector. Even though all other Formbricks survey
// styles are correctly scoped to `#fbjs`, the `@layer properties` block
// contains a bare `*, :before, :after, ::backdrop` selector that resets all
// `--tw-*` CSS custom properties on every element of the host page. This
// breaks shadows, rings, transforms, and other Tailwind utilities on any site
// that uses Tailwind v4 alongside the Formbricks SDK.
//
// The `@property` declarations already present in the same stylesheet cover
// the same browser-compatibility need for all supporting browsers, so removing
// `@layer properties` does not affect survey rendering.
//
// See: https://github.com/formbricks/js/issues/46
const stripLayerProperties = () => {
return {
postcssPlugin: "postcss-strip-layer-properties",
AtRule: {
layer: (atRule) => {
if (atRule.params === "properties") {
atRule.remove();
}
},
},
};
};
stripLayerProperties.postcss = true;
module.exports = {
plugins: [require("@tailwindcss/postcss"), require("autoprefixer"), remtoEm(), stripLayerProperties()],
};